~ubuntu-branches/debian/squeeze/sword/squeeze

« back to all changes in this revision

Viewing changes to src/modules/filters/swbasicfilter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Glassey
  • Date: 2004-01-15 15:50:07 UTC
  • Revision ID: james.westby@ubuntu.com-20040115155007-n9mz4x0zxrs1isd3
Tags: upstream-1.5.7
ImportĀ upstreamĀ versionĀ 1.5.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 *  swbasicfilter.h     - definition of class SWBasicFilter.  An SWFilter
 
3
 *                              impl that provides some basic methods that
 
4
 *                              many filters will need and can use as a starting
 
5
 *                              point. 
 
6
 *
 
7
 * $Id: swbasicfilter.cpp,v 1.33 2003/10/24 02:43:46 scribe Exp $
 
8
 *
 
9
 * Copyright 2001 CrossWire Bible Society (http://www.crosswire.org)
 
10
 *      CrossWire Bible Society
 
11
 *      P. O. Box 2528
 
12
 *      Tempe, AZ  85280-2528
 
13
 *
 
14
 * This program is free software; you can redistribute it and/or modify it
 
15
 * under the terms of the GNU General Public License as published by the
 
16
 * Free Software Foundation version 2.
 
17
 *
 
18
 * This program is distributed in the hope that it will be useful, but
 
19
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
21
 * General Public License for more details.
 
22
 *
 
23
 */
 
24
 
 
25
#include <stdlib.h>
 
26
#include <swbasicfilter.h>
 
27
#include <stdio.h>
 
28
#include <stdarg.h>
 
29
 
 
30
SWORD_NAMESPACE_START
 
31
 
 
32
const char SWBasicFilter::INITIALIZE = 1;
 
33
const char SWBasicFilter::PRECHAR    = 2;
 
34
const char SWBasicFilter::POSTCHAR   = 4;
 
35
const char SWBasicFilter::FINALIZE   = 8;
 
36
 
 
37
SWBasicFilter::SWBasicFilter() {
 
38
        processStages = 0;
 
39
        tokenStart    = 0;
 
40
        tokenEnd      = 0;
 
41
        escStart      = 0;
 
42
        escEnd        = 0;
 
43
 
 
44
        setTokenStart("<");
 
45
        setTokenEnd(">");
 
46
        setEscapeStart("&");
 
47
        setEscapeEnd(";");
 
48
 
 
49
        escStringCaseSensitive = false;
 
50
        tokenCaseSensitive     = false;
 
51
        passThruUnknownToken   = false;
 
52
        passThruUnknownEsc     = false;
 
53
}
 
54
 
 
55
 
 
56
void SWBasicFilter::setPassThruUnknownToken(bool val) {
 
57
        passThruUnknownToken = val;
 
58
}
 
59
 
 
60
 
 
61
void SWBasicFilter::setPassThruUnknownEscapeString(bool val) {
 
62
        passThruUnknownEsc = val;
 
63
}
 
64
 
 
65
 
 
66
void SWBasicFilter::setTokenCaseSensitive(bool val) {
 
67
        tokenCaseSensitive = val;
 
68
}
 
69
 
 
70
 
 
71
void SWBasicFilter::setEscapeStringCaseSensitive(bool val) {
 
72
        escStringCaseSensitive = val;
 
73
}
 
74
 
 
75
 
 
76
SWBasicFilter::~SWBasicFilter() {
 
77
        if (tokenStart)
 
78
                delete [] tokenStart;
 
79
 
 
80
        if (tokenEnd)
 
81
                delete [] tokenEnd;
 
82
 
 
83
        if (escStart)
 
84
                delete [] escStart;
 
85
 
 
86
        if (escEnd)
 
87
                delete [] escEnd;
 
88
}
 
89
 
 
90
 
 
91
void SWBasicFilter::addTokenSubstitute(const char *findString, const char *replaceString) {
 
92
        char *buf = 0;
 
93
 
 
94
        if (!tokenCaseSensitive) {
 
95
                stdstr(&buf, findString);
 
96
                toupperstr(buf);
 
97
                tokenSubMap[buf] = replaceString;
 
98
                delete [] buf;
 
99
        }
 
100
        else tokenSubMap[findString] = replaceString;
 
101
}
 
102
 
 
103
 
 
104
void SWBasicFilter::replaceTokenSubstitute(const char *findString, const char *replaceString) {
 
105
        if (tokenSubMap.find(findString) != tokenSubMap.end()) {
 
106
                tokenSubMap.erase( tokenSubMap.find(findString) ); //erase entry
 
107
        }
 
108
        addTokenSubstitute(findString, replaceString);
 
109
}
 
110
 
 
111
 
 
112
void SWBasicFilter::addEscapeStringSubstitute(const char *findString, const char *replaceString) {
 
113
        char *buf = 0;
 
114
 
 
115
        if (!escStringCaseSensitive) {
 
116
                stdstr(&buf, findString);
 
117
                toupperstr(buf);
 
118
                escSubMap.insert(DualStringMap::value_type(buf, replaceString));
 
119
                delete [] buf;
 
120
        }
 
121
        else escSubMap.insert(DualStringMap::value_type(findString, replaceString));
 
122
}
 
123
 
 
124
void SWBasicFilter::replaceEscapeStringSubstitute(const char *findString, const char *replaceString) {
 
125
        if (escSubMap.find(findString) != escSubMap.end()) {
 
126
                escSubMap.erase( escSubMap.find(findString) ); //erase entry
 
127
        }
 
128
        addEscapeStringSubstitute(findString, replaceString);
 
129
}
 
130
 
 
131
 
 
132
bool SWBasicFilter::substituteToken(SWBuf &buf, const char *token) {
 
133
        DualStringMap::iterator it;
 
134
 
 
135
        if (!tokenCaseSensitive) {
 
136
                char *tmp = 0;
 
137
                stdstr(&tmp, token);
 
138
                toupperstr(tmp);
 
139
                it = tokenSubMap.find(tmp);
 
140
                delete [] tmp;
 
141
        } else
 
142
        it = tokenSubMap.find(token);
 
143
 
 
144
        if (it != tokenSubMap.end()) {
 
145
                buf += it->second.c_str();
 
146
                return true;
 
147
        }
 
148
        return false;
 
149
}
 
150
 
 
151
 
 
152
bool SWBasicFilter::substituteEscapeString(SWBuf &buf, const char *escString) {
 
153
        DualStringMap::iterator it;
 
154
 
 
155
        if (!escStringCaseSensitive) {
 
156
                char *tmp = 0;
 
157
                stdstr(&tmp, escString);
 
158
                toupperstr(tmp);
 
159
                it = escSubMap.find(tmp);
 
160
                delete [] tmp;
 
161
        } else 
 
162
        it = escSubMap.find(escString);
 
163
 
 
164
        if (it != escSubMap.end()) {
 
165
                buf += it->second.c_str();
 
166
                return true;
 
167
        }
 
168
        return false;
 
169
}
 
170
 
 
171
 
 
172
bool SWBasicFilter::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
 
173
        return substituteToken(buf, token);
 
174
}
 
175
 
 
176
 
 
177
bool SWBasicFilter::handleEscapeString(SWBuf &buf, const char *escString, BasicFilterUserData *userData) {
 
178
        return substituteEscapeString(buf, escString);
 
179
}
 
180
 
 
181
 
 
182
void SWBasicFilter::setEscapeStart(const char *escStart) {
 
183
        stdstr(&(this->escStart), escStart);
 
184
        escStartLen = strlen(escStart);
 
185
}
 
186
 
 
187
 
 
188
void SWBasicFilter::setEscapeEnd(const char *escEnd) {
 
189
        stdstr(&(this->escEnd), escEnd);
 
190
        escEndLen   = strlen(escEnd);
 
191
}
 
192
 
 
193
 
 
194
void SWBasicFilter::setTokenStart(const char *tokenStart) {
 
195
        stdstr(&(this->tokenStart), tokenStart);
 
196
        tokenStartLen = strlen(tokenStart);
 
197
}
 
198
 
 
199
 
 
200
void SWBasicFilter::setTokenEnd(const char *tokenEnd) {
 
201
        stdstr(&(this->tokenEnd), tokenEnd);
 
202
        tokenEndLen   = strlen(tokenEnd);
 
203
}
 
204
 
 
205
 
 
206
char SWBasicFilter::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
 
207
        char *from;
 
208
        char token[4096];
 
209
        int tokpos = 0;
 
210
        bool intoken = false;
 
211
        bool inEsc = false;
 
212
        char escStartPos = 0, escEndPos = 0;
 
213
        char tokenStartPos = 0, tokenEndPos = 0;
 
214
        SWBuf lastTextNode;
 
215
        BasicFilterUserData *userData = createUserData(module, key);
 
216
 
 
217
        SWBuf orig = text;
 
218
        from = orig.getRawData();
 
219
        text = "";
 
220
 
 
221
        if (processStages & INITIALIZE) {
 
222
                if (processStage(INITIALIZE, text, from, userData)) {   // processStage handled it all
 
223
                        delete userData;
 
224
                        return 0;
 
225
                }
 
226
        }
 
227
 
 
228
        for (;*from; from++) {
 
229
 
 
230
                if (processStages & PRECHAR) {
 
231
                        if (processStage(PRECHAR, text, from, userData))        // processStage handled this char
 
232
                                continue;
 
233
                }
 
234
 
 
235
                if (*from == tokenStart[tokenStartPos]) {
 
236
                        if (tokenStartPos == (tokenStartLen - 1)) {
 
237
                                intoken = true;
 
238
                                tokpos = 0;
 
239
                                token[0] = 0;
 
240
                                token[1] = 0;
 
241
                                token[2] = 0;
 
242
                                inEsc = false;
 
243
                        }
 
244
                        else tokenStartPos++;
 
245
                        continue;
 
246
                }
 
247
 
 
248
                if (*from == escStart[escStartPos]) {
 
249
                        if (escStartPos == (escStartLen - 1)) {
 
250
                                intoken = true;
 
251
                                tokpos = 0;
 
252
                                token[0] = 0;
 
253
                                token[1] = 0;
 
254
                                token[2] = 0;
 
255
                                inEsc = true;
 
256
                        }
 
257
                        else escStartPos++;
 
258
                        continue;
 
259
                }
 
260
 
 
261
                if (inEsc) {
 
262
                        if (*from == escEnd[escEndPos]) {
 
263
                                if (escEndPos == (escEndLen - 1)) {
 
264
                                        intoken = false;
 
265
                                        userData->lastTextNode = lastTextNode;
 
266
                                        if ((!handleEscapeString(text, token, userData)) && (passThruUnknownEsc)) {
 
267
                                                text += escStart;
 
268
                                                text += token;
 
269
                                                text += escEnd;
 
270
                                        }
 
271
                                        escEndPos = escStartPos = tokenEndPos = tokenStartPos = 0;
 
272
                                        lastTextNode = "";
 
273
                                        continue;
 
274
                                }
 
275
                        }
 
276
                }
 
277
 
 
278
                if (!inEsc) {
 
279
                        if (*from == tokenEnd[tokenEndPos]) {
 
280
                                if (tokenEndPos == (tokenEndLen - 1)) {
 
281
                                        intoken = false;
 
282
                                        userData->lastTextNode = lastTextNode;
 
283
                                        if ((!handleToken(text, token, userData)) && (passThruUnknownToken)) {
 
284
                                                text += tokenStart;
 
285
                                                text += token;
 
286
                                                text += tokenEnd;
 
287
                                        }
 
288
                                        escEndPos = escStartPos = tokenEndPos = tokenStartPos = 0;
 
289
                                        lastTextNode = "";
 
290
                                        continue;
 
291
                                }
 
292
                        }
 
293
                }
 
294
 
 
295
                if (intoken) {
 
296
                        if (tokpos < 4090)
 
297
                                token[tokpos++] = *from;
 
298
                                token[tokpos+2] = 0;
 
299
                }
 
300
                else {
 
301
                        if ((!userData->supressAdjacentWhitespace) || (*from != ' ')) {
 
302
                                if (!userData->suspendTextPassThru)
 
303
                                        text += *from;
 
304
                                lastTextNode += *from;
 
305
                        }
 
306
                        userData->supressAdjacentWhitespace = false;
 
307
                }
 
308
 
 
309
                if (processStages & POSTCHAR)
 
310
                        processStage(POSTCHAR, text, from, userData);
 
311
 
 
312
        }
 
313
 
 
314
        if (processStages & FINALIZE)
 
315
                processStage(FINALIZE, text, from, userData);
 
316
 
 
317
        delete userData;
 
318
        return 0;
 
319
}
 
320
 
 
321
SWORD_NAMESPACE_END