Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / nsgmls / GenericEventHandler.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: GenericEventHandler.C /main/1 1996/07/29 16:52:15 cde-hp $ */
24 // Copyright (c) 1996 James Clark
25 // See the file COPYING for copying permission.
26
27 #ifdef __GNUG__
28 #pragma implementation
29 #endif
30
31 #include "splib.h"
32 #include "GenericEventHandler.h"
33 #include "macros.h"
34 #include "ExtendEntityManager.h"
35
36 #ifdef SP_NAMESPACE
37 namespace SP_NAMESPACE {
38 #endif
39
40 class SpOpenEntity : public SGMLApplication::OpenEntity {
41 public:
42   SpOpenEntity(const ConstPtr<Origin> &origin);
43   SGMLApplication::Location location(SGMLApplication::Position) const;
44 private:
45   ConstPtr<Origin> origin_;
46 };
47
48 inline
49 void *operator new(size_t n, GenericEventHandler *handler)
50 {
51   return handler->allocate(n);
52 }
53
54 inline
55 void GenericEventHandler::freeAll()
56 {
57   if (allocBlocks_)
58     freeAll1();
59 }
60
61 inline
62 void GenericEventHandler::clearNotation(SGMLApplication::Notation &to)
63 {
64   clearString(to.name);
65 }
66
67 inline
68 void GenericEventHandler::setLocation(SGMLApplication::Position &pos,
69                                   const Location &loc)
70 {
71   if (lastOrigin_ != loc.origin())
72     setLocation1(pos, loc);
73   else
74     pos = loc.index();
75 }
76
77 GenericEventHandler::GenericEventHandler(SGMLApplication &app,
78                                          bool generalEntities)
79 : app_(&app), generalEntities_(generalEntities),
80   freeBlocks_(0), allocBlocks_(0), firstBlockSpare_(0), firstBlockUsed_(0)
81 {
82 }
83
84 GenericEventHandler::~GenericEventHandler()
85 {
86   freeAll();
87   while (freeBlocks_) {
88     Block *tem = freeBlocks_;
89     freeBlocks_ = freeBlocks_->next;
90     delete [] tem->mem;
91     delete tem;
92   }
93 }
94
95 void GenericEventHandler::freeAll1()
96 {
97   Block **p;
98   for (p = &allocBlocks_; *p; p = &(*p)->next)
99     ;
100   *p = freeBlocks_;
101   freeBlocks_ = allocBlocks_;
102   allocBlocks_ = 0;
103   if (freeBlocks_)
104     firstBlockSpare_ = freeBlocks_->size;
105   else
106     firstBlockSpare_ = 0;
107   firstBlockUsed_ = 0;
108 }
109
110 void *GenericEventHandler::allocate(size_t n)
111 {
112   if (n == 0)
113     return 0;
114   // round up to avoid alignment problems
115   n = (n + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
116   enum { BIG = 1024 };
117   if (n > firstBlockSpare_) {
118     if (freeBlocks_ && firstBlockUsed_) {
119       Block *tem = freeBlocks_;
120       freeBlocks_ = freeBlocks_->next;
121       tem->next = allocBlocks_;
122       allocBlocks_ = tem;
123     }
124     if (!freeBlocks_ || freeBlocks_->size < n) {
125       Block *tem = new Block;
126       tem->size = n < BIG ? int(BIG) : n;
127       tem->mem = new char[tem->size];
128       tem->next = freeBlocks_;
129       freeBlocks_ = tem;
130     }
131     firstBlockUsed_ = 0;
132     firstBlockSpare_ = freeBlocks_->size;
133   }
134   char *tem = freeBlocks_->mem + firstBlockUsed_;
135   firstBlockUsed_ += n;
136   firstBlockSpare_ -= n;
137   return tem;
138 }
139
140 void GenericEventHandler::startElement(StartElementEvent *event)
141 {
142   SGMLApplication::StartElementEvent appEvent;
143   setString(appEvent.gi, event->name());
144   const ElementDefinition *def = event->elementType()->definition();
145   switch (def->declaredContent()) {
146   case ElementDefinition::modelGroup:
147     appEvent.contentType
148       = (def->compiledModelGroup()->containsPcdata()
149          ? SGMLApplication::StartElementEvent::mixed
150          : SGMLApplication::StartElementEvent::element);
151     break;
152   case ElementDefinition::any:
153     appEvent.contentType = SGMLApplication::StartElementEvent::mixed;
154     break;
155   case ElementDefinition::cdata:
156     appEvent.contentType = SGMLApplication::StartElementEvent::cdata;
157     break;
158   case ElementDefinition::rcdata:
159     appEvent.contentType = SGMLApplication::StartElementEvent::rcdata;
160     break;
161   case ElementDefinition::empty:
162     appEvent.contentType = SGMLApplication::StartElementEvent::empty;
163     break;
164   }
165   appEvent.included = event->included();
166   appEvent.nAttributes = event->attributes().size();
167   if (appEvent.nAttributes != 0) {
168     if (event->attributes().conref())
169       appEvent.contentType = SGMLApplication::StartElementEvent::empty;
170     setAttributes(appEvent.attributes, event->attributes());
171   }
172   setLocation(appEvent.pos, event->location());
173   app_->startElement(appEvent);
174   freeAll();
175   delete event;
176 }
177
178 void GenericEventHandler::endElement(EndElementEvent *event)
179 {
180   SGMLApplication::EndElementEvent appEvent;
181   setString(appEvent.gi, event->name());
182   setLocation(appEvent.pos, event->location());
183   app_->endElement(appEvent);
184   delete event;
185 }
186
187 void GenericEventHandler::data(DataEvent *event)
188 {
189   SGMLApplication::DataEvent appEvent;
190   appEvent.data.ptr = event->data();
191   appEvent.data.len = event->dataLength();
192   setLocation(appEvent.pos, event->location());
193   app_->data(appEvent);
194   delete event;
195 }
196
197 void GenericEventHandler::pi(PiEvent *event)
198 {
199   SGMLApplication::PiEvent appEvent;
200   appEvent.data.ptr = event->data();
201   appEvent.data.len = event->dataLength();
202   const Entity *entity = event->entity();
203   if (entity)
204     setString(appEvent.entityName, entity->name());
205   else
206     appEvent.entityName.len = 0;
207   setLocation(appEvent.pos, event->location());
208   app_->pi(appEvent);
209   delete event;
210 }
211
212 void GenericEventHandler::sdataEntity(SdataEntityEvent *event)
213 {
214   SGMLApplication::SdataEvent appEvent;
215   appEvent.text.ptr = event->data();
216   appEvent.text.len = event->dataLength();
217   setString(appEvent.entityName, event->entity()->name());
218   // Don't want location of chars in entity.
219   setLocation(appEvent.pos, event->location().origin()->parent());
220   app_->sdata(appEvent);
221   delete event;
222 }
223
224 void GenericEventHandler::externalDataEntity(ExternalDataEntityEvent *event)
225 {
226   SGMLApplication::ExternalDataEntityRefEvent appEvent;
227   setEntity(appEvent.entity, *event->entity());
228   setLocation(appEvent.pos, event->location());
229   app_->externalDataEntityRef(appEvent);
230   freeAll();
231   delete event;
232 }
233
234 void GenericEventHandler::subdocEntity(SubdocEntityEvent *event)
235 {
236   SGMLApplication::SubdocEntityRefEvent appEvent;
237   setEntity(appEvent.entity, *event->entity());
238   setLocation(appEvent.pos, event->location());
239   app_->subdocEntityRef(appEvent);
240   freeAll();
241   delete event;
242 }
243
244 void GenericEventHandler::startDtd(StartDtdEvent *event)
245 {
246   SGMLApplication::StartDtdEvent appEvent;
247   setString(appEvent.name, event->name());
248   const Entity *entity = event->entity().pointer();
249   if (entity) {
250     appEvent.haveExternalId = 1;
251     setExternalId(appEvent.externalId,
252                   entity->asExternalEntity()->externalId());
253   }
254   else
255     appEvent.haveExternalId = 0;
256   setLocation(appEvent.pos, event->location());
257   app_->startDtd(appEvent);
258   freeAll();
259   delete event;
260 }
261
262 void GenericEventHandler::endDtd(EndDtdEvent *event)
263 {
264   SGMLApplication::EndDtdEvent appEvent;
265   setString(appEvent.name, event->dtd().name());
266   setLocation(appEvent.pos, event->location());
267   app_->endDtd(appEvent);
268   delete event;
269 }
270
271 void GenericEventHandler::endProlog(EndPrologEvent *event)
272 {
273   if (generalEntities_) {
274     SGMLApplication::GeneralEntityEvent entityEvent;
275     const Dtd &dtd = event->dtd();
276     Dtd::ConstEntityIter iter(dtd.generalEntityIter());
277     for (;;) {
278       const Entity *entity = iter.nextTemp();
279       if (!entity)
280         break;
281       setEntity(entityEvent.entity, *entity);
282       app_->generalEntity(entityEvent);
283     }
284     freeAll();
285   }
286   SGMLApplication::EndPrologEvent appEvent;
287   setLocation(appEvent.pos, event->location());
288   app_->endProlog(appEvent);
289   delete event;
290 }
291
292 void GenericEventHandler::entityDefaulted(EntityDefaultedEvent *event)
293 {
294   if (generalEntities_) {
295     SGMLApplication::GeneralEntityEvent appEvent;
296     setEntity(appEvent.entity, event->entity());
297     app_->generalEntity(appEvent);
298   }
299   delete event;
300 }
301
302 void GenericEventHandler::appinfo(AppinfoEvent *event)
303 {
304   SGMLApplication::AppinfoEvent appEvent;
305   const StringC *str;
306   if (event->literal(str)) {
307     setString(appEvent.string, *str);
308     appEvent.none = 0;
309   }
310   else
311     appEvent.none = 1;
312   setLocation(appEvent.pos, event->location());
313   app_->appinfo(appEvent);
314   delete event;
315 }
316
317 void GenericEventHandler::commentDecl(CommentDeclEvent *event)
318 {
319   SGMLApplication::CommentDeclEvent appEvent;
320   appEvent.nComments = 0;
321   {
322     for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
323       if (iter.type() == Markup::comment)
324         appEvent.nComments++;
325   }
326   SGMLApplication::CharString *comments
327     = (SGMLApplication::CharString *)allocate(appEvent.nComments * 2
328                                               * sizeof(SGMLApplication::CharString));
329   appEvent.comments = comments;
330   appEvent.seps = appEvent.comments + appEvent.nComments;
331   size_t i = 0;
332   for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
333     switch (iter.type()) {
334     case Markup::comment:
335       comments[i].ptr = iter.charsPointer();
336       comments[i].len = iter.charsLength();
337       clearString(comments[appEvent.nComments + i]);
338       i++;
339       break;
340     case Markup::s:
341       comments[appEvent.nComments + i - 1].ptr = iter.charsPointer();
342       comments[appEvent.nComments + i - 1].len = iter.charsLength();
343       break;
344     default:
345       break;
346     }
347   setLocation(appEvent.pos, event->location());
348   app_->commentDecl(appEvent);
349   freeAll();
350   delete event;
351 }
352
353 void GenericEventHandler::markedSectionStart(MarkedSectionStartEvent *event)
354 {
355   SGMLApplication::MarkedSectionStartEvent appEvent;
356   unsigned depth = 0;
357   appEvent.nParams = 0;
358   {
359     for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
360       switch (iter.type()) {
361       case Markup::reservedName:
362         if (!depth)
363           appEvent.nParams++;
364         break;
365       case Markup::entityStart:
366         if (!depth)
367           appEvent.nParams++;
368         depth++;
369         break;
370       case Markup::entityEnd:
371         depth--;
372         break;
373       default:
374         break;
375       }
376   }
377   SGMLApplication::MarkedSectionStartEvent::Param *params
378     = (SGMLApplication::MarkedSectionStartEvent::Param *)
379       allocate(appEvent.nParams * sizeof(appEvent.params[0]));
380   appEvent.params = params;
381   size_t i = 0;
382   for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
383     switch (iter.type()) {
384     case Markup::reservedName:
385       if (!depth) {
386         switch (iter.reservedName()) {
387         case Syntax::rTEMP:
388           params[i].type
389             = SGMLApplication::MarkedSectionStartEvent::Param::temp;
390           break;
391         case Syntax::rINCLUDE:
392           params[i].type
393             = SGMLApplication::MarkedSectionStartEvent::Param::include;
394           break;
395         case Syntax::rRCDATA:
396           params[i].type
397             = SGMLApplication::MarkedSectionStartEvent::Param::rcdata;
398           break;
399         case Syntax::rCDATA:
400           params[i].type
401             = SGMLApplication::MarkedSectionStartEvent::Param::cdata;
402           break;
403         case Syntax::rIGNORE:
404           params[i].type
405             = SGMLApplication::MarkedSectionStartEvent::Param::ignore;
406           break;
407         default:
408           CANNOT_HAPPEN();
409         }
410         clearString(params[i].entityName);
411         i++;
412       }
413       break;
414     case Markup::entityStart:
415       if (!depth) {
416         params[i].type
417           = SGMLApplication::MarkedSectionStartEvent::Param::entityRef;
418         setString(params[i].entityName,
419                   iter.entityOrigin()->entity()->name());
420         i++;
421       }
422       depth++;
423       break;
424     case Markup::entityEnd:
425       depth--;
426       break;
427     default:
428       break;
429     }
430   switch (event->status()) {
431   case MarkedSectionEvent::include:
432     appEvent.status = SGMLApplication::MarkedSectionStartEvent::include;
433     break;
434   case MarkedSectionEvent::rcdata:
435     appEvent.status = SGMLApplication::MarkedSectionStartEvent::rcdata;
436     break;
437   case MarkedSectionEvent::cdata:
438     appEvent.status = SGMLApplication::MarkedSectionStartEvent::cdata;
439     break;
440   case MarkedSectionEvent::ignore:
441     appEvent.status = SGMLApplication::MarkedSectionStartEvent::ignore;
442     break;
443   }
444   setLocation(appEvent.pos, event->location());
445   app_->markedSectionStart(appEvent);
446   freeAll();
447   delete event;
448 }
449
450 void GenericEventHandler::ignoredChars(IgnoredCharsEvent *event)
451 {
452   SGMLApplication::IgnoredCharsEvent appEvent;
453   appEvent.data.ptr = event->data();
454   appEvent.data.len = event->dataLength();
455   setLocation(appEvent.pos, event->location());
456   app_->ignoredChars(appEvent);
457   delete event;
458 }
459
460 void GenericEventHandler::markedSectionEnd(MarkedSectionEndEvent *event)
461 {
462   SGMLApplication::MarkedSectionEndEvent appEvent;
463   switch (event->status()) {
464   case MarkedSectionEvent::include:
465     appEvent.status = SGMLApplication::MarkedSectionEndEvent::include;
466     break;
467   case MarkedSectionEvent::rcdata:
468     appEvent.status = SGMLApplication::MarkedSectionEndEvent::rcdata;
469     break;
470   case MarkedSectionEvent::cdata:
471     appEvent.status = SGMLApplication::MarkedSectionEndEvent::cdata;
472     break;
473   case MarkedSectionEvent::ignore:
474     appEvent.status = SGMLApplication::MarkedSectionEndEvent::ignore;
475     break;
476   }
477   setLocation(appEvent.pos, event->location());
478   app_->markedSectionEnd(appEvent);
479   delete event;
480 }
481
482 void GenericEventHandler::message(MessageEvent *event)
483 {
484   SGMLApplication::ErrorEvent appEvent;
485   switch (event->message().type->severity()) {
486   case MessageType::quantityError:
487     appEvent.type = SGMLApplication::ErrorEvent::quantity;
488     break;
489   case MessageType::idrefError:
490     appEvent.type = SGMLApplication::ErrorEvent::idref;
491     break;
492   case MessageType::error:
493     appEvent.type = SGMLApplication::ErrorEvent::otherError;
494     break;
495   case MessageType::info:
496     appEvent.type = SGMLApplication::ErrorEvent::info;
497     break;
498   case MessageType::warning:
499     appEvent.type = SGMLApplication::ErrorEvent::warning;
500     break;
501   }
502   setLocation(appEvent.pos, event->message().loc);
503   StringC str;
504   reportMessage(event->message(), str);
505   setString(appEvent.message, str);
506   app_->error(appEvent);
507   ErrorCountEventHandler::message(event);
508 }
509
510 void GenericEventHandler::setLocation1(SGMLApplication::Position &pos,
511                                    const Location &loc)
512 {
513   const Location *locp = &loc;
514   for (;;) {
515     if (locp->origin().isNull()) {
516       lastOrigin_.clear();
517       openEntityPtr_ = (SpOpenEntity *)0;
518       return;
519     }
520     const InputSourceOrigin *origin = locp->origin()->asInputSourceOrigin();
521     if (origin && origin->externalInfo())
522       break;
523     locp = &locp->origin()->parent();
524   }
525   lastOrigin_ = locp->origin();
526   pos = locp->index();
527   openEntityPtr_ = new SpOpenEntity(locp->origin());
528   app_->openEntityChange(openEntityPtr_);
529 }
530
531 void 
532 GenericEventHandler::setAttributes(const SGMLApplication::Attribute *&attributes,
533                                const AttributeList &attributeList)
534 {
535   size_t nAttributes = attributeList.size();
536   SGMLApplication::Attribute *to
537     = (SGMLApplication::Attribute *)allocate(nAttributes * sizeof(*to));
538   attributes = to;
539   for (size_t i = 0; i < nAttributes; i++) {
540     SGMLApplication::Attribute *p = to + i;
541     setString(p->name, attributeList.name(i));
542     const AttributeValue *value = attributeList.value(i);
543     if (!value)
544       p->type = SGMLApplication::Attribute::invalid;
545     else {
546       const Text *text;
547       const StringC *string;
548       switch (value->info(text, string)) {
549       case AttributeValue::implied:
550         p->type = SGMLApplication::Attribute::implied;
551         break;
552       case AttributeValue::tokenized:
553         {
554           if (attributeList.specified(i))
555             p->defaulted = SGMLApplication::Attribute::specified;
556           else if (attributeList.current(i))
557             p->defaulted = SGMLApplication::Attribute::current;
558           else
559             p->defaulted = SGMLApplication::Attribute::definition;
560           p->type = SGMLApplication::Attribute::tokenized;
561           p->nEntities = 0;
562           p->notation.name.len = 0;
563           p->isId = attributeList.id(i);
564           p->isGroup = (attributeList.getAllowedTokens(i) != 0);
565           setString(p->tokens, *string);
566           const AttributeSemantics *semantics = attributeList.semantics(i);
567           if (semantics) {
568             ConstPtr<Notation> notation = semantics->notation();
569             if (!notation.isNull())
570               setNotation(p->notation, *notation);
571             else {
572               size_t nEntities = semantics->nEntities();
573               if (nEntities) {
574                 SGMLApplication::Entity *v
575                   = (SGMLApplication::Entity *)allocate(nEntities * sizeof(*v));
576                 p->entities = v;
577                 p->nEntities = nEntities;
578                 for (size_t i = 0; i < nEntities; i++)
579                   setEntity(v[i], *semantics->entity(i));
580               }
581             }
582           }
583         }
584         break;
585       case AttributeValue::cdata:
586         {
587           p->type = SGMLApplication::Attribute::cdata;
588           if (attributeList.specified(i))
589             p->defaulted = SGMLApplication::Attribute::specified;
590           else if (attributeList.current(i))
591             p->defaulted = SGMLApplication::Attribute::current;
592           else
593             p->defaulted = SGMLApplication::Attribute::definition;
594           TextItem::Type type;
595           const Char *s;
596           size_t length;
597           const Location *loc;
598           size_t nChunks = 0;
599           {
600             TextIter iter(*text);
601             while (iter.next(type, s, length, loc))
602               switch (type) {
603               case TextItem::data:
604               case TextItem::sdata:
605               case TextItem::cdata:
606                 nChunks++;
607                 break;
608               default:
609                 break;
610               }
611           }
612           p->cdataChunks
613             = (SGMLApplication::Attribute::CdataChunk *)allocate(nChunks * sizeof(SGMLApplication::Attribute::CdataChunk));
614           p->nCdataChunks = nChunks;
615
616           {
617             size_t i = 0;
618             for (TextIter iter(*text);
619                  iter.next(type, s, length, loc);
620                  i++) {
621               switch (type) {
622               case TextItem::data:
623               case TextItem::sdata:
624               case TextItem::cdata:
625                 {
626                   SGMLApplication::Attribute::CdataChunk *chunk
627                     = (SGMLApplication::Attribute::CdataChunk *)(p->cdataChunks + i);
628                   if (type != TextItem::sdata)
629                     chunk->isSdata = 0;
630                   else {
631                     chunk->isSdata = 1;
632                     setString(chunk->entityName,
633                               *loc->origin()->asInputSourceOrigin()->entityName());
634                   }
635                   chunk->data.ptr = s;
636                   chunk->data.len = length;
637                 }
638                 break;
639               default:
640                 break;
641               }
642             }
643           }
644         }
645         break;
646       }
647     }
648   }
649 }
650
651
652 void GenericEventHandler::setEntity(SGMLApplication::Entity &to,
653                                 const Entity &from)
654 {
655   setString(to.name, from.name());
656   switch (from.declType()) {
657   case Entity::generalEntity:
658     to.declType = SGMLApplication::Entity::general;
659     break;
660   case Entity::parameterEntity:
661     to.declType = SGMLApplication::Entity::parameter;
662     break;
663   case Entity::doctype:
664     to.declType = SGMLApplication::Entity::doctype;
665     break;
666   case Entity::linktype:
667     to.declType = SGMLApplication::Entity::linktype;
668     break;
669   default:
670     CANNOT_HAPPEN();
671   }
672   switch (from.dataType()) {
673   case Entity::sgmlText:
674     to.dataType = SGMLApplication::Entity::sgml;
675     break;
676   case Entity::cdata:
677     to.dataType = SGMLApplication::Entity::cdata;
678     break;
679   case Entity::sdata:
680     to.dataType = SGMLApplication::Entity::sdata;
681     break;
682   case Entity::ndata:
683     to.dataType = SGMLApplication::Entity::ndata;
684     break;
685   case Entity::subdoc:
686     to.dataType = SGMLApplication::Entity::subdoc;
687     break;
688   case Entity::pi:
689     to.dataType = SGMLApplication::Entity::pi;
690     break;
691   }
692   const InternalEntity *internal = from.asInternalEntity();
693   if (internal) {
694     to.isInternal = 1;
695     setString(to.text, internal->string());
696   }
697   else {
698     const ExternalEntity *external = from.asExternalEntity();
699     to.isInternal = 0;
700     setExternalId(to.externalId, external->externalId());
701     const ExternalDataEntity *externalData = from.asExternalDataEntity();
702     if (externalData) {
703       setNotation(to.notation, *externalData->notation());
704       to.nAttributes = externalData->attributes().size();
705       if (to.nAttributes)
706         setAttributes(to.attributes, externalData->attributes());
707     }
708     else {
709       to.notation.name.len = 0;
710       to.nAttributes = 0;
711     }
712   }
713 }
714
715
716 void GenericEventHandler::setNotation(SGMLApplication::Notation &to,
717                                       const Notation &from)
718 {
719   setString(to.name, from.name());
720   setExternalId(to.externalId, from.externalId());
721 }
722
723 void GenericEventHandler::setExternalId(SGMLApplication::ExternalId &to,
724                                         const ExternalId &from)
725 {
726   const StringC *str;
727   str = from.systemIdString();
728   if (str) {
729     to.haveSystemId = 1;
730     setString(to.systemId, *str);
731   }
732   else
733     to.haveSystemId = 0;
734   str = from.publicIdString();
735   if (str) {
736     to.havePublicId = 1;
737     setString(to.publicId, *str);
738   }
739   else
740     to.havePublicId = 0;
741   str = &from.effectiveSystemId();
742   if (str->size()) {
743     to.haveGeneratedSystemId = 1;
744     setString(to.generatedSystemId, *str);
745   }
746   else
747     to.haveGeneratedSystemId = 0;
748 }
749
750 MsgGenericEventHandler::MsgGenericEventHandler(SGMLApplication &app, 
751                                                bool generalEntities,
752                                                MessageReporter &reporter,
753                                                const bool *messagesInhibitedPtr)
754 : GenericEventHandler(app, generalEntities),
755   reporter_(&reporter),
756   messagesInhibitedPtr_(messagesInhibitedPtr)
757 {
758 }
759
760 void MsgGenericEventHandler::reportMessage(const Message &msg, StringC &str)
761 {
762   WrapReporter wrap(reporter_);
763   reporter_->dispatchMessage(msg);
764   wrap.strStream.extractString(str);
765   if (!*messagesInhibitedPtr_)
766     *wrap.origStream << str;
767 }
768
769 SpOpenEntity::SpOpenEntity(const ConstPtr<Origin> &origin)
770 : origin_(origin)
771 {
772 }
773
774 SGMLApplication::Location
775 SpOpenEntity::location(SGMLApplication::Position pos) const
776 {
777   SGMLApplication::Location loc;
778   const Origin *origin = origin_.pointer();
779   const InputSourceOrigin *inputSourceOrigin;
780   const ExternalInfo *externalInfo;
781   Index index = Index(pos);
782   for (;;) {
783     if (!origin)
784       return loc;
785     inputSourceOrigin = origin->asInputSourceOrigin();
786     if (inputSourceOrigin) {
787       externalInfo = inputSourceOrigin->externalInfo();
788       if (externalInfo)
789         break;
790     }
791     const Location &loc = origin->parent();
792     index = loc.index();
793     origin = loc.origin().pointer();
794   }
795   const StringC *entityName = inputSourceOrigin->entityName();
796   if (entityName)
797     GenericEventHandler::setString(loc.entityName, *entityName);
798   Offset off = inputSourceOrigin->startOffset(index);
799   loc.entityOffset = off;
800   StorageObjectLocation soLoc;
801   if (!ExtendEntityManager::externalize(externalInfo, off, soLoc))
802     return loc;
803   loc.lineNumber = soLoc.lineNumber;
804   GenericEventHandler::setString(loc.filename, soLoc.storageObjectSpec->id);
805   loc.columnNumber = soLoc.columnNumber;
806   loc.byteOffset = soLoc.byteIndex;
807   loc.other = soLoc.storageObjectSpec;
808   return loc;
809 }
810
811 #ifdef SP_NAMESPACE
812 }
813 #endif