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 Text_INCLUDED
6 #define Text_INCLUDED 1
7 #ifdef __GNUG__
8 #pragma interface
9 #endif
10
11 #include "types.h"
12 #include "StringC.h"
13 #include "Vector.h"
14 #include "Location.h"
15 #include "SubstTable.h"
16 #include <stddef.h>
17
18 #ifdef SP_NAMESPACE
19 namespace SP_NAMESPACE {
20 #endif
21
22 class InternalEntity;
23
24 struct SP_API TextItem {
25 TextItem();
26 enum Type {
27 data,
28 cdata,
29 sdata,
30 nonSgml,
31 entityStart,
32 entityEnd,
33 startDelim,
34 endDelim,
35 endDelimA,
36 ignore
37 };
38 Type type;
39 // char that was ignored
40 Char c;
41 // location of this item
42 // data - location of first char
43 // (c/sdata)entityStart - location of first char of entity
44 // (c/sdata)entityEnd - location of entity end in entity
45 // ignore - location of ignored character
46 // startDelim - location of first char of delimiter
47 // endDelim(A) - location of first char of delimiter
48 Location loc;
49 // index of character in chars_ to which this applies
50 size_t index;
51 };
52
53 // This is used to represent literals and attribute values.
54
55 class SP_API Text {
56 public:
57 Text();
58 void clear();
59 void swap(Text &to);
60 void addChar(Char c, const Location &);
61 void addChars(const StringC &, const Location &);
62 void addChars(const Char *, size_t, const Location &);
63 void insertChars(const StringC &, const Location &);
64 void ignoreChar(Char, const Location &);
65 void ignoreLastChar();
66 void addNonSgmlChar(Char c, const Location &);
67 void addEntityStart(const Location &);
68 void addEntityEnd(const Location &);
69 void addCdata(const InternalEntity *, const ConstPtr<Origin> &);
70 void addSdata(const InternalEntity *, const ConstPtr<Origin> &);
71 void addStartDelim(const Location &loc);
72 void addEndDelim(const Location &loc, Boolean lita);
73 void subst(const SubstTable<Char> &, Char space);
74 void addCharsTokenize(const Char *, size_t, const Location &loc, Char space);
75 void addCharsTokenize(const StringC &, const Location &loc, Char space);
76 void tokenize(Char space, Text &text) const;
77 Location charLocation(size_t i) const;
78 Boolean charLocation(size_t, const Origin *&, Index &) const;
79 Boolean charLocation(size_t i, const ConstPtr<Origin> *&, Index &) const;
80 size_t size() const;
81 Char lastChar() const;
82 const StringC &string() const;
83 size_t normalizedLength(size_t normsep) const;
84 Boolean fixedEqual(const Text &) const;
85 // Location of first char of start delimiter.
86 Boolean startDelimLocation(Location &) const;
87 // Location of first char of end delimiter
88 Boolean endDelimLocation(Location &) const;
89 // Is delimiter a lit or lita?
90 Boolean delimType(Boolean &lita) const;
91 private:
92 void addSimple(TextItem::Type, const Location &);
93 StringC chars_;
94 Vector<TextItem> items_;
95 friend class TextIter;
96 };
97
98 class SP_API TextIter {
99 public:
100 TextIter(const Text &);
101 void rewind();
102 Boolean next(TextItem::Type &, const Char *&, size_t &,
103 const Location *&);
104 // Alternative interface to next()
105 Boolean valid() const;
106 void advance();
107 TextItem::Type type() const;
108 const Location &location() const;
109 const Char *chars(size_t &length) const;
110 private:
111 const TextItem *ptr_;
112 const Text *text_;
113 };
114
115 inline
size()116 size_t Text::size() const
117 {
118 return chars_.size();
119 }
120
121 inline
lastChar()122 Char Text::lastChar() const
123 {
124 return chars_[chars_.size() - 1];
125 }
126
127 inline
string()128 const StringC &Text::string() const
129 {
130 return chars_;
131 }
132
133 inline
addEntityStart(const Location & loc)134 void Text::addEntityStart(const Location &loc)
135 {
136 addSimple(TextItem::entityStart, loc);
137 }
138
139 inline
addEntityEnd(const Location & loc)140 void Text::addEntityEnd(const Location &loc)
141 {
142 addSimple(TextItem::entityEnd, loc);
143 }
144
145 inline
addChars(const StringC & s,const Location & loc)146 void Text::addChars(const StringC &s, const Location &loc)
147 {
148 addChars(s.data(), s.size(), loc);
149 }
150
151 inline
addStartDelim(const Location & loc)152 void Text::addStartDelim(const Location &loc)
153 {
154 addSimple(TextItem::startDelim, loc);
155 }
156
157 inline
addEndDelim(const Location & loc,Boolean lita)158 void Text::addEndDelim(const Location &loc, Boolean lita)
159 {
160 addSimple(lita ? TextItem::endDelimA : TextItem::endDelim,
161 loc);
162 }
163
164 inline
addCharsTokenize(const StringC & str,const Location & loc,Char space)165 void Text::addCharsTokenize(const StringC &str, const Location &loc,
166 Char space)
167 {
168 addCharsTokenize(str.data(), str.size(), loc, space);
169 }
170
171 inline
charLocation(size_t i)172 Location Text::charLocation(size_t i) const
173 {
174 const ConstPtr<Origin> *originP;
175 Index index;
176 if (charLocation(i, originP, index))
177 return Location(*originP, index);
178 else
179 return Location();
180 }
181
182 inline
charLocation(size_t i,const Origin * & origin,Index & index)183 Boolean Text::charLocation(size_t i, const Origin *&origin, Index &index) const
184 {
185 const ConstPtr<Origin> *originP;
186 if (charLocation(i, originP, index)) {
187 origin = originP->pointer();
188 return 1;
189 }
190 else
191 return 0;
192 }
193
194 inline
rewind()195 void TextIter::rewind()
196 {
197 ptr_ = text_->items_.begin();
198 }
199
200 inline
advance()201 void TextIter::advance()
202 {
203 ptr_++;
204 }
205
206 inline
valid()207 Boolean TextIter::valid() const
208 {
209 return ptr_ != (text_->items_.begin() + text_->items_.size());
210 }
211
212 inline
location()213 const Location &TextIter::location() const
214 {
215 return ptr_->loc;
216 }
217
218 inline
type()219 TextItem::Type TextIter::type() const
220 {
221 return ptr_->type;
222 }
223
224 #ifdef SP_NAMESPACE
225 }
226 #endif
227
228 #endif /* not Text_INCLUDED */
229