1 /*
2  * This file was written by Bill Cox.  It is hereby placed into the public domain.
3  */
4 #ifndef UTPERSIST_H
5 #define UTPERSIST_H
6 
7 /* These are the commands supported in the recentChanges.  The high bit of a command byte is used
8  * to indicate that the command is an undo command, rather than a redo command. */
9 typedef enum {
10     UT_TRANSACTION_COMPLETE = 0, /* TRANSACTION_COMPLETE <32-bit checksum> */
11     UT_WRITE_FIELD = 1, /* WRITE_FIELD <16-bit field #> <object number> <value> */
12     UT_WRITE_ARRAY = 2, /* WRITE_ARRAY <16-bit field #> <32-bit index> <32-bit numValues> <values> */
13     UT_WRITE_GLOBAL = 3, /* WRITE_GLOBAL <8-bit moduleID> <16-bit offset> <8-bit numBytes> <values> */
14     UT_RESIZE_FIELD = 4 /* RESIZE_FIELD <16-bit field #> <64-bit size> */
15 } utCommandType;
16 
17 /* This is the maximum header size of a command needed to determine it's size */
18 #define UT_COMMAND_MAX_HEADER_SIZE 11
19 
20 typedef struct utModuleStruct *utModule;
21 typedef struct utClassStruct *utClass;
22 typedef struct utFieldStruct *utField;
23 typedef struct utTransactionStruct *utTransaction;
24 typedef struct utEnumStruct *utEnum;
25 typedef struct utEntryStruct *utEntry;
26 typedef struct utUnionStruct *utUnion;
27 typedef struct utUnioncaseStruct *utUnioncase;
28 
29 #define utModuleNull ((utModule)NULL)
30 #define utClassNull ((utClass)NULL)
31 #define utFieldNull ((utField)NULL)
32 #define utTransactionNull ((utTransaction)NULL)
33 #define utEnumNull ((utEnum)NULL)
34 #define utEntryNull ((utEntry)NULL)
35 #define utUnionNull ((utUnion)NULL)
36 #define utUnioncaseNull ((utUnioncase)NULL)
37 
38 struct utModuleStruct {
39     char *prefix;
40     uint32 hashValue;
41     uint32 globalSize;
42     void *globalData;
43     uint16 firstFieldIndex, numFields;
44     uint16 firstClassIndex, numClasses;
45     uint16 firstEnumIndex, numEnums;
46     void (*start)(void);
47     void (*stop)(void);
48     bool initialized;
49     bool persistent;
50 };
51 
52 extern struct utModuleStruct *utModules;
53 extern uint8 utAllocatedModules, utUsedModules;
54 #define utModuleInitialized(module) module->initialized
55 #define utModuleSetInitialized(module, value) (module->initialized = (value))
56 #define utModulePersistent(module) module->persistent
57 #define utModuleSetPersistent(module, value) (module->persistent = (value))
58 #define utModuleGetHashValue(module) (module->hashValue)
59 #define utModuleSetHashValue(module, value) (module->hashValue = (value))
60 #define utModuleGetGlobalSize(module) (module->globalSize)
61 #define utModuleSetGlobalSize(module, value) (module->globalSize = (value))
62 #define utModuleGetPrefix(module) (module->prefix)
63 #define utModuleSetPrefix(module, value) (module->prefix = (value))
64 #define utModuleGetGlobalData(module) (module->globalData)
65 #define utModuleSetGlobalData(module, value) (module->globalData = (value))
66 #define utModuleGetStop(module) (module->stop)
67 #define utModuleSetStop(module, value) (module->stop = (value))
68 #define utModuleGetStart(module) (module->start)
69 #define utModuleSetStart(module, value) (module->start = (value))
70 #define utModuleGetFirstClassIndex(module) (module->firstClassIndex)
71 #define utModuleSetFirstClassIndex(module, value) (module->firstClassIndex = (value))
72 #define utModuleGetFirstFieldIndex(module) (module->firstFieldIndex)
73 #define utModuleSetFirstFieldIndex(module, value) (module->firstFieldIndex = (value))
74 #define utModuleGetFirstEnumIndex(module) (module->firstEnumIndex)
75 #define utModuleSetFirstEnumIndex(module, value) (module->firstEnumIndex = (value))
76 #define utModuleGetNumClasses(module) (module->numClasses)
77 #define utModuleSetNumClasses(module, value) (module->numClasses = (value))
78 #define utModuleGetNumFields(module) (module->numFields)
79 #define utModuleSetNumFields(module, value) (module->numFields = (value))
80 #define utModuleGetNumEnums(module) (module->numEnums)
81 #define utModuleSetNumEnums(module, value) (module->numEnums = (value))
82 #define utModuleGetNextModule(module) \
83     ((((module) + 1) >= (utModules + utUsedModules))?utModuleNull:((module) + 1))
84 #define utForeachModule(module) \
85     for((module) = utModules; (module) != utModuleNull; module = utModuleGetNextModule(module))
86 #define utEndModule
87 #define utModuleGetFirstClass(module) ((module)->numClasses > 0? utClasses + (module)->firstClassIndex : \
88         utClassNull)
89 #define utModuleGetNextModuleClass(module, Class) \
90     ((((Class) - utClasses + 1) >= ((module)->firstClassIndex + (module)->numClasses))?utClassNull:((Class) + 1))
91 #define utForeachModuleClass(module, Class)\
92     for((Class) = utModuleGetFirstClass(module); (Class) != utClassNull; \
93         (Class) = utModuleGetNextModuleClass(module, Class))
94 #define utEndModuleClass
95 #define utModuleGetFirstField(module) ((module)->numFields > 0? utFields + (module)->firstFieldIndex : utFieldNull)
96 #define utModuleGetNextModuleField(module, field) \
97      ((((field) - utFields + 1) >= ((module)->firstFieldIndex + (module)->numFields))?utFieldNull:((field) + 1))
98 #define utForeachModuleField(module, field) \
99      for((field) = utModuleGetFirstField(module); (field) != utFieldNull; \
100          (field) = utModuleGetNextModuleField(module, field))
101 #define utEndModuleField
102 #define utModuleGetFirstEnum(module) ((module)->numEnums > 0? utEnums + (module)->firstEnumIndex : utEnumNull)
103 #define utModuleGetNextModuleEnum(module, Enum) \
104      ((((Enum) - utEnums + 1) >= ((module)->firstEnumIndex + (module)->numEnums))?utEnumNull:((Enum) + 1))
105 #define utForeachModuleEnum(module, Enum) \
106      for(Enum = utModuleGetFirstEnum(module); Enum != utEnumNull; \
107          Enum = utModuleGetNextModuleEnum(module, Enum))
108 #define utEndModuleEnum
109 
110 utModule utFindModule(char *prefix);
111 
112 struct utClassStruct {
113     char *name;
114     uint16 firstFieldIndex, numFields, numHiddenFields;
115     uint16 baseClassIndex, baseModuleIndex;
116     uint64 (*constructor)(void);
117     void (*destructor)(uint64 objectNumber);
118     void *numUsedPtr;
119     void *numAllocatedPtr;
120     void *firstFreePtr;
121     uint16 nextFreeFieldIndex;
122     uint8 moduleIndex, referenceSize;
123 };
124 
125 extern struct utClassStruct *utClasses;
126 extern uint16 utAllocatedClasses, utUsedClasses;
127 #define utClassGetName(theClass) (theClass->name)
128 #define utClassGetFirstFieldIndex(theClass) (theClass->firstFieldIndex)
129 #define utClassGetNumFields(theClass) (theClass->numFields)
130 #define utClassGetNumUsedPtr(theClass) (theClass->numUsedPtr)
131 #define utClassGetNumAllocatedPtr(theClass) (theClass->numAllocatedPtr)
132 #define utClassGetFirstFreePtr(theClass) (theClass->firstFreePtr)
133 #define utClassGetNextFreeFieldIndex(theClass) (theClass->nextFreeFieldIndex)
134 #define utClassGetNextFreeField(theClass) (utFields + utClassGetModule(theClass)->firstFieldIndex + \
135     theClass->nextFreeFieldIndex)
136 #define utClassGetReferenceSize(theClass) (theClass->referenceSize)
137 #define utClassGetConstructor(theClass) (theClass->constructor)
138 #define utClassGetDestructor(theClass) (theClass->destructor)
139 #define utClassGetModuleIndex(theClass) (theClass->moduleIndex)
140 #define utClassGetModule(theClass) (utModules + (theClass)->moduleIndex)
141 #define utClassGetNumHiddenFields(theClass) (theClass->numHiddenFields)
142 #define utClassGetBaseClassIndex(theClass) (theClass->baseClassIndex)
143 #define utClassGetBaseModuleIndex(theClass) (theClass->BaseModuleIndex)
144 #define utClassSetName(theClass, value) (theClass->name = (value))
145 #define utClassSetFirstFieldIndex(theClass, value) (theClass->firstFieldIndex = (value))
146 #define utClassSetNumFields(theClass, value) (theClass->numFields = (value))
147 #define utClassSetNumUsedPtr(theClass, value) (theClass->numUsedPtr = (value))
148 #define utClassSetNumAllocatedPtr(theClass, value) (theClass->numAllocatedPtr = (value))
149 #define utClassSetFirstFreePtr(theClass, value) (theClass->firstFreePtr = (value))
150 #define utClassSetNextFreeFieldIndex(theClass, value) (theClass->nextFreeFieldIndex = (value))
151 #define utClassSetReferenceSize(theClass, value) (theClass->referenceSize = (value))
152 #define utClassSetConstructor(theClass, value) (theClass->constructor = (value))
153 #define utClassSetDestructor(theClass, value) (theClass->destructor = (value))
154 #define utClassSetModuleIndex(theClass, value) (theClass->moduleIndex = (value))
155 #define utClassSetNumHiddenFields(theClass, value) (theClass->numHiddenFields = (value))
156 #define utClassSetBaseClassIndex(theClass, value) (theClass->baseClassIndex = (value))
157 #define utClassSetBaseModuleIndex(theClass, value) (theClass->baseModuleIndex = (value))
158 #define utClassGetiField(theClass, xField) (utFields + (theClass)->firstFieldIndex + xField)
159 #define utClassGetFirstField(Class) ((Class)->numFields > 0? utFields + (Class)->firstFieldIndex : utFieldNull)
160 #define utClassGetNextClassField(Class, Field) \
161     ((((Field) - utFields + 1) >= ((Class)->firstFieldIndex + (Class)->numFields))?utFieldNull:((Field) + 1))
162 #define utForeachClassField(Class, Field)\
163     for((Field) = utClassGetFirstField(Class); (Field) != utFieldNull; \
164         (Field) = utClassGetNextClassField(Class, Field))
165 #define utEndClassField
166 
167 struct utFieldStruct {
168     char *name;
169     void *arrayPtr;
170     uint32 size;
171     uint32 length; /* Only for fixed sized arrays */
172     utFieldType type;
173     char *destName;
174     uint32 *numUsedPtr; /* Only for arrays */
175     uint32 *numAllocatedPtr; /* Only for arrays */
176     void *(*getValues)(uint64 objectNumber, uint32 *numValues);
177     void *(*allocValues)(uint64 objectNumber, uint32 numValues);
178     void (*compactArray)(void);
179     uint16 classIndex;
180     uint16 unionIndex; /* Only for unions */
181     bool array;
182     bool fixedSize;
183     bool hidden; /* Only true for fields tracking array properties, or if declared hidden */
184 };
185 
186 extern struct utFieldStruct *utFields;
187 extern uint16 utAllocatedFields, utUsedFields;
188 #define utFieldSetName(field, value) (field->name = (value))
189 #define utFieldSetArrayPtr(field, value) (field->arrayPtr = (value))
190 #define utFieldSetSize(field, value) (field->size = (value))
191 #define utFieldSetLength(field, value) (field->length = (value))
192 #define utFieldSetType(field, value) (field->type = (value))
193 #define utFieldSetClassIndex(field, value) (field->classIndex = (value))
194 #define utFieldSetDestName(field, value) (field->destName = (value))
195 #define utFieldSetHidden(field, value) (field->hidden = (value))
196 #define utFieldSetArray(field, value) (field->array = (value))
197 #define utFieldSetFixedSize(field, value) (field->fixedSize = (value))
198 #define utFieldSetNumUsedPtr(field, value) (field->numUsedPtr = (value))
199 #define utFieldSetNumAllocatedPtr(field, value) (field->numAllocatedPtr = (value))
200 #define utFieldSetGetValues(field, value) (field->getValues = (value))
201 #define utFieldSetAllocValues(field, value) (field->allocValues = (value))
202 #define utFieldSetCompactArray(field, value) (field->compactArray = (value))
203 #define utFieldSetUnionIndex(field, value) (field->unionIndex = (value))
204 #define utFieldGetName(field) (field->name)
205 #define utFieldGetArrayPtr(field) (field->arrayPtr)
206 #define utFieldGetSize(field) (field->size)
207 #define utFieldGetLength(field) (field->length)
208 #define utFieldGetType(field) (field->type)
209 #define utFieldGetClassIndex(field) (field->classIndex)
210 #define utFieldGetDestName(field) (field->destName)
211 #define utFieldHidden(field) (field->hidden)
212 #define utFieldArray(field) (field->array)
213 #define utFieldFixedSize(field) (field->fixedSize)
214 #define utFieldGetNumUsedPtr(field) (field->numUsedPtr)
215 #define utFieldGetNumAllocatedPtr(field) (field->numAllocatedPtr)
216 #define utFieldGetGetValues(field) (field->getValues)
217 #define utFieldGetAllocValues(field) (field->allocValues)
218 #define utFieldGetCompactArray(field) (field->compactArray)
219 #define utFieldGetUnionIndex(field) (field->unionIndex)
220 utField utFindField(utClass theClass, char *name);
221 #define utFieldGetUnion(field) (utUnions + (field)->unionIndex)
222 #define utFieldGetClass(field) (utClasses + (field)->classIndex)
223 
224 struct utTransactionStruct {
225     uint32 position; /* Position in recent changes file, or in utCommandBuffer if not persistent */
226     uint32 length;
227 };
228 
229 extern struct utTransactionStruct *utTransactions;
230 extern uint32 utUsedTransactions, utAllocatedTransactions;
231 #define utTransactionGetPosition(transaction) (transaction->position)
232 #define utTransactionGetLength(transaction) (transaction->length)
233 #define utTransactionSetPosition(transaction, value) (transaction->position = (value))
234 #define utTransactionSetLength(transaction, value) (transaction->length = (value))
235 
236 struct utEnumStruct {
237     uint16 firstEntryIndex, numEntries;
238     char *name;
239 };
240 
241 extern struct utEnumStruct *utEnums;
242 extern uint16 utAllocatedEnums, utUsedEnums;
243 #define utEnumGetName(theEnum) (theEnum->name)
244 #define utEnumGetFirstEntryIndex(theEnum) (theEnum->firstEntryIndex)
245 #define utEnumGetNumEntries(theEnum) (theEnum->numEntries)
246 #define utEnumSetName(theEnum, value) (theEnum->name = (value))
247 #define utEnumSetFirstEntryIndex(theEnum, value) (theEnum->firstEntryIndex = (value))
248 #define utEnumSetNumEntries(theEnum, value) (theEnum->numEntries = (value))
249 #define utEnumGetFirstEntry(Enum) ((Enum)->numEntries > 0? utEntries + (Enum)->firstEntryIndex: utEntryNull)
250 #define utEnumGetNextEnumEntry(Enum, Entry) \
251     ((((Entry) - utEntries + 1) >= ((Enum)->firstEntryIndex + (Enum)->numEntries))?utEntryNull:((Entry) + 1))
252 #define utForeachEnumEntry(Enum, Entry)\
253     for((Entry) = utEnumGetFirstEntry(Enum); (Entry) != utEntryNull; \
254         (Entry) = utEnumGetNextEnumEntry(Enum, Entry))
255 #define utEndEnumEntry
256 
257 struct utEntryStruct {
258     char *name;
259     uint32 value;
260 };
261 #define utEntrySetName(entry, value) (entry->name = (value))
262 #define utEntrySetValue(entry, value) (entry->value = (value))
263 #define utEntryGetName(entry) (entry->name)
264 #define utEntryGetValue(entry) (entry->value)
265 
266 extern struct utEntryStruct *utEntries;
267 extern uint16 utAllocatedEntries, utUsedEntries;
268 
269 struct utUnionStruct {
270     uint16 fieldIndex;
271     uint16 switchFieldIndex;
272     uint16 firstUnioncaseIndex, numUnioncases;
273 };
274 #define utUnionGetSwitchField(theUnion) (utFields + (theUnion)->switchFieldIndex)
275 #define utUnionGetSwitchFieldIndex(theUnion) (theUnion->switchFieldIndex)
276 #define utUnionGetFieldIndex(theUnion) (theUnion->fieldIndex)
277 #define utUnionGetFirstUnioncaseIndex(theUnion) (theUnion->firstUnioncaseIndex)
278 #define utUnionGetNumUnioncases(theUnion) (theUnion->numUnioncases)
279 #define utUnionSetSwitchFieldIndex(theUnion, value) (theUnion->switchFieldIndex = (value))
280 #define utUnionSetFieldIndex(theUnion, value) (theUnion->fieldIndex = (value))
281 #define utUnionSetFirstUnioncaseIndex(theUnion, value) (theUnion->firstUnioncaseIndex = (value))
282 #define utUnionSetNumUnioncases(theUnion, value) (theUnion->numUnioncases = (value))
283 #define utUnionGetFirstUnioncase(Union) ((Union)->numUnioncases > 0? utUnioncases + (Union)->firstUnioncaseIndex: \
284         utUnioncaseNull)
285 #define utUnionGetNextUnionUnioncase(Union, Unioncase) \
286     ((((Unioncase) - utUnioncases + 1) >= ((Union)->firstUnioncaseIndex + (Union)->numUnioncases))? \
287      utUnioncaseNull:((Unioncase) + 1))
288 #define utForeachUnionUnioncase(Union, Unioncase)\
289     for((Unioncase) = utUnionGetFirstUnioncase(Union); (Unioncase) != utUnioncaseNull; \
290         (Unioncase) = utUnionGetNextUnionUnioncase(Union, Unioncase))
291 #define utEndUnionUnioncase
292 
293 extern struct utUnionStruct *utUnions;
294 extern uint16 utAllocatedUnions, utUsedUnions;
295 
296 struct utUnioncaseStruct {
297     uint32 value;
298     utFieldType type;
299     uint32 size;
300 };
301 
302 extern struct utUnioncaseStruct *utUnioncases;
303 extern uint16 utAllocatedUnioncases, utUsedUnioncases;
304 #define utUnioncaseGetValue(Unioncase) (Unioncase->value)
305 #define utUnioncaseGetSize(Unioncase) (Unioncase->size)
306 #define utUnioncaseGetType(Unioncase) (Unioncase->type)
307 #define utUnioncaseSetValue(Unioncase, value) (Unioncase->value = (value))
308 #define utUnioncaseSetSize(Unioncase, value) (Unioncase->size = (value))
309 #define utUnioncaseSetType(Unioncase, value) (Unioncase->type = (value))
310 /* Some utilities */
311 uint64 utFindIntValue(void *values, uint8 size);
312 void utSetInteger(uint8 *dest, uint64 value, uint8 width);
313 
314 /* This keeps us from writing the the unopened changes file before starting persistence */
315 extern bool utPersistenceInitialized;
316 extern char *utDatabaseDirectory;
317 extern bool utUseTextDatabaseFormat;
318 
319 #endif
320