diff --git a/src/exp.h b/src/exp.h index d3e2fb6..e878a80 100644 --- a/src/exp.h +++ b/src/exp.h @@ -3,7 +3,6 @@ #include "regex.h" #include #include -#include #include "stream.h" namespace YAML @@ -24,10 +23,10 @@ namespace YAML // actual tags - const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx(EOF) || RegEx()); - const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx(EOF) || RegEx()); + const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx()); + const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx()); const RegEx DocIndicator = DocStart || DocEnd; - const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx(EOF)); + const RegEx BlockEntry = RegEx('-') + BlankOrBreak; const RegEx Key = RegEx('?'), KeyInFlow = RegEx('?') + BlankOrBreak; const RegEx Value = RegEx(':') + BlankOrBreak, diff --git a/src/regex.cpp b/src/regex.cpp index ea6e4ee..3982301 100644 --- a/src/regex.cpp +++ b/src/regex.cpp @@ -90,12 +90,12 @@ namespace YAML return Match(str) >= 0; } - bool RegEx::Matches(std::istream& in) const + bool RegEx::Matches(const char *buffer) const { - return Match(in) >= 0; + return Match(buffer) >= 0; } - bool RegEx::Matches(Stream& in) const + bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; } @@ -115,9 +115,9 @@ namespace YAML } // Match - int RegEx::Match(Stream& in) const + int RegEx::Match(const Stream& in) const { - return Match(in.stream()); + return Match(in.current()); } // Match @@ -126,19 +126,12 @@ namespace YAML // . Note: the istream is not a const reference, but we guarantee // that the pointer will be in the same spot, and we'll clear its // flags before we end. - int RegEx::Match(std::istream& in) const + int RegEx::Match(const char *buffer) const { if(!m_pOp) return -1; - int pos = in.tellg(); - int ret = m_pOp->Match(in, *this); - - // reset input stream! - in.clear(); - in.seekg(pos); - - return ret; + return m_pOp->Match(buffer, *this); } RegEx operator ! (const RegEx& ex) @@ -184,9 +177,9 @@ namespace YAML } - int RegEx::MatchOperator::Match(std::istream& in, const RegEx& regex) const + int RegEx::MatchOperator::Match(const char *buffer, const RegEx& regex) const { - if(!in || in.peek() != regex.m_a) + if(buffer[0] != regex.m_a) return -1; return 1; } @@ -199,9 +192,9 @@ namespace YAML return 1; } - int RegEx::RangeOperator::Match(std::istream& in, const RegEx& regex) const + int RegEx::RangeOperator::Match(const char *buffer, const RegEx& regex) const { - if(!in || regex.m_a > in.peek() || regex.m_z < in.peek()) + if(regex.m_a > buffer[0] || regex.m_z < buffer[0]) return -1; return 1; } @@ -217,10 +210,10 @@ namespace YAML return -1; } - int RegEx::OrOperator::Match(std::istream& in, const RegEx& regex) const + int RegEx::OrOperator::Match(const char *buffer, const RegEx& regex) const { for(unsigned i=0;i= 0) return n; } @@ -244,11 +237,11 @@ namespace YAML return first; } - int RegEx::AndOperator::Match(std::istream& in, const RegEx& regex) const + int RegEx::AndOperator::Match(const char *buffer, const RegEx& regex) const { int first = -1; for(unsigned i=0;i= 0) + if(regex.m_params[0].Match(buffer) >= 0) return -1; return 1; } @@ -289,16 +282,15 @@ namespace YAML return offset; } - int RegEx::SeqOperator::Match(std::istream& in, const RegEx& regex) const + int RegEx::SeqOperator::Match(const char *buffer, const RegEx& regex) const { int offset = 0; for(unsigned i=0;i #include -#include namespace YAML { @@ -19,37 +18,37 @@ namespace YAML struct Operator { virtual ~Operator() {} virtual int Match(const std::string& str, const RegEx& regex) const = 0; - virtual int Match(std::istream& in, const RegEx& regex) const = 0; + virtual int Match(const char *buffer, const RegEx& regex) const = 0; }; struct MatchOperator: public Operator { virtual int Match(const std::string& str, const RegEx& regex) const; - virtual int Match(std::istream& in, const RegEx& regex) const; + virtual int Match(const char *buffer, const RegEx& regex) const; }; struct RangeOperator: public Operator { virtual int Match(const std::string& str, const RegEx& regex) const; - virtual int Match(std::istream& in, const RegEx& regex) const; + virtual int Match(const char *buffer, const RegEx& regex) const; }; struct OrOperator: public Operator { virtual int Match(const std::string& str, const RegEx& regex) const; - virtual int Match(std::istream& in, const RegEx& regex) const; + virtual int Match(const char *buffer, const RegEx& regex) const; }; struct AndOperator: public Operator { virtual int Match(const std::string& str, const RegEx& regex) const; - virtual int Match(std::istream& in, const RegEx& regex) const; + virtual int Match(const char *buffer, const RegEx& regex) const; }; struct NotOperator: public Operator { virtual int Match(const std::string& str, const RegEx& regex) const; - virtual int Match(std::istream& in, const RegEx& regex) const; + virtual int Match(const char *buffer, const RegEx& regex) const; }; struct SeqOperator: public Operator { virtual int Match(const std::string& str, const RegEx& regex) const; - virtual int Match(std::istream& in, const RegEx& regex) const; + virtual int Match(const char *buffer, const RegEx& regex) const; }; public: @@ -66,11 +65,11 @@ namespace YAML bool Matches(char ch) const; bool Matches(const std::string& str) const; - bool Matches(std::istream& in) const; - bool Matches(Stream& in) const; + bool Matches(const char *buffer) const; + bool Matches(const Stream& in) const; int Match(const std::string& str) const; - int Match(std::istream& in) const; - int Match(Stream& in) const; + int Match(const char *buffer) const; + int Match(const Stream& in) const; friend RegEx operator ! (const RegEx& ex); friend RegEx operator || (const RegEx& ex1, const RegEx& ex2); diff --git a/src/scanner.cpp b/src/scanner.cpp index 5aed8d5..1d148d9 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -100,7 +100,7 @@ namespace YAML // ***** // end of stream - if(INPUT.peek() == EOF) + if(!INPUT) return EndStream(); if(INPUT.column == 0 && INPUT.peek() == Keys::Directive) diff --git a/src/simplekey.cpp b/src/simplekey.cpp index f971c54..667d683 100644 --- a/src/simplekey.cpp +++ b/src/simplekey.cpp @@ -32,7 +32,7 @@ namespace YAML // and saves it on a stack. void Scanner::InsertSimpleKey() { - SimpleKey key(INPUT.pos(), INPUT.line, INPUT.column, m_flowLevel); + SimpleKey key(INPUT.pos, INPUT.line, INPUT.column, m_flowLevel); // first add a map start, if necessary key.pMapStart = PushIndentTo(INPUT.column, false); @@ -78,7 +78,7 @@ namespace YAML isValid = false; // also needs to be less than 1024 characters and inline - if(INPUT.line != key.line || INPUT.pos() - key.pos > 1024) + if(INPUT.line != key.line || INPUT.pos - key.pos > 1024) isValid = false; // invalidate key diff --git a/src/stream.cpp b/src/stream.cpp index b388899..dc5a3ad 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -4,26 +4,39 @@ namespace YAML { - int Stream::pos() const + Stream::Stream(std::istream& input): buffer(0), pos(0), line(0), column(0), size(0) { - return input.tellg(); + std::streambuf *pBuf = input.rdbuf(); + + // store entire file in buffer + size = pBuf->pubseekoff(0, std::ios::end, std::ios::in); + pBuf->pubseekpos(0, std::ios::in); + buffer = new char[size]; + pBuf->sgetn(buffer, size); } - + + Stream::~Stream() + { + delete [] buffer; + } + + char Stream::peek() { - return input.peek(); + return buffer[pos]; } - Stream::operator bool() + Stream::operator bool() const { - return input.good(); + return pos < size; } // get // . Extracts a character from the stream and updates our position char Stream::get() { - char ch = input.get(); + char ch = buffer[pos]; + pos++; column++; if(ch == '\n') { column = 0; diff --git a/src/stream.h b/src/stream.h index 0276134..5f12f79 100644 --- a/src/stream.h +++ b/src/stream.h @@ -5,21 +5,24 @@ namespace YAML { - struct Stream + class Stream { - Stream(std::istream& input_): input(input_), line(0), column(0) {} + public: + Stream(std::istream& input); + ~Stream(); - int pos() const; - operator bool(); - bool operator !() { return !(*this); } + operator bool() const; + bool operator !() const { return !static_cast (*this); } - std::istream& stream() const { return input; } + const char *current() const { return buffer + pos; } char peek(); char get(); std::string get(int n); void eat(int n = 1); - std::istream& input; - int line, column; + int pos, line, column, size; + + private: + char *buffer; }; } diff --git a/yaml-reader/main.cpp b/yaml-reader/main.cpp index e5833ba..00e47ed 100644 --- a/yaml-reader/main.cpp +++ b/yaml-reader/main.cpp @@ -7,20 +7,13 @@ void run() { std::ifstream fin("tests/test.yaml"); + YAML::Parser parser(fin); - try { - YAML::Parser parser(fin); + while(parser) + { YAML::Node doc; parser.GetNextDocument(doc); - - std::cout << "name: " << doc["name"] << "\n"; - std::cout << "age: " << doc["age"] << "\n"; - } catch(YAML::TypedKeyNotFound & e) { - std::cout << "Key '" << e.key << "' not found at line " << e.line+1 << ", col " << e.column+1 << "\n"; - } catch(YAML::KeyNotFound& e) { - std::cout << "Key not found at line " << e.line+1 << ", col " << e.column+1 << "\n"; - } catch(YAML::Exception& e) { - std::cout << "Error at line " << e.line+1 << ", col " << e.column+1 << ": " << e.msg << "\n"; + std::cout << doc; } } diff --git a/yaml-reader/tests/test.yaml b/yaml-reader/tests/test.yaml index c266abf..32d3ff8 100644 --- a/yaml-reader/tests/test.yaml +++ b/yaml-reader/tests/test.yaml @@ -1,3 +1 @@ -name: Brett Favre -position: QB -teams: [ Falcons, Packers, Jets ] \ No newline at end of file +- test