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 &currentLocation() 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