/*#io UDBRecord ioDoc( docCopyright("Steve Dekorte", 2004) docLicense("BSD revised") docObject("UDBRecord") docDescription("") */ #include "SkipDB.h" #include "UDB.h" #include #include #include UDBRecord *UDBRecord_new(void) { UDBRecord *self = (UDBRecord *)calloc(1, sizeof(UDBRecord)); return self; } UDBRecord *UDBRecord_clone(UDBRecord *self) { UDBRecord *clone = (UDBRecord *)cpalloc(self, sizeof(UDBRecord)); return clone; } void UDBRecord_free(UDBRecord *self) { if (self->data) ByteArray_free(self->data); free(self); } ByteArray *UDBRecord_data(UDBRecord *self) { if (!self->data) self->data = ByteArray_new(); return self->data; } void UDBRecord_setJFile_(UDBRecord *self, JFile *file) { self->file = file; } void UDBRecord_setPos_(UDBRecord *self, PID_TYPE pos) { self->pos = pos; } PID_TYPE UDBRecord_pos(UDBRecord *self) { return self->pos; } void UDBRecord_setPosToEnd(UDBRecord *self) { self->pos = JFile_setPositionToEnd(self->file); } void UDBRecord_pid_(UDBRecord *self, PID_TYPE pid) { self->header.pid = pid; } PID_TYPE UDBRecord_pid(UDBRecord *self) { return self->header.pid; } void UDBRecord_size_(UDBRecord *self, PID_TYPE size) { self->header.size = size; } PID_TYPE UDBRecord_size(UDBRecord *self) { return self->header.size; } void UDBRecord_remove(UDBRecord *self) { self->header.tag = RECORD_TAG_EMPTY; UDBRecord_saveHeader(self); } int UDBRecord_isEmpty(UDBRecord *self) { return (self->header.tag == RECORD_TAG_EMPTY); } // save ----------------------------------------- void UDBRecord_saveHeader(UDBRecord *self) { if (self->pos) JFile_setPosition_(self->file, self->pos); JFile_fwrite(self->file, (unsigned char *)(&(self->header)), sizeof(UDBRecordHeader), 1); } void UDBRecord_saveWithDatum_(UDBRecord *self, Datum d) { self->header.size = d.size; UDBRecord_saveHeader(self); JFile_fwrite(self->file, d.data, d.size, 1); } // read ----------------------------------------- int UDBRecord_readHeader(UDBRecord *self) { int objectsRead; JFile_setPosition_(self->file, self->pos); objectsRead = JFile_fread(self->file, (unsigned char *)(&(self->header)), sizeof(UDBRecordHeader), 1); if (objectsRead != 1) { self->header.pid = 0; self->header.size = 0; return 0; } return 1; } Datum UDBRecord_readDatum(UDBRecord *self) { ByteArray *ba = UDBRecord_data(self); Datum d; PID_TYPE size = self->header.size; JFile_fseek(self->file, self->pos + sizeof(UDBRecordHeader), SEEK_SET); ByteArray_setSize_(ba, size); JFile_fread(self->file, ByteArray_bytes(ba), size, 1); d.size = size; d.data = ByteArray_bytes(ba); return d; } // compact ----------------------------------------- void UDBRecord_moveToPos_(UDBRecord *self, PID_TYPE newPos) { PID_TYPE totalSize = UDBRecord_totalSize(self); unsigned char *data; ByteArray *ba = UDBRecord_data(self); ByteArray_setSize_(ba, totalSize); data = ByteArray_bytes(ba); JFile_fseek(self->file, self->pos, SEEK_SET); JFile_fread(self->file, data, totalSize, 1); JFile_fseek(self->file, newPos, SEEK_SET); JFile_fwrite(self->file, data, totalSize, 1); } PID_TYPE UDBRecord_totalSize(UDBRecord *self) { return sizeof(UDBRecordHeader) + self->header.size; } void UDBRecord_show(UDBRecord *self) { printf("Record pos: %" PID_FORMAT "\n", self->pos); printf(" pid: %" PID_FORMAT "\n", self->header.pid); printf(" size: %" PID_FORMAT "\n", self->header.size); printf("\n"); }