// ---------------------------------------------------------------------------
// - XsoStream.cpp -
// - afnix:xml module - xml/xsm input stream class implementation -
// ---------------------------------------------------------------------------
// - This program is free software; you can redistribute it and/or modify -
// - it provided that this copyright notice is kept intact. -
// - -
// - This program is distributed in the hope that it will be useful, but -
// - without any warranty; without even the implied warranty of -
// - merchantability or fitness for a particular purpose. In no event shall -
// - the copyright holder be liable for any direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software. -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2007 amaury darsch -
// ---------------------------------------------------------------------------
#include "Unicode.hpp"
#include "XsoStream.hpp"
#include "Exception.hpp"
namespace afnix {
// -------------------------------------------------------------------------
// - private section -
// -------------------------------------------------------------------------
// the default xml stream timeout
static const long XSO_STREAM_TOUT = -1L;
// the xml character reference
static const t_quad XSO_CHAR_AM = 0x00000026;
static const t_quad XSO_CHAR_DZ = 0x00000023;
static const t_quad XSO_CHAR_SC = 0x0000003B;
// -------------------------------------------------------------------------
// - class section -
// -------------------------------------------------------------------------
// create a new xml stream
XsoStream::XsoStream (Input* is) {
if (is == nilp) {
throw Exception ("xml-error", "invalid nil input stream");
}
Object::iref (p_is = is);
d_lnum = 1;
d_xbuf.reset ();
}
// destroy this xml stream
XsoStream::~XsoStream (void) {
Object::tref (p_is);
}
// return the current line number
long XsoStream::getlnum (void) const {
return d_lnum;
}
// set the stream encoding mode
void XsoStream::setemod (const String& mode) {
p_is->setemod (mode);
}
// return true if the stream is valid
bool XsoStream::valid (void) const {
return p_is->valid (XSO_STREAM_TOUT);
}
// read the next available character
t_quad XsoStream::rduc (void) {
// check the xml buffer first
if (d_xbuf.empty () == false) {
t_quad c = d_xbuf.read ();
if (c == eolq) d_lnum++;
return c;
}
// check for & character
t_quad c = p_is->rduc ();
if (c != XSO_CHAR_AM) {
if (c == eolq) d_lnum++;
return c;
}
d_xbuf.add (c);
// check for # chracter
c = p_is->rduc ();
if (c == eofq) {
p_is->pushback (c);
c = d_xbuf.read ();
if (c == eolq) d_lnum++;
return c;
}
d_xbuf.add (c);
if (c != XSO_CHAR_DZ) {
c = d_xbuf.read ();
if (c == eolq) d_lnum++;
return c;
}
// accumulate characters until a ; character
s_cref:
c = p_is->rduc ();
switch (c) {
case XSO_CHAR_SC:
c = d_xbuf.tocref ();
d_xbuf.reset ();
return c;
case blkq:
case tabq:
case eolq:
case eofq:
p_is->pushback (c);
c = d_xbuf.read ();
if (c == eolq) d_lnum++;
return c;
default:
d_xbuf.add (c);
goto s_cref;
}
// we should never be here
throw Exception ("internal-error", "out-of-bound rduc with xso stream");
}
// pushback a character
void XsoStream::pushback (const t_quad c) {
if ((c == eolq) && (d_lnum > 1)) d_lnum--;
d_xbuf.pushback (c);
}
}
syntax highlighted by Code2HTML, v. 0.9.1