int/*perr*/ File::Init( File* inParent, File** inSibPrev, const wchar_t* inName, int8_t inFileType, uint8_t inFileFlags, int64_t inWriteTime) { name = sswdup( inName); int perr = pfmErrorOutOfMemory; if (name) { perr = 0; parent = inParent; sibPrev = inSibPrev; sibNext = *sibPrev; if (sibNext) { ASSERT( sibNext->parent == parent && sibNext->sibPrev == sibPrev); sibNext->sibPrev = &sibNext; } *sibPrev = this; volume->CheckConsistency(); fileType = inFileType; fileFlags = inFileFlags; fileId = ++(volume->lastFileId); createTime = accessTime = writeTime = changeTime = inWriteTime; parent->accessTime = parent->writeTime = parent->changeTime = inWriteTime; } return perr; }
void File::Open( int64_t newOpenId, PfmOpenAttribs* openAttribs, int64_t* parentFileId, const wchar_t** endName) { if (!openPrev) { if (!openId) { openId = newOpenId; } openPrev = &volume->firstOpenFile; openNext = *openPrev; if (openNext) { ASSERT( openNext->openPrev == openPrev); openNext->openPrev = &openNext; } *openPrev = this; volume->CheckConsistency(); } Opened( openAttribs); if (parentFileId && parent) { *parentFileId = parent->fileId; } if (endName && name) { *endName = name; } }
int/*perr*/ File::Move( File* inParent, File** inSibPrev, const wchar_t* inNewName, int64_t writeTime) { int perr = 0; File* check = parent; while (check && check != this) { check = check->parent; } if (check) { // Can't move a folder into itself. perr = pfmErrorInvalid; } else { wchar_t* newName = sswdup( inNewName); if (!newName) { perr = pfmErrorOutOfMemory; } else if (inParent == parent) { // Simple rename, not changing parent folders. free( name); name = newName; } else { Delete( writeTime, true/*leaveChildren*/); name = newName; parent = inParent; sibPrev = inSibPrev; sibNext = *sibPrev; if (sibNext) { ASSERT( sibNext->parent == parent && sibNext->sibPrev == sibPrev); sibNext->sibPrev = &sibNext; } *sibPrev = this; volume->CheckConsistency(); } if (!perr && writeTime != pfmTimeInvalid) { parent->writeTime = writeTime; } } return perr; }
void File::Close( int64_t checkOpenSequence) { if (openPrev && checkOpenSequence >= openSequence) { ASSERT( *openPrev == this); *openPrev = openNext; if (openNext) { ASSERT( openNext->openPrev == &openNext); openNext->openPrev = openPrev; } openPrev = 0; volume->CheckConsistency(); } if (!sibPrev && !openPrev && this != &volume->root) { delete this; } }
void File::Delete( int64_t writeTime, bool leaveChildren) { if (sibPrev) { if (!leaveChildren && fileType == pfmFileTypeFolder) { while (data.folder.firstChild) { data.folder.firstChild->Delete( writeTime, false/*leaveChildren*/); } } // Make sure no list iterators are referencing this file. for (FileList* list = parent->data.folder.firstList; !!list; list = list->next) { if (list->position == &sibNext) { list->position = sibPrev; } } ASSERT( *sibPrev == this); *sibPrev = sibNext; if (sibNext) { ASSERT( sibNext->sibPrev == &sibNext); sibNext->sibPrev = sibPrev; } if (writeTime != pfmTimeInvalid) { parent->writeTime = writeTime; } parent = 0; sibPrev = 0; volume->CheckConsistency(); free( name); name = 0; } if (!sibPrev && !openPrev && this != &(volume->root)) { delete this; } }