diff options
Diffstat (limited to 'Source/Core/Common/Src/ChunkFile.cpp')
| -rw-r--r-- | Source/Core/Common/Src/ChunkFile.cpp | 234 |
1 files changed, 139 insertions, 95 deletions
diff --git a/Source/Core/Common/Src/ChunkFile.cpp b/Source/Core/Common/Src/ChunkFile.cpp index 849f692631..be2dad6788 100644 --- a/Source/Core/Common/Src/ChunkFile.cpp +++ b/Source/Core/Common/Src/ChunkFile.cpp @@ -25,151 +25,195 @@ ChunkFile::ChunkFile(const char *filename, ChunkFileMode _mode)
{
- mode = _mode;
- data = 0;
-
- didFail = false;
- f = fopen(filename, mode == MODE_WRITE ? "wb" : "rb");
- if (!f) {
- didFail = true;
- return;
- }
+ mode = _mode;
+ data = 0;
+
+ didFail = false;
+ f = fopen(filename, mode == MODE_WRITE ? "wb" : "rb");
+ if (!f) {
+ didFail = true;
+ return;
+ }
- fseek(f, 0, SEEK_END);
- size = ftell(f);
- eof = size;
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ eof = size;
- stack_ptr = 0;
+ stack_ptr = 0;
}
ChunkFile::~ChunkFile()
{
- if (f)
- fclose(f);
+ if (f)
+ fclose(f);
}
int ChunkFile::ReadInt()
{
- int x;
- fread(&x, 4, 1, f);
- return x;
+ int x;
+ fread(&x, 4, 1, f);
+ return x;
}
void ChunkFile::WriteInt(int x)
{
- fwrite(&x, 4, 1, f);
+ fwrite(&x, 4, 1, f);
}
bool ChunkFile::Do(void *ptr, int size)
{
- int sz;
- switch (mode) {
- case MODE_READ:
- sz = ReadInt();
- if (sz != size)
- return false;
- fread(ptr, size, 1, f);
- fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
- break;
- case MODE_WRITE:
- WriteInt(size);
- fwrite(ptr, size, 1, f);
- fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
- break;
- case MODE_VERIFY:
- sz = ReadInt();
- if (sz != size)
- return false;
- fseek(f, (size + 3) & ~3, SEEK_CUR);
- break;
- }
- return true;
+ int sz;
+ switch (mode) {
+ case MODE_READ:
+ sz = ReadInt();
+ if (sz != size)
+ return false;
+ fread(ptr, size, 1, f);
+ fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
+ break;
+ case MODE_WRITE:
+ WriteInt(size);
+ fwrite(ptr, size, 1, f);
+ fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
+ break;
+ case MODE_VERIFY:
+ sz = ReadInt();
+ if (sz != size)
+ return false;
+ fseek(f, (size + 3) & ~3, SEEK_CUR);
+ break;
+ }
+ return true;
+}
+
+// Do variable size array (probably heap-allocated)
+bool DoArray(void *ptr, int size, int arrSize) {
+ int sz;
+
+ if(ptr == NULL)
+ return false;
+
+ switch (mode) {
+ case MODE_READ:
+ sz = ReadInt();
+ if (sz != size)
+ return false;
+ sz = ReadInt();
+ if (sz != arrSize)
+ return false;
+
+ for(int i = 0; i < arrSize; i++) {
+ fread(ptr[i], size, 1, f);
+ fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
+ }
+ break;
+ case MODE_WRITE:
+ WriteInt(size);
+ WriteInt(arrSize);
+ for(int i = 0; i < arrSize; i++) {
+ fwrite(ptr[i], size, 1, f);
+ fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
+ }
+ break;
+ case MODE_VERIFY:
+ sz = ReadInt();
+ if (sz != size)
+ return false;
+ sz = ReadInt();
+ if (sz != arrSize)
+ return false;
+
+ for(int i = 0; i < arrSize; i++)
+ fseek(f, (size + 3) & ~3, SEEK_CUR);
+ break;
+ }
+ return true;
}
//let's get into the business
bool ChunkFile::Descend(const char *cid)
{
- unsigned int id = *reinterpret_cast<const unsigned int*>(cid);
- if (mode == MODE_READ)
+ unsigned int id = *reinterpret_cast<const unsigned int*>(cid);
+ if (mode == MODE_READ)
{
- bool found = false;
- int startPos = ftell(f);
- ChunkInfo temp = stack[stack_ptr];
+ bool found = false;
+ int startPos = ftell(f);
+ ChunkInfo temp = stack[stack_ptr];
- //save information to restore after the next Ascend
- stack[stack_ptr].parentStartLocation = startPos;
- stack[stack_ptr].parentEOF = eof;
+ //save information to restore after the next Ascend
+ stack[stack_ptr].parentStartLocation = startPos;
+ stack[stack_ptr].parentEOF = eof;
- unsigned int firstID = 0;
- //let's search through children..
- while (ftell(f) < eof)
+ unsigned int firstID = 0;
+ //let's search through children..
+ while (ftell(f) < eof)
{
- stack[stack_ptr].ID = ReadInt();
- if (firstID == 0)
- firstID = stack[stack_ptr].ID|1;
- stack[stack_ptr].length = ReadInt();
- stack[stack_ptr].startLocation = ftell(f);
- if (stack[stack_ptr].ID == id)
+ stack[stack_ptr].ID = ReadInt();
+ if (firstID == 0)
+ firstID = stack[stack_ptr].ID|1;
+ stack[stack_ptr].length = ReadInt();
+ stack[stack_ptr].startLocation = ftell(f);
+ if (stack[stack_ptr].ID == id)
{
- found = true;
- break;
+ found = true;
+ break;
}
- else
+ else
{
- fseek(f, stack[stack_ptr].length, SEEK_CUR); //try next block
+ fseek(f, stack[stack_ptr].length, SEEK_CUR); //try next block
}
}
- //if we found nothing, return false so the caller can skip this
- if (!found)
+ //if we found nothing, return false so the caller can skip this
+ if (!found)
{
- stack[stack_ptr] = temp;
- fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
- return false;
+ stack[stack_ptr] = temp;
+ fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
+ return false;
}
- //descend into it
- //pos was set inside the loop above
- eof = stack[stack_ptr].startLocation + stack[stack_ptr].length;
- stack_ptr++;
- return true;
+ //descend into it
+ //pos was set inside the loop above
+ eof = stack[stack_ptr].startLocation + stack[stack_ptr].length;
+ stack_ptr++;
+ return true;
}
- else
+ else
{
- //write a chunk id, and prepare for filling in length later
- WriteInt(id);
- WriteInt(0); //will be filled in by Ascend
- stack[stack_ptr].startLocation = ftell(f);
- stack_ptr++;
- return true;
+ //write a chunk id, and prepare for filling in length later
+ WriteInt(id);
+ WriteInt(0); //will be filled in by Ascend
+ stack[stack_ptr].startLocation = ftell(f);
+ stack_ptr++;
+ return true;
}
}
//let's ascend out
void ChunkFile::Ascend()
{
- if (mode == MODE_READ)
+ if (mode == MODE_READ)
{
- //ascend, and restore information
- stack_ptr--;
- fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
- eof = stack[stack_ptr].parentEOF;
+ //ascend, and restore information
+ stack_ptr--;
+ fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
+ eof = stack[stack_ptr].parentEOF;
}
- else
+ else
{
- stack_ptr--;
- //now fill in the written length automatically
- int posNow = ftell(f);
- fseek(f, stack[stack_ptr].startLocation - 4, SEEK_SET);
- WriteInt(posNow - stack[stack_ptr].startLocation);
- fseek(f, posNow, SEEK_SET);
+ stack_ptr--;
+ //now fill in the written length automatically
+ int posNow = ftell(f);
+ fseek(f, stack[stack_ptr].startLocation - 4, SEEK_SET);
+ WriteInt(posNow - stack[stack_ptr].startLocation);
+ fseek(f, posNow, SEEK_SET);
}
}
int ChunkFile::GetCurrentChunkSize()
{
- if (stack_ptr)
- return stack[stack_ptr - 1].length;
- else
- return 0;
+ if (stack_ptr)
+ return stack[stack_ptr - 1].length;
+ else
+ return 0;
}
|
