Link with C++ linker
[oweals/cde.git] / cde / programs / nsgmls / CharsetDecl.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: CharsetDecl.C /main/1 1996/07/29 16:47:07 cde-hp $ */
24 // Copyright (c) 1994 James Clark
25 // See the file COPYING for copying permission.
26
27 #ifdef __GNUG__
28 #pragma implementation
29 #endif
30 #include "splib.h"
31 #include "CharsetDecl.h"
32 #include "macros.h"
33 #include "ISet.h"
34 #include "constant.h"
35
36 #ifdef SP_NAMESPACE
37 namespace SP_NAMESPACE {
38 #endif
39
40 CharsetDeclRange::CharsetDeclRange()
41 {
42 }
43
44 CharsetDeclRange::CharsetDeclRange(WideChar descMin, Number count,
45                                    WideChar baseMin)
46 : descMin_(descMin),
47   count_(count),
48   type_(number),
49   baseMin_(baseMin)
50 {
51 }
52
53 CharsetDeclRange::CharsetDeclRange(WideChar descMin, Number count)
54 : descMin_(descMin),
55   count_(count),
56   type_(unused)
57      
58 {
59 }
60
61 CharsetDeclRange::CharsetDeclRange(WideChar descMin, Number count,
62                                    const StringC &str)
63 : descMin_(descMin),
64   count_(count),
65   type_(string),
66   str_(str)
67 {
68 }
69
70 void CharsetDeclRange::rangeDeclared(WideChar min, Number count,
71                                      ISet<WideChar> &declared) const
72 {
73   if (count > 0 && min + count > descMin_ && min < descMin_ + count_) {
74     WideChar commMin = (descMin_ > min) ? descMin_ : min;
75     WideChar commMax = min + ((min + count < descMin_ + count_
76                                ? count
77                                : descMin_ + count_ - min) - 1);
78     ASSERT(commMin <= commMax);
79     declared.addRange(commMin, commMax);
80   }
81 }
82
83 void CharsetDeclRange::usedSet(ISet<Char> &set) const
84 {
85   if (type_ != unused && count_ > 0 && descMin_ <= charMax) {
86     Char max;
87     if (charMax - descMin_ < count_ - 1)
88       max = charMax;
89     else
90       max = Char(descMin_ + (count_ - 1));
91     set.addRange(Char(descMin_), max);
92   }
93 }
94
95 void CharsetDeclRange::stringToChar(const StringC &str, ISet<WideChar> &to)
96      const
97 {
98   if (type_ == string && str_ == str && count_ > 0)
99     to.addRange(descMin_, descMin_ + (count_ - 1));
100 }
101
102 void CharsetDeclRange::numberToChar(Number n, ISet<WideChar> &to,
103                                     Number &count)
104      const
105 {
106   if (type_ == number && n >= baseMin_ && n - baseMin_ < count_) {
107     Number thisCount = count_ - (n - baseMin_);
108     if (to.isEmpty() || thisCount < count)
109       count = thisCount;
110     to.add(descMin_ + (n - baseMin_));
111   }
112 }
113
114 Boolean CharsetDeclRange::getCharInfo(WideChar fromChar,
115                                       CharsetDeclRange::Type &type,
116                                       Number &n,
117                                       StringC &str,
118                                       Number &count) const
119 {
120   if (fromChar >= descMin_ && fromChar - descMin_ < count_) {
121     type = type_;
122     if (type == number)
123       n = baseMin_ + (fromChar - descMin_);
124     else if (type == string)
125       str = str_;
126     count = count_ - (fromChar - descMin_);
127     return 1;
128   }
129   else
130     return 0;
131 }
132
133 CharsetDeclSection::CharsetDeclSection()
134 {
135 }
136
137 void CharsetDeclSection::setPublicId(const PublicId &id)
138 {
139   baseset_ = id;
140 }
141
142 void CharsetDeclSection::addRange(const CharsetDeclRange &range)
143 {
144   ranges_.push_back(range);
145 }
146
147 void CharsetDeclSection::rangeDeclared(WideChar min, Number count,
148                                        ISet<WideChar> &declared) const
149 {
150   for (size_t i = 0; i < ranges_.size(); i++)
151     ranges_[i].rangeDeclared(min, count, declared);
152 }
153
154 void CharsetDeclSection::usedSet(ISet<Char> &set) const
155 {
156   for (size_t i = 0; i < ranges_.size(); i++)
157     ranges_[i].usedSet(set);
158 }
159
160 void CharsetDeclSection::stringToChar(const StringC &str, ISet<WideChar> &to)
161      const
162 {
163   for (size_t i = 0; i < ranges_.size(); i++)
164     ranges_[i].stringToChar(str, to);
165 }
166
167 void CharsetDeclSection::numberToChar(const PublicId *id, Number n,
168                                       ISet<WideChar> &to, Number &count) const
169 {
170   PublicId::OwnerType ownerType;
171   StringC seq1, seq2;
172   if (id->string() == baseset_.string()
173       // Assume that 2 ISO character sets are the same if
174       // their designating sequences are the same.
175       || (id->getOwnerType(ownerType)
176           && ownerType == PublicId::ISO
177           && baseset_.getOwnerType(ownerType)
178           && ownerType == PublicId::ISO
179           && id->getDesignatingSequence(seq1)
180           && baseset_.getDesignatingSequence(seq2)
181           && seq1 == seq2)) {
182     for (size_t i = 0; i < ranges_.size(); i++)
183       ranges_[i].numberToChar(n, to, count);
184   }
185 }
186
187 Boolean CharsetDeclSection::getCharInfo(WideChar fromChar,
188                                         const PublicId *&id,
189                                         CharsetDeclRange::Type &type,
190                                         Number &n,
191                                         StringC &str,
192                                         Number &count) const
193 {
194   for (size_t i = 0; i < ranges_.size(); i++)
195     if (ranges_[i].getCharInfo(fromChar, type, n, str, count)) {
196       id = &baseset_;
197       return 1;
198     }
199   return 0;
200 }
201
202 CharsetDecl::CharsetDecl()
203 {
204 }
205
206 void CharsetDecl::addSection(const PublicId &id)
207 {
208   sections_.resize(sections_.size() + 1);
209   sections_.back().setPublicId(id);
210 }
211
212 void CharsetDecl::swap(CharsetDecl &to)
213 {
214   sections_.swap(to.sections_);
215   declaredSet_.swap(to.declaredSet_);
216 }
217
218 void CharsetDecl::clear()
219 {
220   sections_.clear();
221 }
222
223 void CharsetDecl::addRange(WideChar min, Number count, WideChar baseMin)
224 {
225   if (count > 0)
226     declaredSet_.addRange(min, min + (count - 1));
227   CharsetDeclRange range(min, count, baseMin);
228   sections_.back().addRange(range);
229 }
230
231 void CharsetDecl::addRange(WideChar min, Number count)
232 {
233   if (count > 0)
234     declaredSet_.addRange(min, min + (count - 1));
235   CharsetDeclRange range(min, count);
236   sections_.back().addRange(range);
237 }
238
239 void CharsetDecl::addRange(WideChar min, Number count, const StringC &str)
240 {
241   if (count > 0)
242     declaredSet_.addRange(min, min + (count - 1));
243   CharsetDeclRange range(min, count, str);
244   sections_.back().addRange(range);
245 }
246
247 void CharsetDecl::rangeDeclared(WideChar min, Number count,
248                                 ISet<WideChar> &declared) const
249 {
250   for (size_t i = 0; i < sections_.size(); i++)
251     sections_[i].rangeDeclared(min, count, declared);
252 }
253
254 void CharsetDecl::usedSet(ISet<Char> &set) const
255 {
256   for (size_t i = 0; i < sections_.size(); i++)
257     sections_[i].usedSet(set);
258 }
259
260 Boolean CharsetDecl::getCharInfo(WideChar fromChar,
261                                  const PublicId *&id,
262                                  CharsetDeclRange::Type &type,
263                                  Number &n,
264                                  StringC &str,
265                                  Number &count) const
266 {
267   for (size_t i = 0; i < sections_.size(); i++)
268     if (sections_[i].getCharInfo(fromChar, id, type, n, str, count))
269       return 1;
270   return 0;
271 }
272
273 void CharsetDecl::stringToChar(const StringC &str, ISet<WideChar> &to) const
274 {
275   for (size_t i = 0; i < sections_.size(); i++)
276     sections_[i].stringToChar(str, to);
277 }
278
279 void CharsetDecl::numberToChar(const PublicId *id, Number n,
280                                ISet<WideChar> &to, Number &count) const
281 {
282   for (size_t i = 0; i < sections_.size(); i++)
283     sections_[i].numberToChar(id, n, to, count);
284 }
285
286 #ifdef SP_NAMESPACE
287 }
288 #endif