00001 #include <entriesblk.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004
00005 const int EntriesBlock::METAHEADERSIZE = 4;
00006
00007 const int EntriesBlock::METAENTRYSIZE = 8;
00008
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())
00046 return;
00047
00048
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())
00062 return;
00063
00064
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
00093 block = (char *)realloc(block, dataSize + METAENTRYSIZE + len + 1);
00094
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) {
00100 offset += METAENTRYSIZE;
00101 setMetaEntry(loop, offset, size);
00102 }
00103 }
00104
00105 offset = dataSize;
00106 size = len + 1;
00107
00108 memcpy(block + offset + METAENTRYSIZE, entry, size);
00109
00110 setCount(count + 1);
00111
00112 setMetaEntry(count, offset + METAENTRYSIZE, size);
00113
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)
00148 return;
00149
00150
00151 memmove(block + offset, block + offset + size, dataSize - (offset + size));
00152
00153
00154 for (int loop = entryIndex + 1; loop < count; loop++) {
00155 getMetaEntry(loop, &offset, &size2);
00156 if (offset) {
00157 offset -= size;
00158 setMetaEntry(loop, offset, size2);
00159 }
00160 }
00161
00162
00163 setMetaEntry(entryIndex, 0L, 0);
00164 }
00165
00166