Field.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /* ---------------------------------------------------------------------------
  2. Nullsoft Database Engine
  3. --------------------
  4. codename: Near Death Experience
  5. --------------------------------------------------------------------------- */
  6. /* ---------------------------------------------------------------------------
  7. Field Class
  8. --------------------------------------------------------------------------- */
  9. #include "field.h"
  10. #include "vfs.h"
  11. #include "table.h"
  12. #include "nde.h"
  13. #include "dbutils.h"
  14. #ifdef WIN32
  15. #include <malloc.h>
  16. #elif defined(__APPLE__)
  17. #include <alloca.h>
  18. #endif
  19. //---------------------------------------------------------------------------
  20. void PUT_BINARY(uint8_t *dest, const uint8_t *src, size_t size, size_t pos)
  21. {
  22. if (src && dest && size > 0)
  23. memcpy(dest+pos, src, size);
  24. }
  25. //---------------------------------------------------------------------------
  26. void GET_BINARY(uint8_t *dest, const uint8_t *src, size_t size, size_t pos)
  27. {
  28. if (dest && src && size > 0)
  29. memcpy(dest, src+pos, size);
  30. }
  31. //---------------------------------------------------------------------------
  32. void PUT_FLOAT(float f, uint8_t *data, size_t pos)
  33. {
  34. unsigned int y = *(const unsigned int *)&f;
  35. 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);
  36. }
  37. //---------------------------------------------------------------------------
  38. float GET_FLOAT(const uint8_t *data, size_t pos)
  39. {
  40. int a = data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24);
  41. float f = *(const float *)&a;
  42. return f;
  43. }
  44. //---------------------------------------------------------------------------
  45. Field::Field(int FieldPos)
  46. {
  47. InitField();
  48. Pos = FieldPos;
  49. }
  50. //---------------------------------------------------------------------------
  51. void Field::InitField(void)
  52. {
  53. Type = FIELD_UNKNOWN;
  54. Pos = 0;
  55. ID = 0;
  56. MaxSizeOnDisk = 0;
  57. }
  58. //---------------------------------------------------------------------------
  59. Field::Field()
  60. {
  61. InitField();
  62. }
  63. //---------------------------------------------------------------------------
  64. Field::~Field()
  65. {
  66. }
  67. //---------------------------------------------------------------------------
  68. Field *Field::ReadField(Table *pTable, int pos, uint32_t *next_position)
  69. {
  70. return ReadField(pTable, pos, false, next_position);
  71. }
  72. //---------------------------------------------------------------------------
  73. Field *Field::ReadField(Table *pTable, int pos, bool Quick, uint32_t *next_position)
  74. {
  75. VFILE *HTable = pTable->Handle;
  76. int newPos = pos;
  77. int rType = FIELD_REDIRECTOR;
  78. unsigned char oType;
  79. if (!Vflock(HTable, false))
  80. return 0;
  81. while (rType == FIELD_REDIRECTOR)
  82. {
  83. Vfseek(HTable, Pos, SEEK_SET);
  84. if (Vfread(&ID, sizeof(ID), HTable) != 1 ||
  85. Vfread(&oType, sizeof(oType), HTable) != 1)
  86. {
  87. Vfunlock(HTable, false);
  88. return NULL;
  89. }
  90. if (oType == FIELD_REDIRECTOR)
  91. {
  92. if (Vfread(&newPos, sizeof(newPos), HTable) != 1)
  93. {
  94. Vfunlock(HTable, false);
  95. return NULL;
  96. }
  97. Pos = newPos;
  98. }
  99. rType = oType;
  100. }
  101. if (Quick)
  102. Vfseek(HTable, sizeof(MaxSizeOnDisk), SEEK_CUR);
  103. else
  104. {
  105. if (Vfread(&MaxSizeOnDisk, sizeof(MaxSizeOnDisk), HTable) != 1)
  106. {
  107. Vfunlock(HTable, false);
  108. return NULL;
  109. }
  110. }
  111. uint32_t NextFieldPos = 0;
  112. if (Vfread(&NextFieldPos, sizeof(NextFieldPos), HTable) != 1)
  113. {
  114. Vfunlock(HTable, false);
  115. return NULL;
  116. }
  117. if (next_position) *next_position = NextFieldPos;
  118. if (Quick)
  119. {
  120. Vfunlock(HTable, false);
  121. return this;
  122. }
  123. uint32_t PreviousFieldPos = 0;
  124. if (Vfread(&PreviousFieldPos, sizeof(PreviousFieldPos), HTable) != 1)
  125. {
  126. Vfunlock(HTable, false);
  127. return NULL;
  128. }
  129. Field *O=NULL;
  130. O = TranslateObject(oType, pTable);
  131. if (O)
  132. {
  133. O->ID = ID;
  134. O->Type = oType;
  135. O->Pos = Pos;
  136. O->MaxSizeOnDisk = MaxSizeOnDisk;
  137. uint8_t *data = NULL;
  138. if (HTable->cached && MaxSizeOnDisk > VFILE_INC)
  139. {
  140. pTable->IncErrorCount();
  141. MaxSizeOnDisk = (uint32_t)GetDataSize();
  142. O->MaxSizeOnDisk = MaxSizeOnDisk;
  143. }
  144. else if (HTable->cached)
  145. {
  146. data = HTable->data+HTable->ptr; // benski> uber-hack
  147. Vfseek(HTable, MaxSizeOnDisk, SEEK_CUR);
  148. }
  149. else
  150. {
  151. data = (uint8_t *)_malloca(MaxSizeOnDisk);
  152. Vfread(data, MaxSizeOnDisk, HTable);
  153. }
  154. if (data)
  155. {
  156. O->ReadTypedData(data, MaxSizeOnDisk);
  157. if (!HTable->cached)
  158. {
  159. _freea(data);
  160. }
  161. }
  162. Vfunlock(HTable, false);
  163. return O;
  164. }
  165. Vfunlock(HTable, false);
  166. return NULL;
  167. }
  168. //---------------------------------------------------------------------------
  169. void Field::WriteField(Table *pTable, Field *previous_field, Field *next_field)
  170. {
  171. VFILE *HTable = pTable->Handle;
  172. if (Pos == -1) return;
  173. size_t data_size = GetDataSize();
  174. if (HTable->cached && MaxSizeOnDisk > VFILE_INC) {
  175. pTable->IncErrorCount();
  176. MaxSizeOnDisk = (uint32_t)data_size;
  177. }
  178. if (Pos == 0 || (uint32_t)data_size > MaxSizeOnDisk)
  179. {
  180. MaxSizeOnDisk = (uint32_t)data_size;
  181. uint32_t newPos = AllocNewPos(HTable);
  182. if (Pos != 0)
  183. {
  184. unsigned char v = 0;
  185. Vfseek(HTable, Pos, SEEK_SET);
  186. Vfwrite(&v, sizeof(v), HTable);
  187. v = FIELD_REDIRECTOR;
  188. Vfwrite(&v, sizeof(v), HTable);
  189. Vfwrite(&newPos, sizeof(newPos), HTable);
  190. }
  191. Pos = newPos;
  192. if (previous_field)
  193. {
  194. //previous_field->NextFieldPos = Pos;
  195. if (previous_field->Pos)
  196. {
  197. Vfseek(HTable, previous_field->Pos+sizeof(ID)+sizeof(MaxSizeOnDisk)+sizeof(Type), SEEK_SET);
  198. Vfwrite(&Pos, sizeof(Pos), HTable);
  199. }
  200. }
  201. if (next_field)
  202. {
  203. if (next_field->Pos)
  204. {
  205. Vfseek(HTable, next_field->Pos+sizeof(ID)+sizeof(uint32_t/*NextFieldPos*/)+sizeof(Type)+sizeof(MaxSizeOnDisk), SEEK_SET);
  206. Vfwrite(&Pos, sizeof(Pos), HTable);
  207. }
  208. }
  209. }
  210. uint32_t PreviousFieldPos = 0, NextFieldPos = 0;
  211. if (previous_field) PreviousFieldPos = previous_field->GetFieldPos(); else PreviousFieldPos = NULL;
  212. if (next_field) NextFieldPos = next_field->GetFieldPos(); else NextFieldPos = NULL;
  213. Vfseek(HTable, Pos, SEEK_SET);
  214. Vfwrite(&ID, sizeof(ID), HTable);
  215. Vfwrite(&Type, sizeof(Type), HTable);
  216. Vfwrite(&MaxSizeOnDisk, sizeof(MaxSizeOnDisk), HTable);
  217. Vfwrite(&NextFieldPos, sizeof(NextFieldPos), HTable);
  218. Vfwrite(&PreviousFieldPos, sizeof(PreviousFieldPos), HTable);
  219. uint8_t *data = (unsigned char*)_malloca(MaxSizeOnDisk);
  220. WriteTypedData(data, MaxSizeOnDisk);
  221. Vfwrite(data, MaxSizeOnDisk, HTable);
  222. _freea(data);
  223. }
  224. //---------------------------------------------------------------------------
  225. uint32_t Field::GetFieldPos(void)
  226. {
  227. return Pos;
  228. }
  229. //---------------------------------------------------------------------------
  230. Field *Field::Clone(Table *pTable)
  231. {
  232. Field *clone = TranslateObject(Type, pTable);
  233. size_t size = GetDataSize();
  234. uint8_t *data = (unsigned char*)_malloca(size);
  235. WriteTypedData(data, size);
  236. clone->ReadTypedData(data, size);
  237. if (data) _freea(data);
  238. clone->Type = Type;
  239. //clone->HTable = HTable;
  240. clone->Pos = FIELD_CLONE;
  241. clone->ID = ID;
  242. //clone->NextFieldPos = 0;
  243. clone->MaxSizeOnDisk=(uint32_t)size;
  244. return clone;
  245. }
  246. //---------------------------------------------------------------------------
  247. int Field::GetType() {
  248. return Type;
  249. }
  250. size_t Field::GetTotalSize()
  251. {
  252. return GetDataSize() + sizeof(ID)+sizeof(Type)+sizeof(MaxSizeOnDisk)+sizeof(uint32_t/*NextFieldPos*/)+sizeof(uint32_t /*PreviousFieldPos*/);
  253. }