/*#io
docCopyright("Steve Dekorte", 2004)
docLicense("BSD revised")
docObject("Datum")
*/
#include "Datum.h"
#include "ByteArray.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
PID_TYPE Datum_size(Datum *self)
{
return self->size;
}
unsigned char *Datum_data(Datum *self)
{
return self->data;
}
void *Datum_asByteArray(Datum *self)
{
return ByteArray_newWithData_size_(self->data, self->size);
}
Datum Datum_FromData_length_(unsigned char *data, PID_TYPE size)
{
Datum d;
d.data = data;
d.size = size;
return d;
}
Datum Datum_FromCString_(const char *s)
{
Datum d;
d.data = (unsigned char *)s;
d.size = strlen(s) + 1;
return d;
}
/*
Datum Datum_FromPid_(PID_TYPE pid)
{
Datum d;
d.data = (unsigned char *)&pid;
d.size = sizeof(PID_TYPE);
return d;
}
*/
Datum Datum_FromByteArray_(ByteArray *ba)
{
Datum d;
d.data = ByteArray_bytes(ba);
d.size = ByteArray_size(ba);
return d;
}
Datum Datum_Empty(void)
{
Datum d;
d.data = NULL;
d.size = 0;
return d;
}
Datum Datum_datumAt_(Datum *self, size_t i)
{
Datum d;
if (i < self->size)
{
d.data = self->data + i;
d.size = self->size - i;
}
else
{
d.data = NULL;
d.size = 0;
}
return d;
}
int Datum_compare_(Datum *self, Datum *other)
{
size_t l1 = self->size;
size_t l2 = other->size;
size_t min = l1 < l2 ? l1 : l2;
int cmp = memcmp(self->data, other->data, min);
if (cmp == 0)
{
if (l1 == l2)
{
return 0;
}
if (l1 < l2)
{
return -1;
}
return 1;
}
return cmp;
}
int Datum_compare_length_(Datum *self, Datum *other, size_t limit)
{
size_t l1 = self->size;
size_t l2 = other->size;
size_t min = l1 < l2 ? l1 : l2;
min = min < limit ? min : limit;
return memcmp(self->data, other->data, min);
}
int Datum_beginsWith_(Datum *self, Datum *other)
{
if (self->size >= other->size)
{
return (0 == Datum_compare_length_(self, other, other->size));
}
return 0;
}
int Datum_endsWith_(Datum *self, Datum *other)
{
if (self->size >= other->size)
{
Datum d = Datum_datumAt_(self, self->size - other->size);
return (0 == Datum_compare_(&d, other));
}
return 0;
}
int Datum_compareCString_(Datum *self, const char *s)
{
Datum sd = Datum_FromCString_(s);
return Datum_compare_(self, &sd);
}
size_t Datum_matchingPrefixSizeWith_(Datum *self, Datum *other)
{
unsigned int l1 = self->size;
unsigned int l2 = other->size;
unsigned int min = l1 < l2 ? l1 : l2;
unsigned char *b1 = self->data;
unsigned char *b2 = other->data;
size_t i;
for (i = 0; i < min; i ++)
{
if (*b1 != *b2) break;
*b1 ++;
*b2 ++;
}
return i;
}
Datum *Datum_newFrom_to_(Datum *self, size_t start, size_t end)
{
Datum *d = (Datum *)malloc(sizeof(Datum));
if ((start < end) && (end <= (size_t)self->size))
{
d->data = self->data + start;
d->size = end - start;
return d;
}
d->data = NULL;
d->size = 0;
return d;
}
void *Datum_split_(Datum *self, void *delimsList) /* returns a List */
{
List *delims = (List *)delimsList;
List *results = List_new();
size_t i, last = 0;
for (i = 0; i < self->size; i ++)
{
Datum d = Datum_datumAt_(self, i);
size_t j;
for (j = 0; j < (size_t)List_size(delims); j ++)
{
Datum *delim = (Datum *)List_at_(delims, j);
if (Datum_beginsWith_(&d, delim))
{
List_append_(results, Datum_newFrom_to_(self, last, i));
last = i + delim->size;
i = last - 1; /* since for() will increment it */
break;
}
}
}
if (last != self->size)
{
List_append_(results, Datum_newFrom_to_(self, last, self->size));
}
return results;
}
// enumeration
/*
int Datum_next(Datum *self)
{
if (self->size)
{
self->data ++;
self->size --;
return 1;
}
return 0;
}
*/
unsigned int Datum_hash(Datum *self)
{
PID_TYPE length = self->size;
unsigned char *key = self->data;
unsigned int h = 5381;
while (length-- > 0)
{
h += (h << 5); /* h(i) = (h(i-1) * 33) ^ key(i) */
h ^= *key ++;
}
return h;
}
/*
typedef int (DatumDetectWithFunc)(void *, Datum *); // 1 = match, -1 = break
int Datum_detect_withTarget_(Datum *self, DatumDetectWithFunc *func, void *target)
{
unsigned char *s = self->data;
unsigned char *end = self->data + self->size;
Datum d;
int result;
while (s < end)
{
d.data = s;
d.size = end - s;
result = (*func)(target, &d);
if (result == 1)
{
return s - self->bytes;
}
else if (result == -1)
{
return -1;
}
s ++;
}
return -1;
}
*/
/*
Datum Datum_datumUntil_withTarget_(Datum *self, DatumDetectWithFunc *func, void *target)
{
int index = Datum_detect_withTarget_(self, func, target);
Datum chunk;
if (index == -1)
{
index = length;
}
d.data = self->data + index;
d.size = self->size - index;
return d;
}
*/
syntax highlighted by Code2HTML, v. 0.9.1