Mercurial > hg > dmlib
view dmpack.c @ 722:ad3965b93ef1
Merge.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 21 Apr 2013 16:42:35 +0300 |
parents | bb14d7907eb2 324374ced543 |
children |
line wrap: on
line source
/* * DMLib * -- PACK-file handling * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2011 Tecnic Software productions (TNSP) */ #include "dmpack.h" #include "dmfile.h" DMPackEntry *dmPackEntryNew() { return (DMPackEntry *) dmMalloc0(sizeof(DMPackEntry)); } void dmPackEntryFree(DMPackEntry * node) { dmFree(node); } void dmPackEntryInsert(DMPackEntry ** packDir, DMPackEntry * node) { if (*packDir != NULL) { node->prev = (*packDir)->prev; (*packDir)->prev->next = node; (*packDir)->prev = node; } else { *packDir = node->prev = node; } node->next = NULL; } void dmPackEntryDelete(DMPackEntry ** packDir, DMPackEntry * node) { if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; else (*packDir)->prev = node->prev; node->prev = node->next = NULL; } DMPackEntry *dmPackFind(DMPackEntry *list, const char *filename) { DMPackEntry *node; for (node = list; node != NULL; node = node->next) { if (strcmp(node->filename, filename) == 0) return node; } return NULL; } /* * OPEN a packfile */ int dmPackOpen(const char *filename, DMPackFile ** ppPack, BOOL readOnly) { unsigned int i; DMPackFile *pack; DMPackFileHeader hdr; *ppPack = NULL; // Allocate packfile-structure pack = (DMPackFile *) dmMalloc0(sizeof(DMPackFile)); if (pack == NULL) return DMERR_MALLOC; // Open the file pack->file = fopen(filename, readOnly ? "rb" : "r+b"); if (pack->file == NULL) { dmFree(pack); return DMERR_FOPEN; } pack->filename = dm_strdup(filename); // Read PACK header fseek(pack->file, 0L, SEEK_SET); if (!dm_fread_str(pack->file, (Uint8 *) &hdr.ident, sizeof(hdr.ident)) || !dm_fread_le16(pack->file, &hdr.version) || !dm_fread_le32(pack->file, &hdr.dirEntries) || !dm_fread_le32(pack->file, &hdr.dirOffset)) { dmPackClose(pack); return DMERR_FREAD; } // Check information if (memcmp(&hdr.ident, DPACK_IDENT, sizeof(hdr.ident)) != 0) { dmPackClose(pack); return DMERR_NOTPACK; } if (hdr.version != DPACK_VERSION) { dmPackClose(pack); return DMERR_VERSION; } // Read directory if (fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0) { dmPackClose(pack); return DMERR_INVALID; } for (i = 0; i < hdr.dirEntries; i++) { // Allocate and read directory entry DMPackEntry *entry = dmPackEntryNew(); if (entry == NULL) { dmPackClose(pack); return DMERR_MALLOC; } if (!dm_fread_str(pack->file, (Uint8 *) &entry->filename, sizeof(entry->filename)) || !dm_fread_le32(pack->file, &entry->size) || !dm_fread_le32(pack->file, &entry->offset) || !dm_fread_le32(pack->file, &entry->length) || !dm_fread_le32(pack->file, &entry->flags)) { *ppPack = pack; return DMERR_FREAD; } // Insert into list dmPackEntryInsert(&pack->entries, entry); } // Set the result *ppPack = pack; return DMERR_OK; } /* * CLOSE the packfile */ int dmPackClose(DMPackFile * pack) { DMPackEntry *node; if (pack == NULL) return DMERR_OK; // Write the directory node = pack->entries; while (node != NULL) { DMPackEntry *next = node->next; dmPackEntryFree(node); node = next; } // Close the file if (pack->file != NULL) { fclose(pack->file); pack->file = NULL; } // Free structures dmFree(pack->filename); pack->filename = NULL; // Free packfile pack->entries = NULL; dmFree(pack); return DMERR_OK; }