123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /* ---------------------------------------------------------------------------
- Nullsoft Database Engine
- --------------------
- codename: Near Death Experience
- --------------------------------------------------------------------------- */
- /* ---------------------------------------------------------------------------
- Field Class
- --------------------------------------------------------------------------- */
- #include "field.h"
- #include "vfs.h"
- #include "table.h"
- #include "nde.h"
- #include "dbutils.h"
- #ifdef WIN32
- #include <malloc.h>
- #elif defined(__APPLE__)
- #include <alloca.h>
- #endif
- //---------------------------------------------------------------------------
- void PUT_BINARY(uint8_t *dest, const uint8_t *src, size_t size, size_t pos)
- {
- if (src && dest && size > 0)
- memcpy(dest+pos, src, size);
- }
- //---------------------------------------------------------------------------
- void GET_BINARY(uint8_t *dest, const uint8_t *src, size_t size, size_t pos)
- {
- if (dest && src && size > 0)
- memcpy(dest, src+pos, size);
- }
- //---------------------------------------------------------------------------
- void PUT_FLOAT(float f, uint8_t *data, size_t pos)
- {
- unsigned int y = *(const unsigned int *)&f;
- data[pos]=(unsigned char)(y&255); data[pos+1]=(unsigned char)((y>>8)&255); data[pos+2]=(unsigned char)((y>>16)&255); data[pos+3]=(unsigned char)((y>>24)&255);
- }
- //---------------------------------------------------------------------------
- float GET_FLOAT(const uint8_t *data, size_t pos)
- {
- int a = data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24);
- float f = *(const float *)&a;
- return f;
- }
- //---------------------------------------------------------------------------
- Field::Field(int FieldPos)
- {
- InitField();
- Pos = FieldPos;
- }
- //---------------------------------------------------------------------------
- void Field::InitField(void)
- {
- Type = FIELD_UNKNOWN;
- Pos = 0;
- ID = 0;
- MaxSizeOnDisk = 0;
- }
- //---------------------------------------------------------------------------
- Field::Field()
- {
- InitField();
- }
- //---------------------------------------------------------------------------
- Field::~Field()
- {
- }
- //---------------------------------------------------------------------------
- Field *Field::ReadField(Table *pTable, int pos, uint32_t *next_position)
- {
- return ReadField(pTable, pos, false, next_position);
- }
- //---------------------------------------------------------------------------
- Field *Field::ReadField(Table *pTable, int pos, bool Quick, uint32_t *next_position)
- {
- VFILE *HTable = pTable->Handle;
- int newPos = pos;
- int rType = FIELD_REDIRECTOR;
- unsigned char oType;
- if (!Vflock(HTable, false))
- return 0;
- while (rType == FIELD_REDIRECTOR)
- {
- Vfseek(HTable, Pos, SEEK_SET);
- if (Vfread(&ID, sizeof(ID), HTable) != 1 ||
- Vfread(&oType, sizeof(oType), HTable) != 1)
- {
- Vfunlock(HTable, false);
- return NULL;
- }
- if (oType == FIELD_REDIRECTOR)
- {
- if (Vfread(&newPos, sizeof(newPos), HTable) != 1)
- {
- Vfunlock(HTable, false);
- return NULL;
- }
- Pos = newPos;
- }
- rType = oType;
- }
- if (Quick)
- Vfseek(HTable, sizeof(MaxSizeOnDisk), SEEK_CUR);
- else
- {
- if (Vfread(&MaxSizeOnDisk, sizeof(MaxSizeOnDisk), HTable) != 1)
- {
- Vfunlock(HTable, false);
- return NULL;
- }
- }
- uint32_t NextFieldPos = 0;
- if (Vfread(&NextFieldPos, sizeof(NextFieldPos), HTable) != 1)
- {
- Vfunlock(HTable, false);
- return NULL;
- }
- if (next_position) *next_position = NextFieldPos;
- if (Quick)
- {
- Vfunlock(HTable, false);
- return this;
- }
- uint32_t PreviousFieldPos = 0;
- if (Vfread(&PreviousFieldPos, sizeof(PreviousFieldPos), HTable) != 1)
- {
- Vfunlock(HTable, false);
- return NULL;
- }
- Field *O=NULL;
- O = TranslateObject(oType, pTable);
- if (O)
- {
- O->ID = ID;
- O->Type = oType;
- O->Pos = Pos;
- O->MaxSizeOnDisk = MaxSizeOnDisk;
- uint8_t *data = NULL;
- if (HTable->cached && MaxSizeOnDisk > VFILE_INC)
- {
- pTable->IncErrorCount();
- MaxSizeOnDisk = (uint32_t)GetDataSize();
- O->MaxSizeOnDisk = MaxSizeOnDisk;
- }
- else if (HTable->cached)
- {
- data = HTable->data+HTable->ptr; // benski> uber-hack
- Vfseek(HTable, MaxSizeOnDisk, SEEK_CUR);
- }
- else
- {
- data = (uint8_t *)_malloca(MaxSizeOnDisk);
- Vfread(data, MaxSizeOnDisk, HTable);
- }
- if (data)
- {
- O->ReadTypedData(data, MaxSizeOnDisk);
- if (!HTable->cached)
- {
- _freea(data);
- }
- }
- Vfunlock(HTable, false);
- return O;
- }
- Vfunlock(HTable, false);
- return NULL;
- }
- //---------------------------------------------------------------------------
- void Field::WriteField(Table *pTable, Field *previous_field, Field *next_field)
- {
- VFILE *HTable = pTable->Handle;
- if (Pos == -1) return;
- size_t data_size = GetDataSize();
- if (HTable->cached && MaxSizeOnDisk > VFILE_INC) {
- pTable->IncErrorCount();
- MaxSizeOnDisk = (uint32_t)data_size;
- }
-
- if (Pos == 0 || (uint32_t)data_size > MaxSizeOnDisk)
- {
- MaxSizeOnDisk = (uint32_t)data_size;
- uint32_t newPos = AllocNewPos(HTable);
- if (Pos != 0)
- {
- unsigned char v = 0;
- Vfseek(HTable, Pos, SEEK_SET);
- Vfwrite(&v, sizeof(v), HTable);
- v = FIELD_REDIRECTOR;
- Vfwrite(&v, sizeof(v), HTable);
- Vfwrite(&newPos, sizeof(newPos), HTable);
- }
- Pos = newPos;
- if (previous_field)
- {
- //previous_field->NextFieldPos = Pos;
- if (previous_field->Pos)
- {
- Vfseek(HTable, previous_field->Pos+sizeof(ID)+sizeof(MaxSizeOnDisk)+sizeof(Type), SEEK_SET);
- Vfwrite(&Pos, sizeof(Pos), HTable);
- }
- }
- if (next_field)
- {
- if (next_field->Pos)
- {
- Vfseek(HTable, next_field->Pos+sizeof(ID)+sizeof(uint32_t/*NextFieldPos*/)+sizeof(Type)+sizeof(MaxSizeOnDisk), SEEK_SET);
- Vfwrite(&Pos, sizeof(Pos), HTable);
- }
- }
- }
- uint32_t PreviousFieldPos = 0, NextFieldPos = 0;
- if (previous_field) PreviousFieldPos = previous_field->GetFieldPos(); else PreviousFieldPos = NULL;
- if (next_field) NextFieldPos = next_field->GetFieldPos(); else NextFieldPos = NULL;
- Vfseek(HTable, Pos, SEEK_SET);
- Vfwrite(&ID, sizeof(ID), HTable);
- Vfwrite(&Type, sizeof(Type), HTable);
- Vfwrite(&MaxSizeOnDisk, sizeof(MaxSizeOnDisk), HTable);
- Vfwrite(&NextFieldPos, sizeof(NextFieldPos), HTable);
- Vfwrite(&PreviousFieldPos, sizeof(PreviousFieldPos), HTable);
- uint8_t *data = (unsigned char*)_malloca(MaxSizeOnDisk);
- WriteTypedData(data, MaxSizeOnDisk);
- Vfwrite(data, MaxSizeOnDisk, HTable);
- _freea(data);
- }
- //---------------------------------------------------------------------------
- uint32_t Field::GetFieldPos(void)
- {
- return Pos;
- }
- //---------------------------------------------------------------------------
- Field *Field::Clone(Table *pTable)
- {
- Field *clone = TranslateObject(Type, pTable);
- size_t size = GetDataSize();
- uint8_t *data = (unsigned char*)_malloca(size);
- WriteTypedData(data, size);
- clone->ReadTypedData(data, size);
- if (data) _freea(data);
- clone->Type = Type;
- //clone->HTable = HTable;
- clone->Pos = FIELD_CLONE;
- clone->ID = ID;
- //clone->NextFieldPos = 0;
- clone->MaxSizeOnDisk=(uint32_t)size;
- return clone;
- }
- //---------------------------------------------------------------------------
- int Field::GetType() {
- return Type;
- }
- size_t Field::GetTotalSize()
- {
- return GetDataSize() + sizeof(ID)+sizeof(Type)+sizeof(MaxSizeOnDisk)+sizeof(uint32_t/*NextFieldPos*/)+sizeof(uint32_t /*PreviousFieldPos*/);
- }
|