1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
4
5 #ifndef InputSource_INCLUDED
6 #define InputSource_INCLUDED 1
7 #ifdef __GNUG__
8 #pragma interface
9 #endif
10
11 #include "types.h"
12 #include "Link.h"
13 #include "Ptr.h"
14 #include "Location.h"
15 #include "XcharMap.h"
16 #include <stddef.h>
17
18 #ifdef SP_NAMESPACE
19 namespace SP_NAMESPACE {
20 #endif
21
22 class Messenger;
23 class NamedCharRef;
24 class CharsetInfo;
25
26 class SP_API InputSource : public Link {
27 public:
28 enum { eE = -1 }; // end of entity signal
29
30 virtual ~InputSource();
31 Xchar get(Messenger &);
32 virtual void pushCharRef(Char ch, const NamedCharRef &) = 0;
33 const Location ¤tLocation() const;
34 const Char *currentTokenStart() const;
35 size_t currentTokenLength() const;
36 const Char *currentTokenEnd() const;
37 Index nextIndex() const;
38 // Discard all but the last character of the current token.
39 void discardInitial();
40 void startToken();
41 void startTokenNoMulticode();
42 void endToken(size_t length);
43 Xchar tokenChar(Messenger &);
44 void ungetToken();
45 void setMarkupScanTable(const XcharMap<unsigned char> &);
46 Boolean scanSuppress() const;
47 void extendToBufferEnd();
48 virtual void willNotRewind();
49 virtual Boolean rewind(Messenger &) = 0;
50 Boolean accessError() const;
51 virtual void setDocCharset(const CharsetInfo &docCharset,
52 const CharsetInfo &emCharset);
53 virtual void willNotSetDocCharset();
54 protected:
55 InputSource(InputSourceOrigin *origin, const Char *start, const Char *end);
56 void reset(const Char *start, const Char *end);
57 InputSourceOrigin *inputSourceOrigin();
58 void noteCharRef(Index replacementIndex, const NamedCharRef &);
59 const Char *cur();
60 const Char *start();
61 const Char *end();
62 Index startIndex();
63 void changeBuffer(const Char *newBase, const Char *oldBase);
64 void advanceEnd(const Char *newEnd);
65 void moveLeft();
66 void moveStart(const Char *newStart);
67 Char nextChar();
68 void setAccessError();
69 private:
70 InputSource(const InputSource &); // undefined
71 void operator=(const InputSource &); // undefined
72 virtual Xchar fill(Messenger &) = 0;
73 void advanceStart(const Char *to);
74 void advanceStartMulticode(const Char *to);
75
76 const Char *cur_;
77 const Char *start_;
78 const Char *end_;
79 Location startLocation_;
80 Ptr<InputSourceOrigin> origin_;
81 Boolean accessError_;
82 Boolean scanSuppress_;
83 Boolean scanSuppressSingle_;
84 Index scanSuppressIndex_;
85 Boolean multicode_;
86 XcharMap<unsigned char> markupScanTable_;
87 };
88
89 inline
advanceStart(const Char * to)90 void InputSource::advanceStart(const Char *to)
91 {
92 if (multicode_)
93 advanceStartMulticode(to);
94 else {
95 startLocation_ += to - start_;
96 start_ = to;
97 }
98 }
99
100 inline
get(Messenger & mgr)101 Xchar InputSource::get(Messenger &mgr)
102 {
103 advanceStart(cur_);
104 return cur_ < end_ ? *cur_++ : fill(mgr);
105 }
106
107 inline
startTokenNoMulticode()108 void InputSource::startTokenNoMulticode()
109 {
110 startLocation_ += cur_ - start_;
111 start_ = cur_;
112 }
113
114 inline
startToken()115 void InputSource::startToken()
116 {
117 advanceStart(cur_);
118 }
119
120 inline
endToken(size_t length)121 void InputSource::endToken(size_t length)
122 {
123 cur_ = start_ + length;
124 }
125
126 inline
tokenChar(Messenger & mgr)127 Xchar InputSource::tokenChar(Messenger &mgr)
128 {
129 return cur_ < end_ ? *cur_++ : fill(mgr);
130 }
131
132 inline
extendToBufferEnd()133 void InputSource::extendToBufferEnd()
134 {
135 cur_ = end_;
136 }
137
138 inline
cur()139 const Char *InputSource::cur()
140 {
141 return cur_;
142 }
143
144 inline
start()145 const Char *InputSource::start()
146 {
147 return start_;
148 }
149
150 inline
end()151 const Char *InputSource::end()
152 {
153 return end_;
154 }
155
156 inline
changeBuffer(const Char * newBase,const Char * oldBase)157 void InputSource::changeBuffer(const Char *newBase, const Char *oldBase)
158 {
159 cur_ = newBase + (cur_ - oldBase);
160 start_ = newBase + (start_ - oldBase);
161 end_ = newBase + (end_ - oldBase);
162 }
163
164 inline
moveStart(const Char * newStart)165 void InputSource::moveStart(const Char *newStart)
166 {
167 cur_ = newStart + (cur_ - start_);
168 end_ = newStart + (end_ - start_);
169 start_ = newStart;
170 }
171
172 inline
advanceEnd(const Char * newEnd)173 void InputSource::advanceEnd(const Char *newEnd)
174 {
175 end_ = newEnd;
176 }
177
178 inline
nextChar()179 Char InputSource::nextChar()
180 {
181 return *cur_++;
182 }
183
184 inline
startIndex()185 Index InputSource::startIndex()
186 {
187 return startLocation_.index();
188 }
189
190 inline
moveLeft()191 void InputSource::moveLeft()
192 {
193 start_--;
194 cur_--;
195 }
196
197 inline
noteCharRef(Index replacementIndex,const NamedCharRef & ref)198 void InputSource::noteCharRef(Index replacementIndex, const NamedCharRef &ref)
199 {
200 origin_->noteCharRef(replacementIndex, ref);
201 }
202
203 inline
currentLocation()204 const Location &InputSource::currentLocation() const
205 {
206 return startLocation_;
207 }
208
209 inline
currentTokenStart()210 const Char *InputSource::currentTokenStart() const
211 {
212 return start_;
213 }
214
215 inline
currentTokenLength()216 size_t InputSource::currentTokenLength() const
217 {
218 return cur_ - start_;
219 }
220
221 inline
nextIndex()222 Index InputSource::nextIndex() const
223 {
224 return startLocation_.index() + (cur_ - start_);
225 }
226
227 inline
currentTokenEnd()228 const Char *InputSource::currentTokenEnd() const
229 {
230 return cur_;
231 }
232
233 inline
discardInitial()234 void InputSource::discardInitial()
235 {
236 advanceStart(cur_ - 1);
237 }
238
239 inline
ungetToken()240 void InputSource::ungetToken()
241 {
242 cur_ = start_;
243 }
244
245 inline
setMarkupScanTable(const XcharMap<unsigned char> & table)246 void InputSource::setMarkupScanTable(const XcharMap<unsigned char> &table)
247 {
248 markupScanTable_ = table;
249 multicode_ = 1;
250 }
251
252 inline
scanSuppress()253 Boolean InputSource::scanSuppress() const
254 {
255 return scanSuppress_ && (!scanSuppressSingle_
256 || startLocation_.index() == scanSuppressIndex_);
257 }
258
259 inline
inputSourceOrigin()260 InputSourceOrigin *InputSource::inputSourceOrigin()
261 {
262 return origin_.pointer();
263 }
264
265 inline
setAccessError()266 void InputSource::setAccessError()
267 {
268 accessError_ = 1;
269 }
270
271 inline
accessError()272 Boolean InputSource::accessError() const
273 {
274 return accessError_;
275 }
276
277 #ifdef SP_NAMESPACE
278 }
279 #endif
280
281 #endif /* not InputSource_INCLUDED */
282