summaryrefslogtreecommitdiff
path: root/src/cajun
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-02-12 15:09:25 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-02-12 15:09:25 (GMT)
commit5546f7d01e87a8fcbd8ea5c9e13162ccd474d7e8 (patch)
treee9f70416adf08092eee325ca0d3f2e6bca38e936 /src/cajun
parentec6d1012b263049241984dfc96fae37f4280e7eb (diff)
downloadpowder-5546f7d01e87a8fcbd8ea5c9e13162ccd474d7e8.zip
powder-5546f7d01e87a8fcbd8ea5c9e13162ccd474d7e8.tar.gz
Fixed some lua methods, set decorations enabled by default, allow toggling of decorations with ctrl+b, saving and loading of render, display and colour modes for the renderer
Diffstat (limited to 'src/cajun')
-rw-r--r--src/cajun/elements.inl442
-rw-r--r--src/cajun/reader.inl533
-rw-r--r--src/cajun/writer.inl178
3 files changed, 0 insertions, 1153 deletions
diff --git a/src/cajun/elements.inl b/src/cajun/elements.inl
deleted file mode 100644
index dbfbf2a..0000000
--- a/src/cajun/elements.inl
+++ /dev/null
@@ -1,442 +0,0 @@
-/******************************************************************************
-
-Copyright (c) 2009-2010, Terry Caton
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the projecct nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#include "visitor.h"
-#include "reader.h"
-#include <cassert>
-#include <algorithm>
-#include <map>
-
-/*
-
-TODO:
-* better documentation
-
-*/
-
-namespace json
-{
-
-
-inline Exception::Exception(const std::string& sMessage) :
- std::runtime_error(sMessage) {}
-
-
-/////////////////////////
-// UnknownElement members
-
-class UnknownElement::Imp
-{
-public:
- virtual ~Imp() {}
- virtual Imp* Clone() const = 0;
-
- virtual bool Compare(const Imp& imp) const = 0;
-
- virtual void Accept(ConstVisitor& visitor) const = 0;
- virtual void Accept(Visitor& visitor) = 0;
-};
-
-
-template <typename ElementTypeT>
-class UnknownElement::Imp_T : public UnknownElement::Imp
-{
-public:
- Imp_T(const ElementTypeT& element) : m_Element(element) {}
- virtual Imp* Clone() const { return new Imp_T<ElementTypeT>(*this); }
-
- virtual void Accept(ConstVisitor& visitor) const { visitor.Visit(m_Element); }
- virtual void Accept(Visitor& visitor) { visitor.Visit(m_Element); }
-
- virtual bool Compare(const Imp& imp) const
- {
- ConstCastVisitor_T<ElementTypeT> castVisitor;
- imp.Accept(castVisitor);
- return castVisitor.m_pElement &&
- m_Element == *castVisitor.m_pElement;
- }
-
-private:
- ElementTypeT m_Element;
-};
-
-
-class UnknownElement::ConstCastVisitor : public ConstVisitor
-{
- virtual void Visit(const Array& array) {}
- virtual void Visit(const Object& object) {}
- virtual void Visit(const Number& number) {}
- virtual void Visit(const String& string) {}
- virtual void Visit(const Boolean& boolean) {}
- virtual void Visit(const Null& null) {}
-};
-
-template <typename ElementTypeT>
-class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor
-{
-public:
- ConstCastVisitor_T() : m_pElement(0) {}
- virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
- const ElementTypeT* m_pElement;
-};
-
-
-class UnknownElement::CastVisitor : public Visitor
-{
- virtual void Visit(Array& array) {}
- virtual void Visit(Object& object) {}
- virtual void Visit(Number& number) {}
- virtual void Visit(String& string) {}
- virtual void Visit(Boolean& boolean) {}
- virtual void Visit(Null& null) {}
-};
-
-template <typename ElementTypeT>
-class UnknownElement::CastVisitor_T : public CastVisitor
-{
-public:
- CastVisitor_T() : m_pElement(0) {}
- virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
- ElementTypeT* m_pElement;
-};
-
-
-
-
-inline UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {}
-inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {}
-inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {}
-inline UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T<Array>(array) ) {}
-inline UnknownElement::UnknownElement(const Number& number) : m_pImp( new Imp_T<Number>(number) ) {}
-inline UnknownElement::UnknownElement(const Boolean& boolean) : m_pImp( new Imp_T<Boolean>(boolean) ) {}
-inline UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T<String>(string) ) {}
-inline UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T<Null>(null) ) {}
-
-inline UnknownElement::~UnknownElement() { delete m_pImp; }
-
-inline UnknownElement::operator const Object& () const { return CastTo<Object>(); }
-inline UnknownElement::operator const Array& () const { return CastTo<Array>(); }
-inline UnknownElement::operator const Number& () const { return CastTo<Number>(); }
-inline UnknownElement::operator const Boolean& () const { return CastTo<Boolean>(); }
-inline UnknownElement::operator const String& () const { return CastTo<String>(); }
-inline UnknownElement::operator const Null& () const { return CastTo<Null>(); }
-
-inline UnknownElement::operator Object& () { return ConvertTo<Object>(); }
-inline UnknownElement::operator Array& () { return ConvertTo<Array>(); }
-inline UnknownElement::operator Number& () { return ConvertTo<Number>(); }
-inline UnknownElement::operator Boolean& () { return ConvertTo<Boolean>(); }
-inline UnknownElement::operator String& () { return ConvertTo<String>(); }
-inline UnknownElement::operator Null& () { return ConvertTo<Null>(); }
-
-inline UnknownElement& UnknownElement::operator = (const UnknownElement& unknown)
-{
- // always check for this
- if (&unknown != this)
- {
- // we might be copying from a subtree of ourselves. delete the old imp
- // only after the clone operation is complete. yes, this could be made
- // more efficient, but isn't worth the complexity
- Imp* pOldImp = m_pImp;
- m_pImp = unknown.m_pImp->Clone();
- delete pOldImp;
- }
-
- return *this;
-}
-
-inline UnknownElement& UnknownElement::operator[] (const std::string& key)
-{
- // the people want an object. make us one if we aren't already
- Object& object = ConvertTo<Object>();
- return object[key];
-}
-
-inline const UnknownElement& UnknownElement::operator[] (const std::string& key) const
-{
- // throws if we aren't an object
- const Object& object = CastTo<Object>();
- return object[key];
-}
-
-inline UnknownElement& UnknownElement::operator[] (size_t index)
-{
- // the people want an array. make us one if we aren't already
- Array& array = ConvertTo<Array>();
- return array[index];
-}
-
-inline const UnknownElement& UnknownElement::operator[] (size_t index) const
-{
- // throws if we aren't an array
- const Array& array = CastTo<Array>();
- return array[index];
-}
-
-
-template <typename ElementTypeT>
-const ElementTypeT& UnknownElement::CastTo() const
-{
- ConstCastVisitor_T<ElementTypeT> castVisitor;
- m_pImp->Accept(castVisitor);
- if (castVisitor.m_pElement == 0)
- throw Exception("Bad cast");
- return *castVisitor.m_pElement;
-}
-
-
-
-template <typename ElementTypeT>
-ElementTypeT& UnknownElement::ConvertTo()
-{
- CastVisitor_T<ElementTypeT> castVisitor;
- m_pImp->Accept(castVisitor);
- if (castVisitor.m_pElement == 0)
- {
- // we're not the right type. fix it & try again
- *this = ElementTypeT();
- m_pImp->Accept(castVisitor);
- }
-
- return *castVisitor.m_pElement;
-}
-
-
-inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); }
-inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); }
-
-
-inline bool UnknownElement::operator == (const UnknownElement& element) const
-{
- return m_pImp->Compare(*element.m_pImp);
-}
-
-
-
-//////////////////
-// Object members
-
-
-inline Object::Member::Member(const std::string& nameIn, const UnknownElement& elementIn) :
- name(nameIn), element(elementIn) {}
-
-inline bool Object::Member::operator == (const Member& member) const
-{
- return name == member.name &&
- element == member.element;
-}
-
-class Object::Finder : public std::unary_function<Object::Member, bool>
-{
-public:
- Finder(const std::string& name) : m_name(name) {}
- bool operator () (const Object::Member& member) {
- return member.name == m_name;
- }
-
-private:
- std::string m_name;
-};
-
-
-
-inline Object::iterator Object::Begin() { return m_Members.begin(); }
-inline Object::iterator Object::End() { return m_Members.end(); }
-inline Object::const_iterator Object::Begin() const { return m_Members.begin(); }
-inline Object::const_iterator Object::End() const { return m_Members.end(); }
-
-inline size_t Object::Size() const { return m_Members.size(); }
-inline bool Object::Empty() const { return m_Members.empty(); }
-
-inline Object::iterator Object::Find(const std::string& name)
-{
- return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
-}
-
-inline Object::const_iterator Object::Find(const std::string& name) const
-{
- return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
-}
-
-inline Object::iterator Object::Insert(const Member& member)
-{
- return Insert(member, End());
-}
-
-inline Object::iterator Object::Insert(const Member& member, iterator itWhere)
-{
- iterator it = Find(member.name);
- if (it != m_Members.end())
- throw Exception(std::string("Object member already exists: ") + member.name);
-
- it = m_Members.insert(itWhere, member);
- return it;
-}
-
-inline Object::iterator Object::Erase(iterator itWhere)
-{
- return m_Members.erase(itWhere);
-}
-
-inline UnknownElement& Object::operator [](const std::string& name)
-{
-
- iterator it = Find(name);
- if (it == m_Members.end())
- {
- Member member(name);
- it = Insert(member, End());
- }
- return it->element;
-}
-
-inline const UnknownElement& Object::operator [](const std::string& name) const
-{
- const_iterator it = Find(name);
- if (it == End())
- throw Exception(std::string("Object member not found: ") + name);
- return it->element;
-}
-
-inline void Object::Clear()
-{
- m_Members.clear();
-}
-
-inline bool Object::operator == (const Object& object) const
-{
- return m_Members == object.m_Members;
-}
-
-
-/////////////////
-// Array members
-
-inline Array::iterator Array::Begin() { return m_Elements.begin(); }
-inline Array::iterator Array::End() { return m_Elements.end(); }
-inline Array::const_iterator Array::Begin() const { return m_Elements.begin(); }
-inline Array::const_iterator Array::End() const { return m_Elements.end(); }
-
-inline Array::iterator Array::Insert(const UnknownElement& element, iterator itWhere)
-{
- return m_Elements.insert(itWhere, element);
-}
-
-inline Array::iterator Array::Insert(const UnknownElement& element)
-{
- return Insert(element, End());
-}
-
-inline Array::iterator Array::Erase(iterator itWhere)
-{
- return m_Elements.erase(itWhere);
-}
-
-inline void Array::Resize(size_t newSize)
-{
- m_Elements.resize(newSize);
-}
-
-inline size_t Array::Size() const { return m_Elements.size(); }
-inline bool Array::Empty() const { return m_Elements.empty(); }
-
-inline UnknownElement& Array::operator[] (size_t index)
-{
- size_t nMinSize = index + 1; // zero indexed
- if (m_Elements.size() < nMinSize)
- m_Elements.resize(nMinSize);
- return m_Elements[index];
-}
-
-inline const UnknownElement& Array::operator[] (size_t index) const
-{
- if (index >= m_Elements.size())
- throw Exception("Array out of bounds");
- return m_Elements[index];
-}
-
-inline void Array::Clear() {
- m_Elements.clear();
-}
-
-inline bool Array::operator == (const Array& array) const
-{
- return m_Elements == array.m_Elements;
-}
-
-
-////////////////////////
-// TrivialType_T members
-
-template <typename DataTypeT>
-TrivialType_T<DataTypeT>::TrivialType_T(const DataTypeT& t) :
- m_tValue(t) {}
-
-template <typename DataTypeT>
-TrivialType_T<DataTypeT>::operator DataTypeT&()
-{
- return Value();
-}
-
-template <typename DataTypeT>
-TrivialType_T<DataTypeT>::operator const DataTypeT&() const
-{
- return Value();
-}
-
-template <typename DataTypeT>
-DataTypeT& TrivialType_T<DataTypeT>::Value()
-{
- return m_tValue;
-}
-
-template <typename DataTypeT>
-const DataTypeT& TrivialType_T<DataTypeT>::Value() const
-{
- return m_tValue;
-}
-
-template <typename DataTypeT>
-bool TrivialType_T<DataTypeT>::operator == (const TrivialType_T<DataTypeT>& trivial) const
-{
- return m_tValue == trivial.m_tValue;
-}
-
-
-
-//////////////////
-// Null members
-
-inline bool Null::operator == (const Null& trivial) const
-{
- return true;
-}
-
-
-
-} // End namespace
diff --git a/src/cajun/reader.inl b/src/cajun/reader.inl
deleted file mode 100644
index 47311ad..0000000
--- a/src/cajun/reader.inl
+++ /dev/null
@@ -1,533 +0,0 @@
-/******************************************************************************
-
-Copyright (c) 2009-2010, Terry Caton
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the projecct nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#include <cassert>
-#include <set>
-#include <sstream>
-
-/*
-
-TODO:
-* better documentation
-* unicode character decoding
-
-*/
-
-namespace json
-{
-
-inline std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) {
- Reader::Read(elementRoot, istr);
- return istr;
-}
-
-inline Reader::Location::Location() :
- m_nLine(0),
- m_nLineOffset(0),
- m_nDocOffset(0)
-{}
-
-
-//////////////////////
-// Reader::InputStream
-
-class Reader::InputStream // would be cool if we could inherit from std::istream & override "get"
-{
-public:
- InputStream(std::istream& iStr) :
- m_iStr(iStr) {}
-
- // protect access to the input stream, so we can keeep track of document/line offsets
- char Get(); // big, define outside
- char Peek() {
- assert(m_iStr.eof() == false); // enforce reading of only valid stream data
- return m_iStr.peek();
- }
-
- bool EOS() {
- m_iStr.peek(); // apparently eof flag isn't set until a character read is attempted. whatever.
- return m_iStr.eof();
- }
-
- const Location& GetLocation() const { return m_Location; }
-
-private:
- std::istream& m_iStr;
- Location m_Location;
-};
-
-
-inline char Reader::InputStream::Get()
-{
- assert(m_iStr.eof() == false); // enforce reading of only valid stream data
- char c = m_iStr.get();
-
- ++m_Location.m_nDocOffset;
- if (c == '\n') {
- ++m_Location.m_nLine;
- m_Location.m_nLineOffset = 0;
- }
- else {
- ++m_Location.m_nLineOffset;
- }
-
- return c;
-}
-
-
-
-//////////////////////
-// Reader::TokenStream
-
-class Reader::TokenStream
-{
-public:
- TokenStream(const Tokens& tokens);
-
- const Token& Peek();
- const Token& Get();
-
- bool EOS() const;
-
-private:
- const Tokens& m_Tokens;
- Tokens::const_iterator m_itCurrent;
-};
-
-
-inline Reader::TokenStream::TokenStream(const Tokens& tokens) :
- m_Tokens(tokens),
- m_itCurrent(tokens.begin())
-{}
-
-inline const Reader::Token& Reader::TokenStream::Peek() {
- if (EOS())
- {
- const Token& lastToken = *m_Tokens.rbegin();
- std::string sMessage = "Unexpected end of token stream";
- throw ParseException(sMessage, lastToken.locBegin, lastToken.locEnd); // nowhere to point to
- }
- return *(m_itCurrent);
-}
-
-inline const Reader::Token& Reader::TokenStream::Get() {
- const Token& token = Peek();
- ++m_itCurrent;
- return token;
-}
-
-inline bool Reader::TokenStream::EOS() const {
- return m_itCurrent == m_Tokens.end();
-}
-
-///////////////////
-// Reader (finally)
-
-
-inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); }
-inline void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); }
-inline void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); }
-inline void Reader::Read(Number& number, std::istream& istr) { Read_i(number, istr); }
-inline void Reader::Read(Boolean& boolean, std::istream& istr) { Read_i(boolean, istr); }
-inline void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); }
-inline void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); }
-
-
-template <typename ElementTypeT>
-void Reader::Read_i(ElementTypeT& element, std::istream& istr)
-{
- Reader reader;
-
- Tokens tokens;
- InputStream inputStream(istr);
- reader.Scan(tokens, inputStream);
-
- TokenStream tokenStream(tokens);
- reader.Parse(element, tokenStream);
-
- if (tokenStream.EOS() == false)
- {
- const Token& token = tokenStream.Peek();
- std::string sMessage = std::string("Expected End of token stream; found ") + token.sValue;
- throw ParseException(sMessage, token.locBegin, token.locEnd);
- }
-}
-
-
-inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
-{
- while (EatWhiteSpace(inputStream), // ignore any leading white space...
- inputStream.EOS() == false) // ...before checking for EOS
- {
- // if all goes well, we'll create a token each pass
- Token token;
- token.locBegin = inputStream.GetLocation();
-
- // gives us null-terminated string
- char sChar = inputStream.Peek();
- switch (sChar)
- {
- case '{':
- token.sValue = MatchExpectedString(inputStream, "{");
- token.nType = Token::TOKEN_OBJECT_BEGIN;
- break;
-
- case '}':
- token.sValue = MatchExpectedString(inputStream, "}");
- token.nType = Token::TOKEN_OBJECT_END;
- break;
-
- case '[':
- token.sValue = MatchExpectedString(inputStream, "[");
- token.nType = Token::TOKEN_ARRAY_BEGIN;
- break;
-
- case ']':
- token.sValue = MatchExpectedString(inputStream, "]");
- token.nType = Token::TOKEN_ARRAY_END;
- break;
-
- case ',':
- token.sValue = MatchExpectedString(inputStream, ",");
- token.nType = Token::TOKEN_NEXT_ELEMENT;
- break;
-
- case ':':
- token.sValue = MatchExpectedString(inputStream, ":");
- token.nType = Token::TOKEN_MEMBER_ASSIGN;
- break;
-
- case '"':
- token.sValue = MatchString(inputStream);
- token.nType = Token::TOKEN_STRING;
- break;
-
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- token.sValue = MatchNumber(inputStream);
- token.nType = Token::TOKEN_NUMBER;
- break;
-
- case 't':
- token.sValue = MatchExpectedString(inputStream, "true");
- token.nType = Token::TOKEN_BOOLEAN;
- break;
-
- case 'f':
- token.sValue = MatchExpectedString(inputStream, "false");
- token.nType = Token::TOKEN_BOOLEAN;
- break;
-
- case 'n':
- token.sValue = MatchExpectedString(inputStream, "null");
- token.nType = Token::TOKEN_NULL;
- break;
-
- default:
- {
- std::string sErrorMessage = std::string("Unexpected character in stream: ") + sChar;
- throw ScanException(sErrorMessage, inputStream.GetLocation());
- }
- }
-
- token.locEnd = inputStream.GetLocation();
- tokens.push_back(token);
- }
-}
-
-
-inline void Reader::EatWhiteSpace(InputStream& inputStream)
-{
- while (inputStream.EOS() == false &&
- ::isspace(inputStream.Peek()))
- inputStream.Get();
-}
-
-inline std::string Reader::MatchExpectedString(InputStream& inputStream, const std::string& sExpected)
-{
- std::string::const_iterator it(sExpected.begin()),
- itEnd(sExpected.end());
- for ( ; it != itEnd; ++it) {
- if (inputStream.EOS() || // did we reach the end before finding what we're looking for...
- inputStream.Get() != *it) // ...or did we find something different?
- {
- std::string sMessage = std::string("Expected string: ") + sExpected;
- throw ScanException(sMessage, inputStream.GetLocation());
- }
- }
-
- // all's well if we made it here
- return sExpected;
-}
-
-
-inline std::string Reader::MatchString(InputStream& inputStream)
-{
- MatchExpectedString(inputStream, "\"");
-
- std::string string;
- while (inputStream.EOS() == false &&
- inputStream.Peek() != '"')
- {
- char c = inputStream.Get();
-
- // escape?
- if (c == '\\' &&
- inputStream.EOS() == false) // shouldn't have reached the end yet
- {
- c = inputStream.Get();
- switch (c) {
- case '/': string.push_back('/'); break;
- case '"': string.push_back('"'); break;
- case '\\': string.push_back('\\'); break;
- case 'b': string.push_back('\b'); break;
- case 'f': string.push_back('\f'); break;
- case 'n': string.push_back('\n'); break;
- case 'r': string.push_back('\r'); break;
- case 't': string.push_back('\t'); break;
- //case 'u': string.push_back('\u'); break; // TODO: what do we do with this?
- default: {
- std::string sMessage = std::string("Unrecognized escape sequence found in string: \\") + c;
- throw ScanException(sMessage, inputStream.GetLocation());
- }
- }
- }
- else {
- string.push_back(c);
- }
- }
-
- // eat the last '"' that we just peeked
- MatchExpectedString(inputStream, "\"");
-
- // all's well if we made it here
- return string;
-}
-
-
-inline std::string Reader::MatchNumber(InputStream& inputStream)
-{
- const char sNumericChars[] = "0123456789.eE-+";
- std::set<char> numericChars;
- numericChars.insert(sNumericChars, sNumericChars + sizeof(sNumericChars));
-
- std::string sNumber;
- while (inputStream.EOS() == false &&
- numericChars.find(inputStream.Peek()) != numericChars.end())
- {
- sNumber.push_back(inputStream.Get());
- }
-
- return sNumber;
-}
-
-
-inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream)
-{
- const Token& token = tokenStream.Peek();
- switch (token.nType) {
- case Token::TOKEN_OBJECT_BEGIN:
- {
- // implicit non-const cast will perform conversion for us (if necessary)
- Object& object = element;
- Parse(object, tokenStream);
- break;
- }
-
- case Token::TOKEN_ARRAY_BEGIN:
- {
- Array& array = element;
- Parse(array, tokenStream);
- break;
- }
-
- case Token::TOKEN_STRING:
- {
- String& string = element;
- Parse(string, tokenStream);
- break;
- }
-
- case Token::TOKEN_NUMBER:
- {
- Number& number = element;
- Parse(number, tokenStream);
- break;
- }
-
- case Token::TOKEN_BOOLEAN:
- {
- Boolean& boolean = element;
- Parse(boolean, tokenStream);
- break;
- }
-
- case Token::TOKEN_NULL:
- {
- Null& null = element;
- Parse(null, tokenStream);
- break;
- }
-
- default:
- {
- std::string sMessage = std::string("Unexpected token: ") + token.sValue;
- throw ParseException(sMessage, token.locBegin, token.locEnd);
- }
- }
-}
-
-
-inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
-{
- MatchExpectedToken(Token::TOKEN_OBJECT_BEGIN, tokenStream);
-
- bool bContinue = (tokenStream.EOS() == false &&
- tokenStream.Peek().nType != Token::TOKEN_OBJECT_END);
- while (bContinue)
- {
- Object::Member member;
-
- // first the member name. save the token in case we have to throw an exception
- const Token& tokenName = tokenStream.Peek();
- member.name = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
-
- // ...then the key/value separator...
- MatchExpectedToken(Token::TOKEN_MEMBER_ASSIGN, tokenStream);
-
- // ...then the value itself (can be anything).
- Parse(member.element, tokenStream);
-
- // try adding it to the object (this could throw)
- try
- {
- object.Insert(member);
- }
- catch (Exception&)
- {
- // must be a duplicate name
- std::string sMessage = std::string("Duplicate object member token: ") + member.name;
- throw ParseException(sMessage, tokenName.locBegin, tokenName.locEnd);
- }
-
- bContinue = (tokenStream.EOS() == false &&
- tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT);
- if (bContinue)
- MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream);
- }
-
- MatchExpectedToken(Token::TOKEN_OBJECT_END, tokenStream);
-}
-
-
-inline void Reader::Parse(Array& array, Reader::TokenStream& tokenStream)
-{
- MatchExpectedToken(Token::TOKEN_ARRAY_BEGIN, tokenStream);
-
- bool bContinue = (tokenStream.EOS() == false &&
- tokenStream.Peek().nType != Token::TOKEN_ARRAY_END);
- while (bContinue)
- {
- // ...what's next? could be anything
- Array::iterator itElement = array.Insert(UnknownElement());
- UnknownElement& element = *itElement;
- Parse(element, tokenStream);
-
- bContinue = (tokenStream.EOS() == false &&
- tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT);
- if (bContinue)
- MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream);
- }
-
- MatchExpectedToken(Token::TOKEN_ARRAY_END, tokenStream);
-}
-
-
-inline void Reader::Parse(String& string, Reader::TokenStream& tokenStream)
-{
- string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
-}
-
-
-inline void Reader::Parse(Number& number, Reader::TokenStream& tokenStream)
-{
- const Token& currentToken = tokenStream.Peek(); // might need this later for throwing exception
- const std::string& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream);
-
- std::istringstream iStr(sValue);
- double dValue;
- iStr >> dValue;
-
- // did we consume all characters in the token?
- if (iStr.eof() == false)
- {
- char c = iStr.peek();
- std::string sMessage = std::string("Unexpected character in NUMBER token: ") + c;
- throw ParseException(sMessage, currentToken.locBegin, currentToken.locEnd);
- }
-
- number = dValue;
-}
-
-
-inline void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream)
-{
- const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream);
- boolean = (sValue == "true" ? true : false);
-}
-
-
-inline void Reader::Parse(Null&, Reader::TokenStream& tokenStream)
-{
- MatchExpectedToken(Token::TOKEN_NULL, tokenStream);
-}
-
-
-inline const std::string& Reader::MatchExpectedToken(Token::Type nExpected, Reader::TokenStream& tokenStream)
-{
- const Token& token = tokenStream.Get();
- if (token.nType != nExpected)
- {
- std::string sMessage = std::string("Unexpected token: ") + token.sValue;
- throw ParseException(sMessage, token.locBegin, token.locEnd);
- }
-
- return token.sValue;
-}
-
-} // End namespace
diff --git a/src/cajun/writer.inl b/src/cajun/writer.inl
deleted file mode 100644
index 71145da..0000000
--- a/src/cajun/writer.inl
+++ /dev/null
@@ -1,178 +0,0 @@
-/******************************************************************************
-
-Copyright (c) 2009-2010, Terry Caton
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the projecct nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#include "writer.h"
-#include <iostream>
-#include <iomanip>
-
-/*
-
-TODO:
-* better documentation
-* unicode character encoding
-
-*/
-
-namespace json
-{
-
-
-inline void Writer::Write(const UnknownElement& elementRoot, std::ostream& ostr) { Write_i(elementRoot, ostr); }
-inline void Writer::Write(const Object& object, std::ostream& ostr) { Write_i(object, ostr); }
-inline void Writer::Write(const Array& array, std::ostream& ostr) { Write_i(array, ostr); }
-inline void Writer::Write(const Number& number, std::ostream& ostr) { Write_i(number, ostr); }
-inline void Writer::Write(const String& string, std::ostream& ostr) { Write_i(string, ostr); }
-inline void Writer::Write(const Boolean& boolean, std::ostream& ostr) { Write_i(boolean, ostr); }
-inline void Writer::Write(const Null& null, std::ostream& ostr) { Write_i(null, ostr); }
-
-
-inline Writer::Writer(std::ostream& ostr) :
- m_ostr(ostr),
- m_nTabDepth(0)
-{}
-
-template <typename ElementTypeT>
-void Writer::Write_i(const ElementTypeT& element, std::ostream& ostr)
-{
- Writer writer(ostr);
- writer.Write_i(element);
- ostr.flush(); // all done
-}
-
-inline void Writer::Write_i(const Array& array)
-{
- if (array.Empty())
- m_ostr << "[]";
- else
- {
- m_ostr << '[' << std::endl;
- ++m_nTabDepth;
-
- Array::const_iterator it(array.Begin()),
- itEnd(array.End());
- while (it != itEnd) {
- m_ostr << std::string(m_nTabDepth, '\t');
-
- Write_i(*it);
-
- if (++it != itEnd)
- m_ostr << ',';
- m_ostr << std::endl;
- }
-
- --m_nTabDepth;
- m_ostr << std::string(m_nTabDepth, '\t') << ']';
- }
-}
-
-inline void Writer::Write_i(const Object& object)
-{
- if (object.Empty())
- m_ostr << "{}";
- else
- {
- m_ostr << '{' << std::endl;
- ++m_nTabDepth;
-
- Object::const_iterator it(object.Begin()),
- itEnd(object.End());
- while (it != itEnd) {
- m_ostr << std::string(m_nTabDepth, '\t');
-
- Write_i(it->name);
-
- m_ostr << " : ";
- Write_i(it->element);
-
- if (++it != itEnd)
- m_ostr << ',';
- m_ostr << std::endl;
- }
-
- --m_nTabDepth;
- m_ostr << std::string(m_nTabDepth, '\t') << '}';
- }
-}
-
-inline void Writer::Write_i(const Number& numberElement)
-{
- m_ostr << std::setprecision(20) << numberElement.Value();
-}
-
-inline void Writer::Write_i(const Boolean& booleanElement)
-{
- m_ostr << (booleanElement.Value() ? "true" : "false");
-}
-
-inline void Writer::Write_i(const String& stringElement)
-{
- m_ostr << '"';
-
- const std::string& s = stringElement.Value();
- std::string::const_iterator it(s.begin()),
- itEnd(s.end());
- for (; it != itEnd; ++it)
- {
- switch (*it)
- {
- case '"': m_ostr << "\\\""; break;
- case '\\': m_ostr << "\\\\"; break;
- case '\b': m_ostr << "\\b"; break;
- case '\f': m_ostr << "\\f"; break;
- case '\n': m_ostr << "\\n"; break;
- case '\r': m_ostr << "\\r"; break;
- case '\t': m_ostr << "\\t"; break;
- //case '\u': m_ostr << "\\u"; break; // uh...
- default: m_ostr << *it; break;
- }
- }
-
- m_ostr << '"';
-}
-
-inline void Writer::Write_i(const Null& )
-{
- m_ostr << "null";
-}
-
-inline void Writer::Write_i(const UnknownElement& unknown)
-{
- unknown.Accept(*this);
-}
-
-inline void Writer::Visit(const Array& array) { Write_i(array); }
-inline void Writer::Visit(const Object& object) { Write_i(object); }
-inline void Writer::Visit(const Number& number) { Write_i(number); }
-inline void Writer::Visit(const String& string) { Write_i(string); }
-inline void Writer::Visit(const Boolean& boolean) { Write_i(boolean); }
-inline void Writer::Visit(const Null& null) { Write_i(null); }
-
-
-
-} // End namespace