1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
14 namespace SP_NAMESPACE
{
17 class InputSourceOriginImpl
: public EntityOrigin
{
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;
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
40 class EntityOriginImpl
: public InputSourceOriginImpl
{
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
) {
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
);
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;
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)
72 Owner
<Markup
> markup_
;
75 const size_t EntityOrigin::allocSize
= sizeof(EntityOriginImpl
);
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
)
95 const EntityOrigin
*Origin::asEntityOrigin() const
100 const InputSourceOrigin
*Origin::asInputSourceOrigin() const
105 Index
Origin::refLength() const
110 Boolean
Origin::origChars(const Char
*&) const
115 Boolean
Origin::inBracketedTextOpenDelim() const
120 Boolean
Origin::inBracketedTextCloseDelim() const
125 Boolean
Origin::isNumericCharRef(const Markup
*&) const
130 Boolean
Origin::isNamedCharRef(Index
, NamedCharRef
&) const
135 const EntityDecl
*Origin::entityDecl() const
140 const Markup
*Origin::markup() const
145 const Entity
*Origin::entity() const
150 Boolean
Origin::defLocation(Offset
, const Origin
*&, Index
&) const
155 const ExternalInfo
*Origin::externalInfo() const
160 Offset
Origin::startOffset(Index ind
) const
165 const StringC
*Origin::entityName() const
167 const EntityDecl
*ent
= entityDecl();
174 BracketOrigin::BracketOrigin(const Location
&loc
, Position pos
)
175 : loc_(loc
), pos_(pos
)
179 const Location
&BracketOrigin::parent() const
184 Boolean
BracketOrigin::inBracketedTextOpenDelim() const
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
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
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
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();
265 // charRefs_ < i have replacementIndex < ind
266 // charRefs_ >= lim have replacementIndex >= ind
268 size_t lim
= charRefs_
.size();
270 size_t mid
= i
+ (lim
- i
)/2;
271 if (charRefs_
[mid
].replacementIndex
>= ind
)
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
) {
287 ind
= charRefs_
[n
].refStartIndex
;
288 if (n
== 0 || charRefs_
[n
- 1].replacementIndex
!= ind
)
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
);
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
,
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
,
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
,
364 Owner
<Markup
> &markup
)
365 : InputSourceOriginImpl(refLocation
), refLength_(refLength
), entity_(entity
)
367 markup
.swap(markup_
);
370 EntityOriginImpl::~EntityOriginImpl()
374 InputSourceOrigin
*EntityOriginImpl::copy() const
378 m
= new Markup(*markup_
);
379 return new EntityOriginImpl(entity_
, parent(), refLength_
, m
);
382 Index
EntityOriginImpl::refLength() const
387 const EntityOrigin
*EntityOriginImpl::asEntityOrigin() const
392 Boolean
EntityOriginImpl::defLocation(Offset off
, const Origin
*&origin
, Index
&index
) const
394 if (entity_
.isNull())
396 const InternalEntity
*internal
= entity_
->asInternalEntity();
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
423 Boolean
ReplacementOrigin::origChars(const Char
*&s
) const
425 if (loc_
.origin().isNull() || !loc_
.origin()->origChars(s
))
430 MultiReplacementOrigin::MultiReplacementOrigin(const Location
&loc
,
434 origChars
.swap(origChars_
);
437 const Location
&MultiReplacementOrigin::parent() const
442 Boolean
MultiReplacementOrigin::origChars(const Char
*&s
) const
444 if (loc_
.origin().isNull() || !loc_
.origin()->origChars(s
))
445 s
= origChars_
.data();
449 ProxyOrigin::ProxyOrigin(const 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
),
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
);