Mercurial > hg > dmlib
view dmpack.c @ 510:43ea59887c69
Start work on making C64 formats encoding possible by changing DMDecodeOps
to DMEncDecOps and adding fields and op enums for custom encode functions, renaming,
etc. Split generic op sanity checking into a separate function in
preparation for its use in generic encoding function.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 19 Nov 2012 15:06:01 +0200 |
parents | 32250b436bca |
children | 324374ced543 bb14d7907eb2 |
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" #include <zlib.h> DMPackEntry *dm_pack_entry_new() { return (DMPackEntry *) dmMalloc0(sizeof(DMPackEntry)); } void dm_pack_entry_free(DMPackEntry * node) { dmFree(node); } void dm_pack_entry_insert(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 dm_pack_entry_delete(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 *dm_pack_find(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 dm_pack_open(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)) { dm_pack_close(pack); return DMERR_FREAD; } // Check information if (memcmp(&hdr.ident, DPACK_IDENT, sizeof(hdr.ident)) != 0) { dm_pack_close(pack); return DMERR_NOTPACK; } if (hdr.version != DPACK_VERSION) { dm_pack_close(pack); return DMERR_VERSION; } // Read directory if (fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0) { dm_pack_close(pack); return DMERR_INVALID; } for (i = 0; i < hdr.dirEntries; i++) { // Allocate and read directory entry DMPackEntry *entry = dm_pack_entry_new(); if (entry == NULL) { dm_pack_close(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->resFlags)) { *ppPack = pack; return DMERR_FREAD; } // Insert into list dm_pack_entry_insert(&pack->entries, entry); } // Set the result *ppPack = pack; return DMERR_OK; } /* * CLOSE the packfile */ int dm_pack_close(DMPackFile * pack) { DMPackEntry *node, *next; if (pack == NULL) return DMERR_OK; // Write the directory node = pack->entries; while (node != NULL) { next = node->next; dm_pack_entry_free(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; }