Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

entriesblk.cpp

00001 #include <entriesblk.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 
00005 const int EntriesBlock::METAHEADERSIZE = 4;
00006         // count(4);
00007 const int EntriesBlock::METAENTRYSIZE = 8;
00008         // offset(4); size(4);
00009 
00010 EntriesBlock::EntriesBlock(const char *iBlock, unsigned long size) {
00011         block = (char *)calloc(1, size);
00012         memcpy(block, iBlock, size);
00013 }
00014 
00015 
00016 EntriesBlock::EntriesBlock() {
00017         block = (char *)calloc(1, sizeof(__u32));
00018 }
00019 
00020 
00021 EntriesBlock::~EntriesBlock() {
00022         free(block);
00023 }
00024 
00025 
00026 void EntriesBlock::setCount(int count) {
00027         __u32 rawCount = archtosword32(count);
00028         memcpy(block, &rawCount, sizeof(__u32));
00029 }
00030 
00031 
00032 int EntriesBlock::getCount() {
00033         __u32 count = 0;
00034         memcpy(&count, block, sizeof(__u32));
00035         count = swordtoarch32(count);
00036         return count;
00037 }
00038 
00039 
00040 void EntriesBlock::getMetaEntry(int index, unsigned long *offset, unsigned long *size) {
00041         __u32 rawOffset = 0;
00042         __u32 rawSize = 0;
00043         *offset = 0;
00044         *size = 0;
00045         if (index >= getCount())        // assert index < count
00046                 return;
00047 
00048         // first 4 bytes is count, each 6 bytes after is each meta entry
00049         memcpy(&rawOffset, block + METAHEADERSIZE + (index * METAENTRYSIZE), sizeof(rawOffset));
00050         memcpy(&rawSize, block + METAHEADERSIZE + (index * METAENTRYSIZE) + sizeof(rawOffset), sizeof(rawSize));
00051 
00052         *offset = (unsigned long)swordtoarch32(rawOffset);
00053         *size   = (unsigned long)swordtoarch32(rawSize);
00054 }
00055 
00056 
00057 void EntriesBlock::setMetaEntry(int index, unsigned long offset, unsigned long size) {
00058         __u32 rawOffset = archtosword32(offset);
00059         __u32 rawSize = archtosword32(size);
00060 
00061         if (index >= getCount())        // assert index < count
00062                 return;
00063 
00064         // first 4 bytes is count, each 6 bytes after is each meta entry
00065         memcpy(block + METAHEADERSIZE + (index * METAENTRYSIZE), &rawOffset, sizeof(rawOffset));
00066         memcpy(block + METAHEADERSIZE + (index * METAENTRYSIZE) + sizeof(rawOffset), &rawSize, sizeof(rawSize));
00067 }
00068 
00069 
00070 const char *EntriesBlock::getRawData(unsigned long *retSize) {
00071         unsigned long max = 4;
00072         int loop;
00073         unsigned long offset;
00074         unsigned long size;
00075         for (loop = 0; loop < getCount(); loop++) {
00076                 getMetaEntry(loop, &offset, &size);
00077                 max = ((offset + size) > max) ? (offset + size) : max;
00078         }
00079         *retSize = max;
00080         return block;
00081 }
00082 
00083 
00084 int EntriesBlock::addEntry(const char *entry) {
00085         unsigned long dataSize;
00086         getRawData(&dataSize);
00087         unsigned long  len = strlen(entry);
00088         unsigned long offset;
00089         unsigned long size;
00090         int count = getCount();
00091         unsigned long dataStart = METAHEADERSIZE + (count * METAENTRYSIZE);
00092         // new meta entry + new data size + 1 because null 
00093         block = (char *)realloc(block, dataSize + METAENTRYSIZE + len + 1);
00094         // shift right to make room for new meta entry
00095         memmove(block + dataStart + METAENTRYSIZE, block + dataStart, dataSize - dataStart);
00096 
00097         for (int loop = 0; loop < count; loop++) {
00098                 getMetaEntry(loop, &offset, &size);
00099                 if (offset) {   // if not a deleted entry
00100                         offset += METAENTRYSIZE;
00101                         setMetaEntry(loop, offset, size);
00102                 }
00103         }
00104 
00105         offset = dataSize;      // original dataSize before realloc
00106         size = len + 1;
00107         // add our text to the end
00108         memcpy(block + offset + METAENTRYSIZE, entry, size);
00109         // increment count
00110         setCount(count + 1);
00111         // add our meta entry
00112         setMetaEntry(count, offset + METAENTRYSIZE, size);
00113         // return index of our new entry
00114         return count;
00115 }
00116 
00117 
00118 const char *EntriesBlock::getEntry(int entryIndex) {
00119         unsigned long offset;
00120         unsigned long size;
00121         static char *empty = "";
00122 
00123         getMetaEntry(entryIndex, &offset, &size);
00124         return (offset) ? block+offset : empty;
00125 }
00126 
00127 
00128 unsigned long EntriesBlock::getEntrySize(int entryIndex) {
00129         unsigned long offset;
00130         unsigned long size;
00131 
00132         getMetaEntry(entryIndex, &offset, &size);
00133         return (offset) ? size : 0;
00134 }
00135 
00136 
00137 void EntriesBlock::removeEntry(int entryIndex) {
00138         unsigned long offset;
00139         unsigned long size, size2;
00140         unsigned long dataSize;
00141         getRawData(&dataSize);
00142         getMetaEntry(entryIndex, &offset, &size);
00143         unsigned long len = size - 1;
00144         int count = getCount();
00145         unsigned long dataStart = METAHEADERSIZE + (count * METAENTRYSIZE);
00146 
00147         if (!offset)    // already deleted
00148                 return;
00149 
00150         // shift left to retrieve space used for old entry
00151         memmove(block + offset, block + offset + size, dataSize - (offset + size));
00152 
00153         // fix offset for all entries after our entry that were shifted left
00154         for (int loop = entryIndex + 1; loop < count; loop++) {
00155                 getMetaEntry(loop, &offset, &size2);
00156                 if (offset) {   // if not a deleted entry
00157                         offset -= size;
00158                         setMetaEntry(loop, offset, size2);
00159                 }
00160         }
00161 
00162         // zero out our meta entry
00163         setMetaEntry(entryIndex, 0L, 0);
00164 }
00165 
00166 

Generated on Thu Jun 20 22:12:59 2002 for The Sword Project by doxygen1.2.15