Markup.cxx revision 7c478bd95313f5f23a4c958a745db2134aa03244
// Copyright (c) 1995 James Clark
// See the file COPYING for copying permission.
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __GNUG__
#pragma implementation
#endif
#include "splib.h"
#include "Markup.h"
#include "InputSource.h"
#include "Location.h"
#include "macros.h"
#include "Entity.h"
#ifdef SP_NAMESPACE
namespace SP_NAMESPACE {
#endif
MarkupItem::MarkupItem()
: type(Markup::delimiter), index(0)
{
}
MarkupItem::~MarkupItem()
{
switch (type) {
case Markup::entityStart:
delete origin;
break;
case Markup::literal:
delete text;
break;
case Markup::sdLiteral:
delete sdText;
break;
}
}
MarkupItem::MarkupItem(const MarkupItem &item)
: type(item.type), index(item.index)
{
switch (item.type) {
case Markup::entityStart:
origin = new ConstPtr<Origin>(*item.origin);
break;
case Markup::literal:
text = new Text(*item.text);
break;
case Markup::sdLiteral:
sdText = new SdText(*item.sdText);
break;
case Markup::delimiter:
break;
default:
nChars = item.nChars;
break;
}
}
void MarkupItem::operator=(const MarkupItem &item)
{
switch (type) {
case Markup::entityStart:
if (item.type == Markup::entityStart) {
*origin = *item.origin;
return;
}
delete origin;
break;
case Markup::literal:
if (item.type == Markup::literal) {
*text = *item.text;
return;
}
delete text;
break;
case Markup::sdLiteral:
if (item.type == Markup::sdLiteral) {
*sdText = *item.sdText;
return;
}
delete sdText;
break;
}
type = item.type;
index = item.index;
switch (item.type) {
case Markup::entityStart:
origin = new ConstPtr<Origin>(*item.origin);
break;
case Markup::literal:
text = new Text(*item.text);
break;
case Markup::sdLiteral:
sdText = new SdText(*item.sdText);
break;
case Markup::delimiter:
break;
default:
nChars = item.nChars;
break;
}
}
Markup::Markup()
{
}
void Markup::resize(size_t n)
{
size_t chopChars = 0;
for (size_t i = n; i < items_.size(); i++)
switch (items_[i].type) {
case Markup::reservedName:
case Markup::sdReservedName:
case Markup::name:
case Markup::nameToken:
case Markup::number:
case Markup::attributeValue:
case Markup::s:
case Markup::comment:
case Markup::shortref:
chopChars += items_[i].nChars;
break;
}
items_.resize(n);
chars_.resize(chars_.size() - chopChars);
}
void Markup::addDelim(Syntax::DelimGeneral d)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.type = Markup::delimiter;
item.index = d;
}
void Markup::addReservedName(Syntax::ReservedName rn, const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::reservedName;
item.index = rn;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addReservedName(Syntax::ReservedName rn, const StringC &str)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.nChars = str.size();
item.type = Markup::reservedName;
item.index = rn;
chars_.append(str.data(), str.size());
}
void Markup::addSdReservedName(Sd::ReservedName rn, const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::sdReservedName;
item.index = rn;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addSdReservedName(Sd::ReservedName rn,
const Char *str, size_t length)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.nChars = length;
item.type = Markup::sdReservedName;
item.index = rn;
chars_.append(str, length);
}
void Markup::addS(Char c)
{
if (items_.size() > 0) {
MarkupItem &item = items_.back();
if (item.type == Markup::s) {
item.nChars += 1;
chars_ += c;
return;
}
}
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.type = Markup::s;
item.nChars = 1;
chars_ += c;
}
void Markup::addS(const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::s;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addCommentStart()
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.type = Markup::comment;
item.nChars = 0;
}
void Markup::addRefEndRe()
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.type = Markup::refEndRe;
}
void Markup::addCommentChar(Char c)
{
items_.back().nChars += 1;
chars_ += c;
}
void Markup::addName(const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::name;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addName(const Char *str, size_t length)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.nChars = length;
item.type = Markup::name;
chars_.append(str, length);
}
void Markup::addNumber(const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::number;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addNameToken(const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::nameToken;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addAttributeValue(const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::attributeValue;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addShortref(const InputSource *in)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
size_t length = in->currentTokenLength();
item.nChars = length;
item.type = Markup::shortref;
chars_.append(in->currentTokenStart(), length);
}
void Markup::addEntityStart(const Ptr<EntityOrigin> &origin)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.type = Markup::entityStart;
item.origin = new ConstPtr<Origin>(origin.pointer());
}
void Markup::addEntityEnd()
{
items_.resize(items_.size() + 1);
items_.back().type = Markup::entityEnd;
}
void Markup::addLiteral(const Text &text)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.type = Markup::literal;
item.text = new Text(text);
}
void Markup::addSdLiteral(const SdText &sdText)
{
items_.resize(items_.size() + 1);
MarkupItem &item = items_.back();
item.type = Markup::sdLiteral;
item.sdText = new SdText(sdText);
}
void Markup::changeToAttributeValue(size_t i)
{
ASSERT(items_[i].type == Markup::name);
items_[i].type = Markup::attributeValue;
}
void Markup::changeToSdReservedName(size_t i, Sd::ReservedName rn)
{
ASSERT(items_[i].type == Markup::name);
items_[i].type = Markup::sdReservedName;
items_[i].index = rn;
}
void Markup::swap(Markup &to)
{
chars_.swap(to.chars_);
items_.swap(to.items_);
}
MarkupIter::MarkupIter(const Markup &m)
: chars_(m.chars_.data()),
items_(m.items_.begin()),
nItems_(m.items_.size()),
index_(0),
charIndex_(0)
{
}
void MarkupIter::advance(Location &loc,
const ConstPtr<Syntax> &syntax)
{
switch (items_[index_].type) {
case Markup::delimiter:
loc += syntax->delimGeneral(delimGeneral()).size();
break;
case Markup::refEndRe:
loc += 1;
break;
case Markup::reservedName:
case Markup::sdReservedName:
case Markup::name:
case Markup::nameToken:
case Markup::number:
case Markup::attributeValue:
case Markup::s:
case Markup::shortref:
loc += items_[index_].nChars;
charIndex_ += items_[index_].nChars;
break;
case Markup::comment:
loc += items_[index_].nChars + (2 * syntax->delimGeneral(Syntax::dCOM).size());
charIndex_ += items_[index_].nChars;
break;
case Markup::entityStart:
loc = Location(*items_[index_].origin, 0);
break;
case Markup::entityEnd:
{
ConstPtr<Origin> origin(loc.origin());
loc = origin->parent();
loc += origin->refLength();
}
break;
case Markup::literal:
{
const Text &text = *items_[index_].text;
text.endDelimLocation(loc);
Boolean lita;
text.delimType(lita);
loc
+= syntax->delimGeneral(lita ? Syntax::dLITA : Syntax::dLIT).size();
}
break;
case Markup::sdLiteral:
{
const SdText &text = *items_[index_].sdText;
loc = text.endDelimLocation();
loc += 1;
}
break;
}
index_++;
}
void MarkupIter::advance()
{
switch (items_[index_].type) {
case Markup::reservedName:
case Markup::sdReservedName:
case Markup::name:
case Markup::nameToken:
case Markup::number:
case Markup::attributeValue:
case Markup::s:
case Markup::comment:
case Markup::shortref:
charIndex_ += items_[index_].nChars;
break;
}
index_++;
}
#ifdef SP_NAMESPACE
}
#endif