xref: /onnv-gate/usr/src/cmd/man/src/util/nsgmls.src/lib/ExternalId.cxx (revision 0:68f95e015346)
1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident	"%Z%%M%	%I%	%E% SMI"
4 
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8 #include "splib.h"
9 #include "ExternalId.h"
10 #include "CharsetInfo.h"
11 #include "macros.h"
12 #include "ParserMessages.h"
13 
14 #ifdef SP_NAMESPACE
15 namespace SP_NAMESPACE {
16 #endif
17 
ExternalId()18 ExternalId::ExternalId()
19 : haveSystem_(0), havePublic_(0)
20 {
21 }
22 
setSystem(Text & text)23 void ExternalId::setSystem(Text &text)
24 {
25   text.swap(system_);
26   haveSystem_ = 1;
27 }
28 
setPublic(Text & text,const CharsetInfo & charset,Char space,const MessageType1 * & error)29 Boolean ExternalId::setPublic(Text &text, const CharsetInfo &charset,
30 			      Char space, const MessageType1 *&error)
31 {
32   havePublic_ = 1;
33   return public_.init(text, charset, space, error);
34 }
35 
setLocation(const Location & loc)36 void ExternalId::setLocation(const Location &loc)
37 {
38   loc_ = loc;
39 }
40 
PublicId()41 PublicId::PublicId()
42 : formal_(0)
43 {
44 }
45 
init(Text & text,const CharsetInfo & charset,Char space,const MessageType1 * & error)46 Boolean PublicId::init(Text &text, const CharsetInfo &charset,
47 		       Char space, const MessageType1 *&error)
48 {
49   text.swap(text_);
50   const StringC &str = text_.string();
51   formal_ = 0;
52   const Char *next = str.data();
53   const Char *lim = str.data() + str.size();
54   Char solidus = charset.execToDesc('/');
55   Char minus = charset.execToDesc('-');
56   Char plus = charset.execToDesc('+');
57   const Char *fieldStart;
58   size_t fieldLength;
59   if (!nextField(solidus, next, lim, fieldStart, fieldLength)) {
60     error = &ParserMessages::fpiMissingField;
61     return 0;
62   }
63   if (fieldLength == 1 && (*fieldStart == minus || *fieldStart == plus)) {
64     ownerType_ = (*fieldStart == plus ? registered : unregistered);
65     if (!nextField(solidus, next, lim, fieldStart, fieldLength)) {
66       error = &ParserMessages::fpiMissingField;
67       return 0;
68     }
69   }
70   else
71     ownerType_ = ISO;
72   owner_.assign(fieldStart, fieldLength);
73   if (!nextField(solidus, next, lim, fieldStart, fieldLength)) {
74     error = &ParserMessages::fpiMissingField;
75     return 0;
76   }
77   size_t i;
78   for (i = 0; i < fieldLength; i++)
79     if (fieldStart[i] == space)
80       break;
81   if (i >= fieldLength) {
82     error = &ParserMessages::fpiMissingTextClassSpace;
83     return 0;
84   }
85   StringC textClassString(fieldStart, i);
86   if (!lookupTextClass(textClassString, charset, textClass_)) {
87     error = &ParserMessages::fpiInvalidTextClass;
88     return 0;
89   }
90   i++;				// skip the space
91   fieldStart += i;
92   fieldLength -= i;
93   if (fieldLength  == 1 && *fieldStart == minus) {
94     unavailable_ = 1;
95     if (!nextField(solidus, next, lim, fieldStart, fieldLength)) {
96       error = &ParserMessages::fpiMissingField;
97       return 0;
98     }
99   }
100   else
101     unavailable_ = 0;
102   description_.assign(fieldStart, fieldLength);
103   if (!nextField(solidus, next, lim, fieldStart, fieldLength)) {
104     error = &ParserMessages::fpiMissingField;
105     return 0;
106   }
107   if (textClass_ != CHARSET) {
108     for (i = 0; i < fieldLength; i++) {
109       UnivChar c;
110       if (!charset.descToUniv(fieldStart[i], c)
111 	  || c < UnivCharsetDesc::A || c >= UnivCharsetDesc::A + 26) {
112 	error = &ParserMessages::fpiInvalidLanguage;
113 	return 0;
114       }
115     }
116     // The public text language must be a name.
117     // Names cannot be empty.
118     if (fieldLength == 0) {
119       error = &ParserMessages::fpiInvalidLanguage;
120       return 0;
121     }
122   }
123   languageOrDesignatingSequence_.assign(fieldStart, fieldLength);
124   if (nextField(solidus, next, lim, fieldStart, fieldLength)) {
125     switch (textClass_) {
126     case CAPACITY:
127     case CHARSET:
128     case NOTATION:
129     case SYNTAX:
130       error = &ParserMessages::fpiIllegalDisplayVersion;
131       return 0;
132     default:
133       break;
134     }
135     haveDisplayVersion_ = 1;
136     displayVersion_.assign(fieldStart, fieldLength);
137   }
138   else
139     haveDisplayVersion_ = 0;
140   if (next != 0) {
141     error = &ParserMessages::fpiExtraField;
142     return 0;
143   }
144   formal_ = 1;
145   return 1;
146 }
147 
nextField(Char solidus,const Char * & next,const Char * lim,const Char * & fieldStart,size_t & fieldLength)148 Boolean PublicId::nextField(Char solidus,
149 				  const Char *&next,
150 				  const Char *lim,
151 				  const Char *&fieldStart,
152 				  size_t &fieldLength)
153 
154 {
155   if (next == 0)
156     return 0;
157   fieldStart = next;
158   for (; next < lim; next++) {
159     if (next[0] == solidus && next + 1 < lim && next[1] == solidus) {
160       fieldLength = next - fieldStart;
161       next += 2;
162       return 1;
163     }
164   }
165   fieldLength = lim - fieldStart;
166   next = 0;
167   return 1;
168 }
169 
170 const char *const PublicId::textClasses[] = {
171   "CAPACITY",
172   "CHARSET",
173   "DOCUMENT",
174   "DTD",
175   "ELEMENTS",
176   "ENTITIES",
177   "LPD",
178   "NONSGML",
179   "NOTATION",
180   "SD",
181   "SHORTREF",
182   "SUBDOC",
183   "SYNTAX",
184   "TEXT",
185 };
186 
lookupTextClass(const StringC & str,const CharsetInfo & charset,TextClass & textClass)187 Boolean PublicId::lookupTextClass(const StringC &str,
188 					const CharsetInfo &charset,
189 					TextClass &textClass)
190 {
191   for (size_t i = 0; i < SIZEOF(textClasses); i++)
192     if (str == charset.execToDesc(textClasses[i])) {
193       textClass = TextClass(i);
194       return 1;
195     }
196   return 0;
197 }
198 
getOwnerType(OwnerType & result) const199 Boolean PublicId::getOwnerType(OwnerType &result) const
200 {
201   if (!formal_)
202     return 0;
203   result = ownerType_;
204   return 1;
205 }
206 
getOwner(StringC & result) const207 Boolean PublicId::getOwner(StringC &result) const
208 {
209   if (!formal_)
210     return 0;
211   result = owner_;
212   return 1;
213 }
214 
getTextClass(TextClass & result) const215 Boolean PublicId::getTextClass(TextClass &result) const
216 {
217   if (!formal_)
218     return 0;
219   result = textClass_;
220   return 1;
221 }
222 
getUnavailable(Boolean & result) const223 Boolean PublicId::getUnavailable(Boolean &result) const
224 {
225   if (!formal_)
226     return 0;
227   result = unavailable_;
228   return 1;
229 }
230 
getDescription(StringC & result) const231 Boolean PublicId::getDescription(StringC &result) const
232 {
233   if (!formal_)
234     return 0;
235   result = description_;
236   return 1;
237 }
238 
getLanguage(StringC & result) const239 Boolean PublicId::getLanguage(StringC &result) const
240 {
241   if (!formal_ || textClass_ == CHARSET)
242     return 0;
243   result = languageOrDesignatingSequence_;
244   return 1;
245 }
246 
getDesignatingSequence(StringC & result) const247 Boolean PublicId::getDesignatingSequence(StringC &result) const
248 {
249   if (!formal_ || textClass_ != CHARSET)
250     return 0;
251   result = languageOrDesignatingSequence_;
252   return 1;
253 }
254 
getDisplayVersion(StringC & result) const255 Boolean PublicId::getDisplayVersion(StringC &result) const
256 {
257   if (!formal_)
258     return 0;
259   if (haveDisplayVersion_)
260     result = displayVersion_;
261   return 1;
262 }
263 
264 #ifdef SP_NAMESPACE
265 }
266 #endif
267