// ---------------------------------------------------------------------------
// - XsoBuffer.cpp -
// - afnix:xml module - xsm character buffer 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 "Vector.hpp"
#include "Utility.hpp"
#include "Unicode.hpp"
#include "XsoBuffer.hpp"
#include "Exception.hpp"
namespace afnix {
// -------------------------------------------------------------------------
// - private section -
// -------------------------------------------------------------------------
// default buffer size
static const long XSO_BUFFER_SIZE = 1024;
// the xso special characters
static const t_quad XSO_CHAR_AM = 0x00000026; // &
static const t_quad XSO_CHAR_NS = 0x00000023; // #
// -------------------------------------------------------------------------
// - class section -
// -------------------------------------------------------------------------
// create a new buffer class with a default size of 1024 characters
XsoBuffer::XsoBuffer (void) {
d_size = XSO_BUFFER_SIZE;
p_ubuf = new t_quad[d_size];
d_blen = 0;
d_lnum = 0;
for (long i = 0; i < d_size; i++) p_ubuf[i] = nilq;
}
// create a new buffer with a string
XsoBuffer::XsoBuffer (const String& xval) {
d_size = XSO_BUFFER_SIZE;
p_ubuf = new t_quad[d_size];
d_blen = 0;
d_lnum = 0;
for (long i = 0; i < d_size; i++) p_ubuf[i] = nilq;
add (xval);
}
// copy construct this buffer
XsoBuffer::XsoBuffer (const XsoBuffer& that){
d_size = that.d_size;
p_ubuf = new t_quad[d_size];
d_blen = that.d_blen;
d_lnum = that.d_lnum;
for (long i = 0; i < d_blen; i++) p_ubuf[i] = that.p_ubuf[i];
}
// destroy this buffer
XsoBuffer::~XsoBuffer (void) {
delete [] p_ubuf;
}
// assign a buffer to this one
XsoBuffer& XsoBuffer::operator = (const XsoBuffer& that){
// check for equality
if (this == &that) return *this;
// clean the old buffer
delete [] p_ubuf;
// copy the data
d_size = that.d_size;
p_ubuf = new t_quad[d_size];
d_blen = that.d_blen;
d_lnum = that.d_lnum;
for (long i = 0; i < d_blen; i++) p_ubuf[i] = that.p_ubuf[i];
// this the new buffer
return *this;
}
// reset this buffer but do not change the size
void XsoBuffer::reset (void) {
d_blen = 0;
d_lnum = 0;
}
// clear this buffer content
void XsoBuffer::clear (void) {
d_blen = 0;
for (long i = 0; i < d_size; i++) p_ubuf[i] = nilq;
}
// begin a new session with a line number
void XsoBuffer::begin (const long lnum) {
reset ();
setlnum (lnum);
}
// set the current line number
void XsoBuffer::setlnum (const long lnum) {
d_lnum = lnum;
}
// return the current line number
long XsoBuffer::getlnum (void) const {
return d_lnum;
}
// return the length of this buffer
long XsoBuffer::length (void) const {
return d_blen;
}
// return true if the buffer is empty
bool XsoBuffer::empty (void) const {
return (d_blen == 0);
}
// add a character in this buffer
void XsoBuffer::add (const t_quad c) {
// first check if we are at the buffer end
if (d_blen == d_size) {
long size = d_size * 2;
t_quad* buf = new t_quad[size];
for (long i = 0; i < d_blen; i++) buf[i] = p_ubuf[i];
delete [] p_ubuf;
d_size = size;
p_ubuf = buf;
}
p_ubuf[d_blen++] = c;
}
// add a string to this buffer
void XsoBuffer::add (const String& s) {
long len = s.length ();
for (long i = 0; i < len; i++) add (s[i]);
}
// get the next unicode character but do not remove it
t_quad XsoBuffer::get (void) const {
return (d_blen == 0) ? nilq : p_ubuf[0];
}
// read a character in this buffer
t_quad XsoBuffer::read (void) {
// check for empty buffer character
if (d_blen == 0) return nilq;
// get value and shift
long ulen = d_blen - 1;
t_quad result = p_ubuf[0];
for (long i = 0; i < ulen; i++) p_ubuf[i] = p_ubuf[i+1];
p_ubuf[ulen] = nilq;
d_blen = ulen;
return result;
}
// pushback a character in this buffer
void XsoBuffer::pushback (const t_quad c) {
// first check if we are at the buffer end
if (d_blen == d_size) {
long size = d_size * 2;
t_quad* buf = new t_quad[size];
for (long i = 0; i < d_blen; i++) buf[i] = p_ubuf[i];
delete [] p_ubuf;
d_size = size;
p_ubuf = buf;
}
// shift the buffer by one
for (long i = d_blen; i > 0; i--) p_ubuf[i] = p_ubuf[i-1];
// pushback the character
p_ubuf[0] = c;
d_blen++;
}
// pushback a string in this buffer
void XsoBuffer::pushback (const String& s) {
long len = s.length ();
if (len == 0) return;
for (long i = len - 1; i >= 0; i--) pushback (s[i]);
}
// return the buffer content as a valid string
String XsoBuffer::tostring (void) const {
// mark the end of string
t_quad* ubuf = Unicode::strdup (p_ubuf, d_blen);
// convert the string
String result = ubuf;
delete [] ubuf;
return result;
}
// return the buffer content as a character reference
t_quad XsoBuffer::tocref (void) const {
// check for valid buffer starter
if (d_blen < 2) {
throw Exception ("xso-error", "invalid character reference buffer");
}
if (p_ubuf[0] != XSO_CHAR_AM) {
throw Exception ("xso-error", "invalid character reference buffer");
}
if (p_ubuf[1] != XSO_CHAR_NS) {
throw Exception ("xml-error", "invalid character reference buffer");
}
// mark the end of string
t_quad* ubuf = Unicode::strdup (&p_ubuf[2], d_blen-2);
// get the string and check
String xref = ubuf;
delete [] ubuf;
// check for non nil buffer
if (xref.isnil () == true) {
throw Exception ("xso-error", "invalid nil character reference");
}
// prepare the value string
String xbuf;
// check for hexadecimal notation
if (xref[0] == Unicode::toquad ('x')) {
xbuf = "0";
xbuf += xref;
} else {
xbuf = xref;
}
// convert the string
t_quad cval = (t_quad) Utility::tointeger (xbuf);
return cval;
}
// compare the last characater
bool XsoBuffer::islast (const t_quad c) const {
// check for nil
if (d_blen == 0) return false;
return (p_ubuf[d_blen-1] == c);
}
}
syntax highlighted by Code2HTML, v. 0.9.1