1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// Copyright (c) 1994 James Clark
// See the file COPYING for copying permission.
#ifdef __GNUG__
#pragma implementation
#endif
#include "splib.h"
#include "OutputState.h"
#include "Event.h"
#include "Allocator.h"
#ifdef SP_NAMESPACE
namespace SP_NAMESPACE {
#endif
OutputState::OutputState()
{
init();
}
void OutputState::init()
{
nextSerial_ = 0;
stack_.clear();
stack_.insert(new OutputStateLevel);
}
OutputStateLevel::OutputStateLevel()
: state(OutputState::afterStartTag)
{
}
void OutputState::handleRe(EventHandler &handler, Allocator &alloc,
const EventsWanted &eventsWanted, Char re,
const Location &location)
{
re_ = re;
if (eventsWanted.wantInstanceMarkup())
handler.reOrigin(new (alloc) ReOriginEvent(re_, location, nextSerial_));
switch (top().state) {
case afterStartTag:
// it's the first RE in the element
if (eventsWanted.wantInstanceMarkup())
handler.ignoredRe(new (alloc) IgnoredReEvent(re_, location, nextSerial_++));
top().state = afterRsOrRe;
break;
case afterRsOrRe:
case afterData:
top().state = pendingAfterRsOrRe;
top().reLocation = location;
top().reSerial = nextSerial_++;
break;
case pendingAfterRsOrRe:
// We now know that the pending RE won't be ignored as the last RE.
handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
top().state = pendingAfterRsOrRe;
top().reLocation = location;
top().reSerial = nextSerial_++;
break;
case pendingAfterMarkup:
// We've had only markup since the last RS or RE, so this
// RE is ignored. Note that it's this RE that's ignored, not
// the pending one.
if (eventsWanted.wantInstanceMarkup())
handler.ignoredRe(new (alloc) IgnoredReEvent(re_, location, nextSerial_++));
top().state = pendingAfterRsOrRe;
break;
}
}
void OutputState::noteRs(EventHandler &, Allocator &, const EventsWanted &)
{
if (top().hasPendingRe())
top().state = pendingAfterRsOrRe;
else
top().state = afterRsOrRe;
}
void OutputState::noteMarkup(EventHandler &, Allocator &, const EventsWanted &)
{
switch (top().state) {
case afterRsOrRe:
top().state = afterStartTag;
break;
case pendingAfterRsOrRe:
top().state = pendingAfterMarkup;
break;
default:
break; // avoid warning
}
}
void OutputState::noteData(EventHandler &handler, Allocator &alloc,
const EventsWanted &)
{
if (top().hasPendingRe())
handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
top().state = afterData;
}
void OutputState::noteStartElement(Boolean included,
EventHandler &handler, Allocator &alloc,
const EventsWanted &)
{
if (included)
stack_.insert(new OutputStateLevel);
else {
if (top().hasPendingRe())
handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
top().state = afterStartTag;
}
}
void OutputState::noteEndElement(Boolean included, EventHandler &handler,
Allocator &alloc,
const EventsWanted &eventsWanted)
{
if (eventsWanted.wantInstanceMarkup() && top().hasPendingRe())
handler.ignoredRe(new (alloc) IgnoredReEvent(re_, top().reLocation,
top().reSerial));
if (included) {
delete stack_.get();
noteMarkup(handler, alloc, eventsWanted);
}
else
top().state = afterData;
}
#ifdef SP_NAMESPACE
}
#endif
|