3065 some functions in the tcp module can be static
[unleashed.git] / usr / src / cmd / man / src / util / nsgmls.src / lib / Location.cxx
blob74cfc71edf2ace8c1f5cf030b15dc69ae292cad5
1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8 #include "splib.h"
9 #include "Location.h"
10 #include "Entity.h"
11 #include "Mutex.h"
13 #ifdef SP_NAMESPACE
14 namespace SP_NAMESPACE {
15 #endif
17 class InputSourceOriginImpl : public EntityOrigin {
18 public:
19 InputSourceOriginImpl();
20 InputSourceOriginImpl(const Location &refLocation);
21 const Location &parent() const;
22 const ExternalInfo *externalInfo() const;
23 Offset startOffset(Index ind) const;
24 void noteCharRef(Index replacementIndex, const NamedCharRef &);
25 Boolean isNamedCharRef(Index ind, NamedCharRef &ref) const;
26 void setExternalInfo(ExternalInfo *);
27 virtual InputSourceOrigin *copy() const;
28 const InputSourceOrigin *asInputSourceOrigin() const;
29 private:
30 InputSourceOriginImpl(const InputSourceOriginImpl &); // undefined
31 void operator=(const InputSourceOriginImpl &); // undefined
32 size_t nPrecedingCharRefs(Index ind) const;
33 Vector<InputSourceOriginNamedCharRef> charRefs_;
34 StringC charRefOrigNames_;
35 Owner<ExternalInfo> externalInfo_; // 0 for internal entities
36 Location refLocation_; // where referenced from
37 Mutex mutex_;
40 class EntityOriginImpl : public InputSourceOriginImpl {
41 public:
42 void *operator new(size_t sz, Allocator &alloc) {
43 return alloc.alloc(sz);
45 void *operator new(size_t sz) {
46 return Allocator::allocSimple(sz);
48 void operator delete(void *p) {
49 Allocator::free(p);
51 EntityOriginImpl(const ConstPtr<Entity> &);
52 EntityOriginImpl(const ConstPtr<Entity> &,
53 const Location &refLocation);
54 EntityOriginImpl(const ConstPtr<Entity> &,
55 const Location &refLocation, Index refLength,
56 Owner<Markup> &markup);
57 ~EntityOriginImpl();
58 InputSourceOrigin *copy() const;
59 const Entity *entity() const { return entity_.pointer(); }
60 const EntityDecl *entityDecl() const;
61 const EntityOrigin *asEntityOrigin() const;
62 Boolean defLocation(Offset off, const Origin *&, Index &) const;
63 Index refLength() const;
64 const Markup *markup() const;
65 private:
66 EntityOriginImpl(const EntityOriginImpl &); // undefined
67 void operator=(const EntityOriginImpl &); // undefined
68 ConstPtr<Entity> entity_; // 0 for document entity
69 // total length of reference
70 // (characters that were replaced by the entity)
71 Index refLength_;
72 Owner<Markup> markup_;
75 const size_t EntityOrigin::allocSize = sizeof(EntityOriginImpl);
77 Location::Location()
81 Location::Location(Origin *origin, Index i)
82 : origin_(origin), index_(i)
86 Location::Location(ConstPtr<Origin> origin, Index i)
87 : origin_(origin), index_(i)
91 Origin::~Origin()
95 const EntityOrigin *Origin::asEntityOrigin() const
97 return 0;
100 const InputSourceOrigin *Origin::asInputSourceOrigin() const
102 return 0;
105 Index Origin::refLength() const
107 return 0;
110 Boolean Origin::origChars(const Char *&) const
112 return 0;
115 Boolean Origin::inBracketedTextOpenDelim() const
117 return 0;
120 Boolean Origin::inBracketedTextCloseDelim() const
122 return 0;
125 Boolean Origin::isNumericCharRef(const Markup *&) const
127 return 0;
130 Boolean Origin::isNamedCharRef(Index, NamedCharRef &) const
132 return 0;
135 const EntityDecl *Origin::entityDecl() const
137 return 0;
140 const Markup *Origin::markup() const
142 return 0;
145 const Entity *Origin::entity() const
147 return 0;
150 Boolean Origin::defLocation(Offset, const Origin *&, Index &) const
152 return 0;
155 const ExternalInfo *Origin::externalInfo() const
157 return 0;
160 Offset Origin::startOffset(Index ind) const
162 return ind;
165 const StringC *Origin::entityName() const
167 const EntityDecl *ent = entityDecl();
168 if (ent)
169 return &ent->name();
170 else
171 return 0;
174 BracketOrigin::BracketOrigin(const Location &loc, Position pos)
175 : loc_(loc), pos_(pos)
179 const Location &BracketOrigin::parent() const
181 return loc_;
184 Boolean BracketOrigin::inBracketedTextOpenDelim() const
186 return pos_ == open;
189 Boolean BracketOrigin::inBracketedTextCloseDelim() const
191 return pos_ == close;
194 InputSourceOrigin *InputSourceOrigin::make()
196 return new InputSourceOriginImpl;
199 InputSourceOrigin *InputSourceOrigin::make(const Location &refLocation)
201 return new InputSourceOriginImpl(refLocation);
204 InputSourceOriginImpl::InputSourceOriginImpl()
208 InputSourceOriginImpl::InputSourceOriginImpl(const Location &refLocation)
209 : refLocation_(refLocation)
213 const InputSourceOrigin *InputSourceOriginImpl::asInputSourceOrigin() const
215 return this;
218 const ExternalInfo *InputSourceOriginImpl::externalInfo() const
220 return externalInfo_.pointer();
223 InputSourceOrigin *InputSourceOriginImpl::copy() const
225 return new InputSourceOriginImpl(refLocation_);
228 const Location &InputSourceOriginImpl::parent() const
230 return refLocation_;
233 void InputSourceOriginImpl::setExternalInfo(ExternalInfo *info)
235 externalInfo_ = info;
238 void InputSourceOriginImpl::noteCharRef(Index replacementIndex,
239 const NamedCharRef &ref)
241 Mutex::Lock lock(&mutex_);
242 charRefs_.resize(charRefs_.size() + 1);
243 charRefs_.back().replacementIndex = replacementIndex;
244 charRefs_.back().refStartIndex = ref.refStartIndex();
245 charRefs_.back().refEndType = ref.refEndType();
246 charRefs_.back().origNameOffset = charRefOrigNames_.size();
247 charRefOrigNames_ += ref.origName();
250 // Number of character references whose replacement index < ind.
252 size_t InputSourceOriginImpl::nPrecedingCharRefs(Index ind) const
254 size_t i;
255 // Find i such that
256 // charRefs_[I].replacementIndex >= ind
257 // charRefs_[i - 1].replacementIndex < ind
258 if (charRefs_.size() == 0
259 || ind > charRefs_.back().replacementIndex)
260 // This will be a common case, so optimize it.
261 i = charRefs_.size();
262 else {
263 // Binary search
264 // Invariant:
265 // charRefs_ < i have replacementIndex < ind
266 // charRefs_ >= lim have replacementIndex >= ind
267 i = 0;
268 size_t lim = charRefs_.size();
269 while (i < lim) {
270 size_t mid = i + (lim - i)/2;
271 if (charRefs_[mid].replacementIndex >= ind)
272 lim = mid;
273 else
274 i = mid + 1;
277 return i;
280 Offset InputSourceOriginImpl::startOffset(Index ind) const
282 Mutex::Lock lock(&((InputSourceOriginImpl *)this)->mutex_);
283 size_t n = nPrecedingCharRefs(ind);
284 if (n < charRefs_.size()
285 && ind == charRefs_[n].replacementIndex) {
286 for (;;) {
287 ind = charRefs_[n].refStartIndex;
288 if (n == 0 || charRefs_[n - 1].replacementIndex != ind)
289 break;
290 --n;
293 // charRefs[n - 1].replacementIndex < ind
294 return Offset(ind - n);
297 Boolean InputSourceOriginImpl::isNamedCharRef(Index ind, NamedCharRef &ref) const
299 Mutex::Lock lock(&((InputSourceOriginImpl *)this)->mutex_);
300 size_t n = nPrecedingCharRefs(ind);
301 if (n < charRefs_.size() && ind == charRefs_[n].replacementIndex) {
302 ref.set(charRefs_[n].refStartIndex,
303 charRefs_[n].refEndType,
304 charRefOrigNames_.data() + charRefs_[n].origNameOffset,
305 (n + 1 < charRefs_.size()
306 ? charRefs_[n + 1].origNameOffset
307 : charRefOrigNames_.size())
308 - charRefs_[n].origNameOffset);
309 return 1;
311 return 0;
314 EntityOrigin *EntityOrigin::make(Allocator &alloc,
315 const ConstPtr<Entity> &entity)
317 return new (alloc) EntityOriginImpl(entity);
320 EntityOrigin *EntityOrigin::make(Allocator &alloc,
321 const ConstPtr<Entity> &entity,
322 const Location &refLocation)
324 return new (alloc) EntityOriginImpl(entity, refLocation);
327 EntityOrigin *EntityOrigin::make(Allocator &alloc,
328 const ConstPtr<Entity> &entity,
329 const Location &refLocation,
330 Index refLength,
331 Owner<Markup> &markup)
333 return new (alloc) EntityOriginImpl(entity, refLocation, refLength, markup);
336 EntityOrigin *EntityOrigin::make(const ConstPtr<Entity> &entity,
337 const Location &refLocation,
338 Index refLength,
339 Owner<Markup> &markup)
341 return new EntityOriginImpl(entity, refLocation, refLength, markup);
344 EntityOrigin *EntityOrigin::make(const ConstPtr<Entity> &entity,
345 const Location &refLocation)
347 return new EntityOriginImpl(entity, refLocation);
350 EntityOriginImpl::EntityOriginImpl(const ConstPtr<Entity> &entity)
351 : refLength_(0), entity_(entity)
355 EntityOriginImpl::EntityOriginImpl(const ConstPtr<Entity> &entity,
356 const Location &refLocation)
357 : InputSourceOriginImpl(refLocation), refLength_(0), entity_(entity)
361 EntityOriginImpl::EntityOriginImpl(const ConstPtr<Entity> &entity,
362 const Location &refLocation,
363 Index refLength,
364 Owner<Markup> &markup)
365 : InputSourceOriginImpl(refLocation), refLength_(refLength), entity_(entity)
367 markup.swap(markup_);
370 EntityOriginImpl::~EntityOriginImpl()
374 InputSourceOrigin *EntityOriginImpl::copy() const
376 Owner<Markup> m;
377 if (markup_)
378 m = new Markup(*markup_);
379 return new EntityOriginImpl(entity_, parent(), refLength_, m);
382 Index EntityOriginImpl::refLength() const
384 return refLength_;
387 const EntityOrigin *EntityOriginImpl::asEntityOrigin() const
389 return this;
392 Boolean EntityOriginImpl::defLocation(Offset off, const Origin *&origin, Index &index) const
394 if (entity_.isNull())
395 return 0;
396 const InternalEntity *internal = entity_->asInternalEntity();
397 if (!internal)
398 return 0;
399 return internal->text().charLocation(off, origin, index);
402 const EntityDecl *EntityOriginImpl::entityDecl() const
404 return entity_.pointer();
407 const Markup *EntityOriginImpl::markup() const
409 return markup_.pointer();
413 ReplacementOrigin::ReplacementOrigin(const Location &loc, Char origChar)
414 : loc_(loc), origChar_(origChar)
418 const Location &ReplacementOrigin::parent() const
420 return loc_;
423 Boolean ReplacementOrigin::origChars(const Char *&s) const
425 if (loc_.origin().isNull() || !loc_.origin()->origChars(s))
426 s = &origChar_;
427 return 1;
430 MultiReplacementOrigin::MultiReplacementOrigin(const Location &loc,
431 StringC &origChars)
432 : loc_(loc)
434 origChars.swap(origChars_);
437 const Location &MultiReplacementOrigin::parent() const
439 return loc_;
442 Boolean MultiReplacementOrigin::origChars(const Char *&s) const
444 if (loc_.origin().isNull() || !loc_.origin()->origChars(s))
445 s = origChars_.data();
446 return 1;
449 ProxyOrigin::ProxyOrigin(const Origin *origin)
450 : origin_(origin)
454 const EntityOrigin *ProxyOrigin::asEntityOrigin() const
456 return origin_->asEntityOrigin();
459 const InputSourceOrigin *ProxyOrigin::asInputSourceOrigin() const
461 return origin_->asInputSourceOrigin();
464 const Location &ProxyOrigin::parent() const
466 return origin_->parent();
469 Index ProxyOrigin::refLength() const
471 return origin_->refLength();
474 Boolean ProxyOrigin::origChars(const Char *&p) const
476 return origin_->origChars(p);
479 Boolean ProxyOrigin::inBracketedTextOpenDelim() const
481 return origin_->inBracketedTextOpenDelim();
484 Boolean ProxyOrigin::inBracketedTextCloseDelim() const
486 return origin_->inBracketedTextCloseDelim();
489 Boolean ProxyOrigin::isNumericCharRef(const Markup *&markup) const
491 return origin_->isNumericCharRef(markup);
494 Boolean ProxyOrigin::isNamedCharRef(Index ind, NamedCharRef &ref) const
496 return origin_->isNamedCharRef(ind, ref);
499 const EntityDecl *ProxyOrigin::entityDecl() const
501 return origin_->entityDecl();
504 Boolean ProxyOrigin::defLocation(Offset off, const Origin *&origin, Index &index) const
506 return origin_->defLocation(off, origin, index);
509 const Markup *ProxyOrigin::markup() const
511 return origin_->markup();
514 const Entity *ProxyOrigin::entity() const
516 return origin_->entity();
519 const ExternalInfo *ProxyOrigin::externalInfo() const
521 return origin_->externalInfo();
524 Offset ProxyOrigin::startOffset(Index ind) const
526 return origin_->startOffset(ind);
529 ExternalInfo::~ExternalInfo()
533 RTTI_DEF0(ExternalInfo)
535 NamedCharRef::NamedCharRef()
539 NamedCharRef::NamedCharRef(Index refStartIndex, RefEndType refEndType,
540 const StringC &origName)
541 : refStartIndex_(refStartIndex),
542 refEndType_(refEndType),
543 origName_(origName)
547 void NamedCharRef::set(Index refStartIndex, RefEndType refEndType,
548 const Char *s, size_t n)
550 refStartIndex_ = refStartIndex;
551 refEndType_ = refEndType;
552 origName_.assign(s, n);
555 #ifdef SP_NAMESPACE
557 #endif