📄 utpersist.c
字号:
utDatabaseSize = utFindFileSize(utSprintf("%s%cdatabase", utDatabaseDirectory, UTDIRSEP)); resetCommandBuffer(); fclose(utRecentChangesFile); openRecentChanges("wb");}/*-------------------------------------------------------------------------------------------------- Mark the transaction complete, and optionally fush to disk.--------------------------------------------------------------------------------------------------*/void utTransactionComplete( bool flushToDisk){ uint32 checksum = utChecksum; uint32 length; writeUint8(UT_TRANSACTION_COMPLETE); writeUint32(checksum); utChecksum = 0; length = utBufferStartPosition + utBufferPosition - utLastTransactionPosition; utTransactionCreate(utLastTransactionPosition, length); utLastTransactionPosition += length; if(utPersistenceInitialized) { if(flushToDisk) { flushRecentChanges(); fflush(utRecentChangesFile); }#ifndef UT_USE_UTDATABASEUP_H /* Don't do this if we are a persistent undo/redo database */ if((utBufferStartPosition << 2) > utDatabaseSize) { utCompactDatabase(); }#endif }}/*-------------------------------------------------------------------------------------------------- Register an enumerated type.--------------------------------------------------------------------------------------------------*/void utRegisterEnum( char *name, uint16 numEntries){ utEnum theEnum; if(utUsedEnums == utAllocatedEnums) { utAllocatedEnums += utAllocatedEnums >> 1; utResizeArray(utEnums, utAllocatedEnums); } theEnum = utEnums + utUsedEnums++; theEnum->name = calloc(strlen(name) + 1, sizeof(char)); strcpy(theEnum->name, name); theEnum->firstEntryIndex = utUsedEntries; theEnum->numEntries = numEntries;}/*-------------------------------------------------------------------------------------------------- Register an entry in an enumerated type.--------------------------------------------------------------------------------------------------*/void utRegisterEntry( char *name, uint32 value){ utEntry entry; if(utUsedEntries == utAllocatedEntries) { utAllocatedEntries += utAllocatedEntries >> 1; utResizeArray(utEntries, utAllocatedEntries); } entry = utEntries + utUsedEntries++; entry->name = calloc(strlen(name) + 1, sizeof(char)); entry->value = value; strcpy(entry->name, name);}/*-------------------------------------------------------------------------------------------------- Register the previously registered field as a union.--------------------------------------------------------------------------------------------------*/void utRegisterUnion( char *switchFieldName, uint16 numCases){ utField unionField = utFields + utUsedFields - 1; utUnion theUnion; utField switchField = utFindField(utCurrentClass, switchFieldName); if(utUsedUnions == utAllocatedUnions) { utAllocatedUnions += utAllocatedUnions >> 1; utResizeArray(utUnions, utAllocatedUnions); } unionField->unionIndex = utUsedUnions; theUnion = utUnions + utUsedUnions++; theUnion->switchFieldIndex = switchField - utFields; theUnion->fieldIndex = utUsedFields - 1; theUnion->firstUnionCaseIndex = utUsedUnionCases; theUnion->numUnionCases = numCases;}/*-------------------------------------------------------------------------------------------------- Write the variable sized integer.--------------------------------------------------------------------------------------------------*/void utRegisterUnionCase( uint32 value, utFieldType type, uint32 size){ utUnionCase unionCase; if(utUsedUnionCases == utAllocatedUnionCases) { utAllocatedUnionCases += utAllocatedUnionCases >> 1; utResizeArray(utUnionCases, utAllocatedUnionCases); } unionCase = utUnionCases + utUsedUnionCases++; unionCase->value = value; if(type == UT_BIT) { type = UT_BOOL; /* We convert bit to bool in unions */ size = sizeof(bool); } unionCase->size = size; unionCase->type = type;}/*-------------------------------------------------------------------------------------------------- Write the variable sized integer.--------------------------------------------------------------------------------------------------*/static void writeInteger( uint64 value, uint8 size){ switch(size) { case 1: writeUint8((uint8)value); break; case 2: writeUint16((uint16)value); break; case 4: writeUint32((uint32)value); break; case 8: writeUint64(value); break; default: utExit("Invalid reference size"); }}/*-------------------------------------------------------------------------------------------------- Record the change to the field.--------------------------------------------------------------------------------------------------*/void utRecordField( uint8 moduleID, uint16 fieldIndex, uint64 objectNumber, bool undo){ utModule module = utModules + moduleID; uint16 fieldPosition = module->firstFieldIndex + fieldIndex; utField field = utFields + fieldPosition; utClass theClass = utClasses + field->classIndex; uint8 *values = *(uint8 **)(field->arrayPtr) + objectNumber*field->size; writeUint8(UT_WRITE_FIELD | (undo? 0x80 : 0)); writeUint16(fieldPosition); writeInteger(objectNumber, theClass->referenceSize); writeValues(values, field->size);}/*-------------------------------------------------------------------------------------------------- Record the change to the field.--------------------------------------------------------------------------------------------------*/void utRecordArray( uint8 moduleID, uint16 fieldIndex, uint32 dataIndex, uint32 length, bool undo){ utModule module = utModules + moduleID; uint16 fieldPosition = module->firstFieldIndex + fieldIndex; utField field = utFields + fieldPosition; uint8 *values = *(uint8 **)(field->arrayPtr) + dataIndex*field->size; writeUint8(UT_WRITE_ARRAY | (undo? 0x80 : 0)); writeUint16(fieldPosition); writeUint32(dataIndex); writeUint32(length); writeValues(values, field->size*length);}/*-------------------------------------------------------------------------------------------------- Record the change to the global value.--------------------------------------------------------------------------------------------------*/void utRecordGlobal( uint8 moduleID, uint8 numBytes, void *location, bool undo){ utModule module = utModules + moduleID; uint32 offset = ((uint8 *) location) - ((uint8 *) module->globalData); writeUint8(UT_WRITE_GLOBAL | (undo? 0x80 : 0)); writeUint8(moduleID); writeUint16(offset); writeUint8(numBytes); writeValues(location, numBytes);}/*-------------------------------------------------------------------------------------------------- Record when a field is resized.--------------------------------------------------------------------------------------------------*/void utRecordResize( uint8 moduleID, uint16 fieldIndex, uint64 length, bool undo){ utModule module = utModules + moduleID; uint16 fieldPosition = module->firstFieldIndex + fieldIndex; writeUint8(UT_RESIZE_FIELD | (undo? 0x80 : 0)); writeUint16(fieldPosition); writeUint64(length);}#define readUint8(buffer) (*(buffer))/*-------------------------------------------------------------------------------------------------- Read a uint16 from the command buffer.--------------------------------------------------------------------------------------------------*/static uint16 readUint16( uint8 *buffer){ return *(uint16 *)(void *)(buffer);}/*-------------------------------------------------------------------------------------------------- Read a uint32 from a buffer.--------------------------------------------------------------------------------------------------*/static uint32 readUint32( uint8 *buffer){ return *(uint32 *)(void *)(buffer);}/*-------------------------------------------------------------------------------------------------- Read a uint64 from a buffer.--------------------------------------------------------------------------------------------------*/static uint64 readUint64( uint8 *buffer){ return *(uint64 *)(void *)(buffer);}/*-------------------------------------------------------------------------------------------------- Apply a field value. WRITE_FIELD <16-bit field #> <32-bit index> <value>--------------------------------------------------------------------------------------------------*/static void applyField( uint8 *command){ uint16 xField = readUint16(command); utField field = utFields + xField; utClass theClass = utClasses + field->classIndex; uint8 *values; uint64 objectNumber; command += 2; objectNumber = utFindIntValue(command, theClass->referenceSize); command += theClass->referenceSize; values = *(uint8 **)(field->arrayPtr) + objectNumber*field->size; memcpy(values, command, field->size);}/*-------------------------------------------------------------------------------------------------- Apply an array of values. WRITE_ARRAY <16-bit field #> <32-bit index> <32-bit numValues> <values>--------------------------------------------------------------------------------------------------*/static void applyArray( uint8 *command){ uint16 xField = readUint16(command); utField field = utFields + xField; uint8 *values; uint32 length, bytes; uint32 dataIndex; command += 2; dataIndex = readUint32(command); command += 4; length = readUint32(command); command += 4; bytes = field->size*length; values = *(uint8 **)(field->arrayPtr) + dataIndex*field->size; memcpy(values, command, bytes);}/*-------------------------------------------------------------------------------------------------- Apply a global value change. WRITE_GLOBAL <8-bit moduleID> <16-bit offset> <8-bit numBytes> <values>--------------------------------------------------------------------------------------------------*/static void applyGlobal( uint8 *command){ uint8 moduleID = readUint8(command); utModule module = utModules + moduleID; uint16 offset; uint8 numBytes; uint8 *values; command++; offset = readUint16(command); command += 2; numBytes = readUint8(command); command++; values = (uint8 *)(module->globalData) + offset; memcpy(values, command, numBytes);}/*-------------------------------------------------------------------------------------------------- Apply a resize field command. RESIZE_FIELD <16-bit field #> <64-bit size>--------------------------------------------------------------------------------------------------*/static void applyResize( uint8 *command){ uint16 xField = readUint16(command); utField field = utFields + xField; uint64 size; command += 2; size = readUint64(command); command += 8; *(uint8 **)(field->arrayPtr) = utRealloc(*(uint8 **)field->arrayPtr, size, field->size);}/*-------------------------------------------------------------------------------------------------- Find the size of a command.--------------------------------------------------------------------------------------------------*/static uint32 findCommandSize( uint8 *command){ utClass theClass; utField field; uint16 xField; switch((*command) & 0x7f) { case UT_TRANSACTION_COMPLETE: /* TRANSACTION_COMPLETE <32-bit checksum> */ return 5; case UT_WRITE_FIELD: /* WRITE_FIELD <16-bit field #> <32-bit index> <value> */ xField = readUint16(command + 1); field = utFields + xField; theClass = utClasses + field->classIndex; return 3 + field->size + theClass->referenceSize; case UT_WRITE_ARRAY: /* WRITE_ARRAY <16-bit field #> <32-bit index> <32-bit numValues> <values> */ xField = readUint16(command + 1); field = utFields + xField; return 11 + field->size*readUint32(command + 7); case UT_WRITE_GLOBAL: /* WRITE_GLOBAL <8-bit moduleID> <16-bit offset> <8-bit numBytes> <values> */ return 5 + readUint8(command + 4); case UT_RESIZE_FIELD: /* RESIZE_FIELD <16-bit field #> <64-bit size> */ return 11; default: utExit("Invalid command"); } return 0;}/*-------------------------------------------------------------------------------------------------- Apply the command.--------------------------------------------------------------------------------------------------*/static void applyCommand( uint8 *command){ switch(*command++ & 0x7f) { case UT_WRITE_FIELD: applyField(command); break; case UT_WRITE_ARRAY: applyArray(command); break; case UT_WRITE_GLOBAL: applyGlobal(command); break; case UT_RESIZE_FIELD: applyResize(command); break; default: utExit("Unknown command in recentChanges file"); }}/*-------------------------------------------------------------------------------------------------- Apply changes from the commands in the buffer.--------------------------------------------------------------------------------------------------*/static void applyCommands( uint8 *commands, uint32 length){ uint32 xCommand = 0; uint32 size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -