source: trunk/gsdl/src/mgpp/text/FText.cpp@ 860

Last change on this file since 860 was 860, checked in by rjmcnab, 24 years ago

Fixed a couple of bugs and made building silent if needed.

  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/**************************************************************************
2 *
3 * FText.cpp -- File structures for text compression
4 * Copyright (C) 1999 Rodger McNab
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: FText.cpp 860 2000-01-18 03:53:24Z rjmcnab $
21 *
22 **************************************************************************/
23
24#include "FText.h"
25#include "netorder.h" /* [RPAP - Jan 97: Endian Ordering] */
26
27
28BitAddr::BitAddr () {
29 Clear ();
30}
31
32void BitAddr::Clear () {
33 byte = 0;
34 bit = 0;
35}
36
37bool BitAddr::Read (FILE *f) {
38 return (ReadUL (f, byte) && ReadUC (f, bit));
39}
40
41bool BitAddr::Write (FILE *f) const {
42 return (WriteUL (f, byte) && WriteUC (f, bit));
43}
44
45#define BITADDRLEN (sizeof(unsigned long) + sizeof(unsigned char))
46
47
48TextLevelInfo::TextLevelInfo () {
49 Clear();
50}
51
52void TextLevelInfo::Clear () {
53 levelTag.erase (levelTag.begin(), levelTag.end());
54 textIdxPtr = 0;
55 numEntries = 0;
56}
57
58bool TextLevelInfo::Read (FILE *f) {
59 return (ReadUCArray (f, levelTag) &&
60 ReadUL (f, textIdxPtr) &&
61 ReadUL (f, numEntries));
62}
63
64bool TextLevelInfo::Write (FILE *f) const {
65 return (WriteUCArray (f, levelTag) &&
66 WriteUL (f, textIdxPtr) &&
67 WriteUL (f, numEntries));
68}
69
70ostream &operator<<(ostream &s, const TextLevelInfo &l) {
71 s << " Tag: \"" << l.levelTag << "\"\n"
72 << " textIdxPtr: " << l.textIdxPtr << "\n"
73 << " numEntries: " << l.numEntries << "\n\n";
74
75 return s;
76}
77
78
79FTextLevel::FTextLevel () {
80 Clear();
81}
82
83void FTextLevel::Clear () {
84 levelInfo.erase (levelInfo.begin(), levelInfo.end());
85}
86
87bool FTextLevel::Read (FILE *f) {
88 // read in the array size
89 unsigned long arrSize = 0;
90 if (!ReadVarLenUL (f, arrSize)) return false;
91
92 TextLevelInfo thisLevel;
93 while (arrSize > 0) {
94 // read and insert the next level information
95 if (!thisLevel.Read (f)) return false;
96 levelInfo[thisLevel.levelTag] = thisLevel;
97
98 arrSize--;
99 }
100
101 return true;
102}
103
104bool FTextLevel::Write (FILE *f) const {
105 // write out the array size
106 if (!WriteVarLenUL (f, levelInfo.size())) return false;
107
108 // write out each level info
109 TextLevelInfoMap::const_iterator here = levelInfo.begin();
110 TextLevelInfoMap::const_iterator end = levelInfo.end();
111 while (here != end) {
112 if (!(*here).second.Write (f)) return false;
113
114 here++;
115 }
116
117 return true;
118}
119
120ostream &operator<<(ostream &s, const FTextLevel &l) {
121 TextLevelInfoMap::const_iterator here = l.levelInfo.begin ();
122 TextLevelInfoMap::const_iterator end = l.levelInfo.end ();
123 while (here != end) {
124 s << (*here).second;
125 here++;
126 }
127
128 return s;
129}
130
131
132TextIdx::TextIdx () {
133 Clear ();
134}
135
136void TextIdx::Clear () {
137 start.Clear();
138 end.Clear();
139 which = 0;
140}
141
142#define TEXTIDXLEN (BITADDRLEN*2 + sizeof(char))
143
144bool TextIdx::Read (FILE *f, const TextLevelInfo &levelInfo,
145 unsigned long docNum) {
146 if (!SeekTextIdx (f, levelInfo, docNum)) return false;
147 return Read (f);
148}
149
150bool TextIdx::Read (FILE *f) {
151 return (start.Read (f) && end.Read (f) && ReadUC (f, which));
152}
153
154bool TextIdx::Write (FILE *f) const {
155 return (start.Write (f) && end.Write (f) && WriteUC (f, which));
156}
157
158ostream &operator<<(ostream &s, const TextIdx &t) {
159 s << "start byte: " << t.start.byte << "\n";
160 s << "start bit: " << (int)t.start.bit << "\n";
161 s << "end byte: " << t.end.byte << "\n";
162 s << "end bit: " << (int)t.end.bit << "\n";
163 s << "which: " << (int)t.which << "\n\n";
164
165 return s;
166}
167
168
169bool SeekTextIdx (FILE *f, const TextLevelInfo &levelInfo,
170 unsigned long docNum) {
171 if (docNum == 0 || docNum > levelInfo.numEntries) return false;
172
173 unsigned long seekPos = levelInfo.textIdxPtr + (docNum-1) * TEXTIDXLEN;
174 if (fseek (f, seekPos, SEEK_SET) != 0) return false;
175
176 return true;
177}
178
179
180bool ReadTextIdxArray (FILE *f, TextIdxArray &a, unsigned long arrSize) {
181 // clear the array
182 a.erase (a.begin(), a.end());
183
184 // read in each element
185 TextIdx idx;
186 while (arrSize > 0) {
187 if (!idx.Read(f)) return false;
188 a.push_back (idx);
189 arrSize --;
190 }
191
192 return true;
193}
194
195bool WriteTextIdxArray (FILE *f, const TextIdxArray &a) {
196 TextIdxArray::const_iterator here = a.begin();
197 TextIdxArray::const_iterator end = a.end();
198 while (here != end) {
199 if (!(*here).Write(f)) return false;
200 here++;
201 }
202
203 return true;
204}
205
206
207CompressTextInfo::CompressTextInfo () {
208 Clear();
209}
210
211void CompressTextInfo::Clear () {
212 ResetStart();
213 docPtrs.erase (docPtrs.begin(), docPtrs.end());
214}
215
216void CompressTextInfo::ResetStart () {
217 inDoc = false;
218 start.Clear();
219 which = 0;
220}
221
222void CompressTextInfo::SetStart (unsigned long startPos,
223 unsigned char startBit,
224 unsigned char startWhich) {
225 // place an imaginary end tag if needed
226 // note: the document tag always needs a closing tag
227 if (inDoc) SetEnd (startPos, startBit);
228
229 // remember start of level
230 inDoc = true;
231 start.byte = startPos;
232 start.bit = startBit;
233 which = startWhich;
234}
235
236void CompressTextInfo::SetEnd (unsigned long endPos,
237 unsigned char endBit) {
238 if (inDoc) {
239 // add completed entry to list of ptrs
240 TextIdx textIdx;
241 textIdx.start = start;
242 textIdx.end.byte = endPos;
243 textIdx.end.bit = endBit;
244 textIdx.which = which;
245 docPtrs.push_back (textIdx);
246
247 // reset this entry
248 ResetStart();
249 }
250}
251
Note: See TracBrowser for help on using the repository browser.