<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>entriesblk.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="hierarchy.html">Class Hierarchy</a> <a class="qindex" href="classes.html">Alphabetical List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> </center>
<hr><h1>entriesblk.cpp</h1><div class="fragment"><pre>00001 <font class="preprocessor">#include <entriesblk.h></font>
00002 <font class="preprocessor">#include <stdlib.h></font>
00003 <font class="preprocessor">#include <string.h></font>
00004
00005 <font class="keyword">const</font> <font class="keywordtype">int</font> EntriesBlock::METAHEADERSIZE = 4;
00006 <font class="comment">// count(4);</font>
00007 <font class="keyword">const</font> <font class="keywordtype">int</font> EntriesBlock::METAENTRYSIZE = 8;
00008 <font class="comment">// offset(4); size(4);</font>
00009
00010 EntriesBlock::EntriesBlock(<font class="keyword">const</font> <font class="keywordtype">char</font> *iBlock, <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size) {
00011 block = (<font class="keywordtype">char</font> *)calloc(1, size);
00012 memcpy(block, iBlock, size);
00013 }
00014
00015
00016 EntriesBlock::EntriesBlock() {
00017 block = (<font class="keywordtype">char</font> *)calloc(1, <font class="keyword">sizeof</font>(__u32));
00018 }
00019
00020
00021 EntriesBlock::~EntriesBlock() {
00022 free(block);
00023 }
00024
00025
00026 <font class="keywordtype">void</font> EntriesBlock::setCount(<font class="keywordtype">int</font> count) {
00027 __u32 rawCount = archtosword32(count);
00028 memcpy(block, &rawCount, <font class="keyword">sizeof</font>(__u32));
00029 }
00030
00031
00032 <font class="keywordtype">int</font> EntriesBlock::getCount() {
00033 __u32 count = 0;
00034 memcpy(&count, block, <font class="keyword">sizeof</font>(__u32));
00035 count = swordtoarch32(count);
00036 <font class="keywordflow">return</font> count;
00037 }
00038
00039
00040 <font class="keywordtype">void</font> EntriesBlock::getMetaEntry(<font class="keywordtype">int</font> index, <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> *offset, <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> *size) {
00041 __u32 rawOffset = 0;
00042 __u32 rawSize = 0;
00043 *offset = 0;
00044 *size = 0;
00045 <font class="keywordflow">if</font> (index >= getCount()) <font class="comment">// assert index < count</font>
00046 <font class="keywordflow">return</font>;
00047
00048 <font class="comment">// first 4 bytes is count, each 6 bytes after is each meta entry</font>
00049 memcpy(&rawOffset, block + METAHEADERSIZE + (index * METAENTRYSIZE), <font class="keyword">sizeof</font>(rawOffset));
00050 memcpy(&rawSize, block + METAHEADERSIZE + (index * METAENTRYSIZE) + <font class="keyword">sizeof</font>(rawOffset), <font class="keyword">sizeof</font>(rawSize));
00051
00052 *offset = (<font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>)swordtoarch32(rawOffset);
00053 *size = (<font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>)swordtoarch32(rawSize);
00054 }
00055
00056
00057 <font class="keywordtype">void</font> EntriesBlock::setMetaEntry(<font class="keywordtype">int</font> index, <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> offset, <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size) {
00058 __u32 rawOffset = archtosword32(offset);
00059 __u32 rawSize = archtosword32(size);
00060
00061 <font class="keywordflow">if</font> (index >= getCount()) <font class="comment">// assert index < count</font>
00062 <font class="keywordflow">return</font>;
00063
00064 <font class="comment">// first 4 bytes is count, each 6 bytes after is each meta entry</font>
00065 memcpy(block + METAHEADERSIZE + (index * METAENTRYSIZE), &rawOffset, <font class="keyword">sizeof</font>(rawOffset));
00066 memcpy(block + METAHEADERSIZE + (index * METAENTRYSIZE) + <font class="keyword">sizeof</font>(rawOffset), &rawSize, <font class="keyword">sizeof</font>(rawSize));
00067 }
00068
00069
00070 <font class="keyword">const</font> <font class="keywordtype">char</font> *EntriesBlock::getRawData(<font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> *retSize) {
00071 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> max = 4;
00072 <font class="keywordtype">int</font> loop;
00073 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> offset;
00074 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size;
00075 <font class="keywordflow">for</font> (loop = 0; loop < getCount(); loop++) {
00076 getMetaEntry(loop, &offset, &size);
00077 max = ((offset + size) > max) ? (offset + size) : max;
00078 }
00079 *retSize = max;
00080 <font class="keywordflow">return</font> block;
00081 }
00082
00083
00084 <font class="keywordtype">int</font> EntriesBlock::addEntry(<font class="keyword">const</font> <font class="keywordtype">char</font> *entry) {
00085 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> dataSize;
00086 getRawData(&dataSize);
00087 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> len = strlen(entry);
00088 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> offset;
00089 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size;
00090 <font class="keywordtype">int</font> count = getCount();
00091 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> dataStart = METAHEADERSIZE + (count * METAENTRYSIZE);
00092 <font class="comment">// new meta entry + new data size + 1 because null </font>
00093 block = (<font class="keywordtype">char</font> *)realloc(block, dataSize + METAENTRYSIZE + len + 1);
00094 <font class="comment">// shift right to make room for new meta entry</font>
00095 memmove(block + dataStart + METAENTRYSIZE, block + dataStart, dataSize - dataStart);
00096
00097 <font class="keywordflow">for</font> (<font class="keywordtype">int</font> loop = 0; loop < count; loop++) {
00098 getMetaEntry(loop, &offset, &size);
00099 <font class="keywordflow">if</font> (offset) { <font class="comment">// if not a deleted entry</font>
00100 offset += METAENTRYSIZE;
00101 setMetaEntry(loop, offset, size);
00102 }
00103 }
00104
00105 offset = dataSize; <font class="comment">// original dataSize before realloc</font>
00106 size = len + 1;
00107 <font class="comment">// add our text to the end</font>
00108 memcpy(block + offset + METAENTRYSIZE, entry, size);
00109 <font class="comment">// increment count</font>
00110 setCount(count + 1);
00111 <font class="comment">// add our meta entry</font>
00112 setMetaEntry(count, offset + METAENTRYSIZE, size);
00113 <font class="comment">// return index of our new entry</font>
00114 <font class="keywordflow">return</font> count;
00115 }
00116
00117
00118 <font class="keyword">const</font> <font class="keywordtype">char</font> *EntriesBlock::getEntry(<font class="keywordtype">int</font> entryIndex) {
00119 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> offset;
00120 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size;
00121 <font class="keyword">static</font> <font class="keywordtype">char</font> *empty = <font class="stringliteral">""</font>;
00122
00123 getMetaEntry(entryIndex, &offset, &size);
00124 <font class="keywordflow">return</font> (offset) ? block+offset : empty;
00125 }
00126
00127
00128 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> EntriesBlock::getEntrySize(<font class="keywordtype">int</font> entryIndex) {
00129 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> offset;
00130 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size;
00131
00132 getMetaEntry(entryIndex, &offset, &size);
00133 <font class="keywordflow">return</font> (offset) ? size : 0;
00134 }
00135
00136
00137 <font class="keywordtype">void</font> EntriesBlock::removeEntry(<font class="keywordtype">int</font> entryIndex) {
00138 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> offset;
00139 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size, size2;
00140 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> dataSize;
00141 getRawData(&dataSize);
00142 getMetaEntry(entryIndex, &offset, &size);
00143 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> len = size - 1;
00144 <font class="keywordtype">int</font> count = getCount();
00145 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> dataStart = METAHEADERSIZE + (count * METAENTRYSIZE);
00146
00147 <font class="keywordflow">if</font> (!offset) <font class="comment">// already deleted</font>
00148 <font class="keywordflow">return</font>;
00149
00150 <font class="comment">// shift left to retrieve space used for old entry</font>
00151 memmove(block + offset, block + offset + size, dataSize - (offset + size));
00152
00153 <font class="comment">// fix offset for all entries after our entry that were shifted left</font>
00154 <font class="keywordflow">for</font> (<font class="keywordtype">int</font> loop = entryIndex + 1; loop < count; loop++) {
00155 getMetaEntry(loop, &offset, &size2);
00156 <font class="keywordflow">if</font> (offset) { <font class="comment">// if not a deleted entry</font>
00157 offset -= size;
00158 setMetaEntry(loop, offset, size2);
00159 }
00160 }
00161
00162 <font class="comment">// zero out our meta entry</font>
00163 setMetaEntry(entryIndex, 0L, 0);
00164 }
00165
00166
</pre></div><hr><address align="right"><small>Generated on Thu Jun 20 22:12:59 2002 for The Sword Project by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>