From 469bbcf0701e1eb8a6670c23145b0da87357e178 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 25 Mar 2012 20:00:08 +0000 Subject: Code is all reorganized. We're about ready to release. I should write up a little explenation of the arrangement. --- src/experimental/xmlreader.cpp | 173 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 src/experimental/xmlreader.cpp (limited to 'src/experimental/xmlreader.cpp') diff --git a/src/experimental/xmlreader.cpp b/src/experimental/xmlreader.cpp new file mode 100644 index 0000000..ba7fb3d --- /dev/null +++ b/src/experimental/xmlreader.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2007-2011 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/xmlreader.h" +#include "bu/stream.h" + +namespace Bu { subExceptionDef( XmlException ) } + +Bu::XmlReader::XmlReader( Stream &rInput ) : + rInput( rInput ), + iCurToken( 0 ), + iNextToken( 0 ), + bIgnoreWS( true ) +{ + nextToken(); + stDocument(); +} + +Bu::XmlReader::~XmlReader() +{ +} + +void Bu::XmlReader::fillBuffer() +{ + if( rInput.isEos() ) + return; + char buf[1024]; + int iSize = rInput.read( buf, 1024 ); + sBuf.append( buf, iSize ); +} + +void Bu::XmlReader::cleanupBuffer( int iUsed ) +{ + for( int j = 0; j < iUsed; j++ ) + { + if( sBuf[j] == '\n' ) + { + spNextToken.iLine++; + spNextToken.iChar = 1; + } + else + { + spNextToken.iChar++; + } + } + + printf("--Deleting %d bytes from front of buffer.\n", iUsed ); + sBuf.trimFront( iUsed ); +} + +int Bu::XmlReader::nextToken() +{ + fillBuffer(); + + int iUsed = 1; + + iCurToken = iNextToken; + spCurToken = spNextToken; + + switch( sBuf[0] ) + { + case '<': + if( !strncmp( sBuf.getStr(), "' ) + { + iNextToken = tokXmlDeclEnd; + iUsed = 2; + } + else + { + iNextToken = '?'; + } + break; + + case ' ': + case '\t': + case '\n': + case '\r': + for( int j = 1;; j++ ) + { + if( j == sBuf.getSize() ) + { + if( rInput.isEos() ) + error("Reached end of input while waiting for whitespace to end."); + + fillBuffer(); + } + if( sBuf[j] == ' ' || sBuf[j] == '\t' || + sBuf[j] == '\n' || sBuf[j] == '\r' ) + iUsed++; + else + break; + } + sStr.clear(); + sStr.append( sBuf, iUsed ); + iNextToken = tokWS; + break; + + case '=': + iNextToken = sBuf[0]; + break; + + default: + if( (sBuf[0] >= 'a' && sBuf[0] <= 'z') || + (sBuf[0] >= 'A' && sBuf[0] <= 'Z') ) + { + for( int j = 1;; j++ ) + { + if( j == sBuf.getSize() ) + { + if( rInput.isEos() ) + error("Reached end of input while waiting for a string to end."); + + fillBuffer(); + } + if( (sBuf[j] >= 'a' && sBuf[j] <= 'z') || + (sBuf[j] >= 'A' && sBuf[j] <= 'Z') ) + iUsed++; + else + break; + } + sStr.clear(); + sStr.append( sBuf, iUsed ); + iNextToken = tokIdent; + } + } + + cleanupBuffer( iUsed ); + + return iCurToken; +} + +void Bu::XmlReader::error( const char *sMessage ) +{ + throw Bu::XmlException("%d:%d: %s", + spCurToken.iLine, spCurToken.iChar, sMessage ); +} + +void Bu::XmlReader::stDocument() +{ + stProlog(); +} + +void Bu::XmlReader::stProlog() +{ + stXmlDecl(); +} + +void Bu::XmlReader::stXmlDecl() +{ + if( nextToken() != tokXmlDeclHead ) + error("You must begin your xml file with a declaration: "); + if( nextToken() != tokIdent ) + error("A version comes first!"); + if( sStr != "version" ) + error("No, a version!"); +} + -- cgit v1.2.3