The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
entriesblk.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * entriesblk.cpp - EntriesBlock facilitates compressed lex/dict modules
4  *
5  * $Id: entriesblk.cpp 3749 2020-07-06 23:51:56Z scribe $
6  *
7  * Copyright 2001-2013 CrossWire Bible Society (http://www.crosswire.org)
8  * CrossWire Bible Society
9  * P. O. Box 2528
10  * Tempe, AZ 85280-2528
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the
14  * Free Software Foundation version 2.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details.
20  *
21  */
22 
23 #include <entriesblk.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
28 
29 const int EntriesBlock::METAHEADERSIZE = 4;
30  // count(4);
31 const int EntriesBlock::METAENTRYSIZE = 8;
32  // offset(4); size(4);
33 
34 EntriesBlock::EntriesBlock(const char *iBlock, unsigned long size) {
35  if (size) {
36  block = (char *)calloc(1, size);
37  memcpy(block, iBlock, size);
38  }
39  else {
40  block = (char *)calloc(1, sizeof(SW_u32));
41  }
42 }
43 
44 
46  block = (char *)calloc(1, sizeof(SW_u32));
47 }
48 
49 
51  free(block);
52 }
53 
54 
55 void EntriesBlock::setCount(int count) {
56  SW_u32 rawCount = archtosword32(count);
57  memcpy(block, &rawCount, sizeof(SW_u32));
58 }
59 
60 
62  SW_u32 count = 0;
63  memcpy(&count, block, sizeof(SW_u32));
64  count = swordtoarch32(count);
65  return count;
66 }
67 
68 
69 void EntriesBlock::getMetaEntry(int index, unsigned long *offset, unsigned long *size) {
70  SW_u32 rawOffset = 0;
71  SW_u32 rawSize = 0;
72  *offset = 0;
73  *size = 0;
74  if (index >= getCount()) // assert index < count
75  return;
76 
77  // first 4 bytes is count, each 6 bytes after is each meta entry
78  memcpy(&rawOffset, block + METAHEADERSIZE + (index * METAENTRYSIZE), sizeof(rawOffset));
79  memcpy(&rawSize, block + METAHEADERSIZE + (index * METAENTRYSIZE) + sizeof(rawOffset), sizeof(rawSize));
80 
81  *offset = (unsigned long)swordtoarch32(rawOffset);
82  *size = (unsigned long)swordtoarch32(rawSize);
83 }
84 
85 
86 void EntriesBlock::setMetaEntry(int index, unsigned long offset, unsigned long size) {
87  SW_u32 rawOffset = (SW_u32)archtosword32(offset);
88  SW_u32 rawSize = (SW_u32)archtosword32(size);
89 
90  if (index >= getCount()) // assert index < count
91  return;
92 
93  // first 4 bytes is count, each 6 bytes after is each meta entry
94  memcpy(block + METAHEADERSIZE + (index * METAENTRYSIZE), &rawOffset, sizeof(rawOffset));
95  memcpy(block + METAHEADERSIZE + (index * METAENTRYSIZE) + sizeof(rawOffset), &rawSize, sizeof(rawSize));
96 }
97 
98 
99 const char *EntriesBlock::getRawData(unsigned long *retSize) {
100  unsigned long max = 4;
101  int loop;
102  unsigned long offset;
103  unsigned long size;
104  for (loop = 0; loop < getCount(); loop++) {
105  getMetaEntry(loop, &offset, &size);
106  max = ((offset + size) > max) ? (offset + size) : max;
107  }
108  *retSize = max;
109  return block;
110 }
111 
112 
113 int EntriesBlock::addEntry(const char *entry) {
114  unsigned long dataSize;
115  getRawData(&dataSize);
116  unsigned long len = strlen(entry);
117  unsigned long offset;
118  unsigned long size;
119  int count = getCount();
120  unsigned long dataStart = METAHEADERSIZE + (count * METAENTRYSIZE);
121  // new meta entry + new data size + 1 because null
122  block = (char *)realloc(block, dataSize + METAENTRYSIZE + len + 1);
123  // shift right to make room for new meta entry
124  memmove(block + dataStart + METAENTRYSIZE, block + dataStart, dataSize - dataStart);
125 
126  for (int loop = 0; loop < count; loop++) {
127  getMetaEntry(loop, &offset, &size);
128  if (offset) { // if not a deleted entry
129  offset += METAENTRYSIZE;
130  setMetaEntry(loop, offset, size);
131  }
132  }
133 
134  offset = dataSize; // original dataSize before realloc
135  size = len + 1;
136  // add our text to the end
137  memcpy(block + offset + METAENTRYSIZE, entry, size);
138  // increment count
139  setCount(count + 1);
140  // add our meta entry
141  setMetaEntry(count, offset + METAENTRYSIZE, size);
142  // return index of our new entry
143  return count;
144 }
145 
146 
147 const char *EntriesBlock::getEntry(int entryIndex) {
148  unsigned long offset;
149  unsigned long size;
150  static const char *empty = "";
151 
152  getMetaEntry(entryIndex, &offset, &size);
153  return (offset) ? block+offset : empty;
154 }
155 
156 
157 unsigned long EntriesBlock::getEntrySize(int entryIndex) {
158  unsigned long offset;
159  unsigned long size;
160 
161  getMetaEntry(entryIndex, &offset, &size);
162  return (offset) ? size : 0;
163 }
164 
165 
166 void EntriesBlock::removeEntry(int entryIndex) {
167  unsigned long offset;
168  unsigned long size, size2;
169  unsigned long dataSize;
170  getRawData(&dataSize);
171  getMetaEntry(entryIndex, &offset, &size);
172  int count = getCount();
173 
174  if (!offset) // already deleted
175  return;
176 
177  // shift left to retrieve space used for old entry
178  memmove(block + offset, block + offset + size, dataSize - (offset + size));
179 
180  // fix offset for all entries after our entry that were shifted left
181  for (int loop = entryIndex + 1; loop < count; loop++) {
182  getMetaEntry(loop, &offset, &size2);
183  if (offset) { // if not a deleted entry
184  offset -= size;
185  setMetaEntry(loop, offset, size2);
186  }
187  }
188 
189  // zero out our meta entry
190  setMetaEntry(entryIndex, 0L, 0);
191 }
192 
193 
#define SWORD_NAMESPACE_START
Definition: defs.h:39
static const int METAHEADERSIZE
Definition: entriesblk.h:33
void setCount(int count)
Definition: entriesblk.cpp:55
#define archtosword32(x)
Definition: sysdata.h:97
int addEntry(const char *entry)
Definition: entriesblk.cpp:113
const char * getEntry(int entryIndex)
Definition: entriesblk.cpp:147
int size2
Definition: regex.c:5079
char * block
Definition: entriesblk.h:37
void removeEntry(int entryIndex)
Definition: entriesblk.cpp:166
free(preg->fastmap)
const char * getRawData(unsigned long *size)
Definition: entriesblk.cpp:99
char * realloc()
void setMetaEntry(int index, unsigned long offset, unsigned long size)
Definition: entriesblk.cpp:86
#define swordtoarch32(x)
Definition: sysdata.h:94
int size
Definition: regex.c:5043
static const int METAENTRYSIZE
Definition: entriesblk.h:34
unsigned int SW_u32
Definition: sysdata.h:41
unsigned long getEntrySize(int entryIndex)
Definition: entriesblk.cpp:157
#define SWORD_NAMESPACE_END
Definition: defs.h:40
void getMetaEntry(int index, unsigned long *offset, unsigned long *size)
Definition: entriesblk.cpp:69
int getCount()
Definition: entriesblk.cpp:61