diff --git a/src/cajun/elements.cpp b/src/cajun/elements.cpp deleted file mode 100644 index 601578ee8..000000000 --- a/src/cajun/elements.cpp +++ /dev/null @@ -1,403 +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 -#include -#include -#include "visitor.h" -#include "reader.h" - -/* - -TODO: -* better documentation - -*/ - -namespace json -{ - - -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 -class UnknownElement::Imp_T : public UnknownElement::Imp -{ -public: - Imp_T(const ElementTypeT& element) : m_Element(element) {} - virtual Imp* Clone() const { return new Imp_T(*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 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 -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 -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; -}; - - - - -UnknownElement::UnknownElement() : m_pImp( new Imp_T( Null() ) ) {} -UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {} -UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T(object) ) {} -UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T(array) ) {} -UnknownElement::UnknownElement(const Number& number) : m_pImp( new Imp_T(number) ) {} -UnknownElement::UnknownElement(const Boolean& boolean) : m_pImp( new Imp_T(boolean) ) {} -UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T(string) ) {} -UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T(null) ) {} - -UnknownElement::~UnknownElement() { delete m_pImp; } - -UnknownElement::operator const Object& () const { return CastTo(); } -UnknownElement::operator const Array& () const { return CastTo(); } -UnknownElement::operator const Number& () const { return CastTo(); } -UnknownElement::operator const Boolean& () const { return CastTo(); } -UnknownElement::operator const String& () const { return CastTo(); } -UnknownElement::operator const Null& () const { return CastTo(); } - -UnknownElement::operator Object& () { return ConvertTo(); } -UnknownElement::operator Array& () { return ConvertTo(); } -UnknownElement::operator Number& () { return ConvertTo(); } -UnknownElement::operator Boolean& () { return ConvertTo(); } -UnknownElement::operator String& () { return ConvertTo(); } -UnknownElement::operator Null& () { return ConvertTo(); } - -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; -} - -UnknownElement& UnknownElement::operator[] (const std::string& key) -{ - // the people want an object. make us one if we aren't already - Object& object = ConvertTo(); - return object[key]; -} - -const UnknownElement& UnknownElement::operator[] (const std::string& key) const -{ - // throws if we aren't an object - const Object& object = CastTo(); - return object[key]; -} - -UnknownElement& UnknownElement::operator[] (size_t index) -{ - // the people want an array. make us one if we aren't already - Array& array = ConvertTo(); - return array[index]; -} - -const UnknownElement& UnknownElement::operator[] (size_t index) const -{ - // throws if we aren't an array - const Array& array = CastTo(); - return array[index]; -} - - -template -const ElementTypeT& UnknownElement::CastTo() const -{ - ConstCastVisitor_T castVisitor; - m_pImp->Accept(castVisitor); - if (castVisitor.m_pElement == 0) - throw Exception("Bad cast"); - return *castVisitor.m_pElement; -} - - - -template -ElementTypeT& UnknownElement::ConvertTo() -{ - CastVisitor_T 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; -} - - -void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); } -void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); } - - -bool UnknownElement::operator == (const UnknownElement& element) const -{ - return m_pImp->Compare(*element.m_pImp); -} - - - -////////////////// -// Object members - - -Object::Member::Member(const std::string& nameIn, const UnknownElement& elementIn) : - name(nameIn), element(elementIn) {} - -bool Object::Member::operator == (const Member& member) const -{ - return name == member.name && - element == member.element; -} - -class Object::Finder : public std::unary_function -{ -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; -}; - - - -Object::iterator Object::Begin() { return m_Members.begin(); } -Object::iterator Object::End() { return m_Members.end(); } -Object::const_iterator Object::Begin() const { return m_Members.begin(); } -Object::const_iterator Object::End() const { return m_Members.end(); } - -size_t Object::Size() const { return m_Members.size(); } -bool Object::Empty() const { return m_Members.empty(); } - -Object::iterator Object::Find(const std::string& name) -{ - return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); -} - -Object::const_iterator Object::Find(const std::string& name) const -{ - return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); -} - -Object::iterator Object::Insert(const Member& member) -{ - return Insert(member, End()); -} - -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; -} - -Object::iterator Object::Erase(iterator itWhere) -{ - return m_Members.erase(itWhere); -} - -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; -} - -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; -} - -void Object::Clear() -{ - m_Members.clear(); -} - -bool Object::operator == (const Object& object) const -{ - return m_Members == object.m_Members; -} - - -///////////////// -// Array members - -Array::iterator Array::Begin() { return m_Elements.begin(); } -Array::iterator Array::End() { return m_Elements.end(); } -Array::const_iterator Array::Begin() const { return m_Elements.begin(); } -Array::const_iterator Array::End() const { return m_Elements.end(); } - -Array::iterator Array::Insert(const UnknownElement& element, iterator itWhere) -{ - return m_Elements.insert(itWhere, element); -} - -Array::iterator Array::Insert(const UnknownElement& element) -{ - return Insert(element, End()); -} - -Array::iterator Array::Erase(iterator itWhere) -{ - return m_Elements.erase(itWhere); -} - -void Array::Resize(size_t newSize) -{ - m_Elements.resize(newSize); -} - -size_t Array::Size() const { return m_Elements.size(); } -bool Array::Empty() const { return m_Elements.empty(); } - -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]; -} - -const UnknownElement& Array::operator[] (size_t index) const -{ - if (index >= m_Elements.size()) - throw Exception("Array out of bounds"); - return m_Elements[index]; -} - -void Array::Clear() { - m_Elements.clear(); -} - -bool Array::operator == (const Array& array) const -{ - return m_Elements == array.m_Elements; -} - - -////////////////// -// Null members - -bool Null::operator == (const Null& trivial) const -{ - return true; -} - - - -} // End namespace diff --git a/src/cajun/elements.h b/src/cajun/elements.h deleted file mode 100644 index 213d79d18..000000000 --- a/src/cajun/elements.h +++ /dev/null @@ -1,337 +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. - -******************************************************************************/ - -#pragma once - -#include -#include -//#include -#include -#include -#include "Config.h" -/* - -TODO: -* better documentation (doxygen?) -* Unicode support -* parent element accessors - -*/ - -namespace json -{ - -namespace Version -{ - enum { MAJOR = 2 }; - enum { MINOR = 0 }; - enum {ENGINEERING = 2 }; -} - -///////////////////////////////////////////////// -// forward declarations (more info further below) - - -class Visitor; -class ConstVisitor; - -template -class TrivialType_T; - -typedef TrivialType_T Number; -typedef TrivialType_T Boolean; -typedef TrivialType_T String; - -class Object; -class Array; -class Null; - - - -///////////////////////////////////////////////////////////////////////// -// Exception - base class for all JSON-related runtime errors - -class Exception : public std::runtime_error -{ -public: - Exception(const std::string& sMessage); -}; - - - - -///////////////////////////////////////////////////////////////////////// -// UnknownElement - provides a typesafe surrogate for any of the JSON- -// sanctioned element types. This class allows the Array and Object -// class to effectively contain a heterogeneous set of child elements. -// The cast operators provide convenient implicit downcasting, while -// preserving dynamic type safety by throwing an exception during a -// a bad cast. -// The object & array element index operators (operators [std::string] -// and [size_t]) provide convenient, quick access to child elements. -// They are a logical extension of the cast operators. These child -// element accesses can be chained together, allowing the following -// (when document structure is well-known): -// String str = objInvoices[1]["Customer"]["Company"]; - - -class UnknownElement -{ -public: - UnknownElement(); - UnknownElement(const UnknownElement& unknown); - UnknownElement(const Object& object); - UnknownElement(const Array& array); - UnknownElement(const Number& number); - UnknownElement(const Boolean& boolean); - UnknownElement(const String& string); - UnknownElement(const Null& null); - - ~UnknownElement(); - - UnknownElement& operator = (const UnknownElement& unknown); - - // implicit cast to actual element type. throws on failure - operator const Object& () const; - operator const Array& () const; - operator const Number& () const; - operator const Boolean& () const; - operator const String& () const; - operator const Null& () const; - - // implicit cast to actual element type. *converts* on failure, and always returns success - operator Object& (); - operator Array& (); - operator Number& (); - operator Boolean& (); - operator String& (); - operator Null& (); - - // provides quick access to children when real element type is object - UnknownElement& operator[] (const std::string& key); - const UnknownElement& operator[] (const std::string& key) const; - - // provides quick access to children when real element type is array - UnknownElement& operator[] (size_t index); - const UnknownElement& operator[] (size_t index) const; - - // implements visitor pattern - void Accept(ConstVisitor& visitor) const; - void Accept(Visitor& visitor); - - // tests equality. first checks type, then value if possible - bool operator == (const UnknownElement& element) const; - -private: - class Imp; - - template - class Imp_T; - - class CastVisitor; - class ConstCastVisitor; - - template - class CastVisitor_T; - - template - class ConstCastVisitor_T; - - template - const ElementTypeT& CastTo() const; - - template - ElementTypeT& ConvertTo(); - - Imp* m_pImp; -}; - - -///////////////////////////////////////////////////////////////////////////////// -// Array - mimics std::deque. The array contents are effectively -// heterogeneous thanks to the ElementUnknown class. push_back has been replaced -// by more generic insert functions. - -class Array -{ -public: - typedef std::deque Elements; - typedef Elements::iterator iterator; - typedef Elements::const_iterator const_iterator; - - iterator Begin(); - iterator End(); - const_iterator Begin() const; - const_iterator End() const; - - iterator Insert(const UnknownElement& element, iterator itWhere); - iterator Insert(const UnknownElement& element); - iterator Erase(iterator itWhere); - void Resize(size_t newSize); - void Clear(); - - size_t Size() const; - bool Empty() const; - - UnknownElement& operator[] (size_t index); - const UnknownElement& operator[] (size_t index) const; - - bool operator == (const Array& array) const; - -private: - Elements m_Elements; -}; - - -///////////////////////////////////////////////////////////////////////////////// -// Object - mimics std::map. The member value -// contents are effectively heterogeneous thanks to the UnknownElement class - -class Object -{ -public: - struct Member { - Member(const std::string& nameIn = std::string(), const UnknownElement& elementIn = UnknownElement()); - - bool operator == (const Member& member) const; - - std::string name; - UnknownElement element; - }; - - typedef std::list Members; // map faster, but does not preserve order - typedef Members::iterator iterator; - typedef Members::const_iterator const_iterator; - - bool operator == (const Object& object) const; - - iterator Begin(); - iterator End(); - const_iterator Begin() const; - const_iterator End() const; - - size_t Size() const; - bool Empty() const; - - iterator Find(const std::string& name); - const_iterator Find(const std::string& name) const; - - iterator Insert(const Member& member); - iterator Insert(const Member& member, iterator itWhere); - iterator Erase(iterator itWhere); - void Clear(); - - UnknownElement& operator [](const std::string& name); - const UnknownElement& operator [](const std::string& name) const; - -private: - class Finder; - - Members m_Members; -}; - - -///////////////////////////////////////////////////////////////////////////////// -// TrivialType_T - class template for encapsulates a simple data type, such as -// a string, number, or boolean. Provides implicit const & noncost cast operators -// for that type, allowing "DataTypeT type = trivialType;" - - -template -class TrivialType_T -{ -public: - TrivialType_T(const DataTypeT& t = DataTypeT()); - - operator DataTypeT&(); - operator const DataTypeT&() const; - - DataTypeT& Value(); - const DataTypeT& Value() const; - - bool operator == (const TrivialType_T& trivial) const; - -private: - DataTypeT m_tValue; -}; - - - -///////////////////////////////////////////////////////////////////////////////// -// Null - doesn't do much of anything but satisfy the JSON spec. It is the default -// element type of UnknownElement - -class Null -{ -public: - bool operator == (const Null& trivial) const; -}; - -//////////////////////// -// TrivialType_T members - -template -TrivialType_T::TrivialType_T(const DataTypeT& t) : - m_tValue(t) {} - -template -TrivialType_T::operator DataTypeT&() -{ - return Value(); -} - -template -TrivialType_T::operator const DataTypeT&() const -{ - return Value(); -} - -template -DataTypeT& TrivialType_T::Value() -{ - return m_tValue; -} - -template -const DataTypeT& TrivialType_T::Value() const -{ - return m_tValue; -} - -template -bool TrivialType_T::operator == (const TrivialType_T& trivial) const -{ - return m_tValue == trivial.m_tValue; -} - - -} // End namespace - - -//#include "elements.inl" diff --git a/src/cajun/reader.cpp b/src/cajun/reader.cpp deleted file mode 100644 index 0a3dfb3ea..000000000 --- a/src/cajun/reader.cpp +++ /dev/null @@ -1,540 +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 -#include -#include -#include "reader.h" - -/* - -TODO: -* better documentation -* unicode character decoding - -*/ - -namespace json -{ - -std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) { - Reader::Read(elementRoot, istr); - return istr; -} - -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; -}; - - -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; -}; - - -Reader::TokenStream::TokenStream(const Tokens& tokens) : - m_Tokens(tokens), - m_itCurrent(tokens.begin()) -{} - -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); -} - -const Reader::Token& Reader::TokenStream::Get() { - const Token& token = Peek(); - ++m_itCurrent; - return token; -} - -bool Reader::TokenStream::EOS() const { - return m_itCurrent == m_Tokens.end(); -} - -/////////////////// -// Reader (finally) - - -void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); } -void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); } -void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); } -void Reader::Read(Number& number, std::istream& istr) { Read_i(number, istr); } -void Reader::Read(Boolean& boolean, std::istream& istr) { Read_i(boolean, istr); } -void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); } -void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); } - - -template -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); - } -} - - -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); - } -} - - -void Reader::EatWhiteSpace(InputStream& inputStream) -{ - while (inputStream.EOS() == false && - ::isspace(inputStream.Peek())) - inputStream.Get(); -} - -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; -} - - -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; - // TPT edit: eat \u0000 characters because the TPT font doesn't support them, and if we ignore it the json can't be parsed - case 'u': { - int eat = 4; - while (eat-- && inputStream.EOS() == false && inputStream.Peek() != '"') - inputStream.Get(); - break; - } - 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; -} - - -std::string Reader::MatchNumber(InputStream& inputStream) -{ - const char sNumericChars[] = "0123456789.eE-+"; - std::set 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; -} - - -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); - } - } -} - - -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); -} - - -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); -} - - -void Reader::Parse(String& string, Reader::TokenStream& tokenStream) -{ - string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream); -} - - -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; -} - - -void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream) -{ - const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream); - boolean = (sValue == "true" ? true : false); -} - - -void Reader::Parse(Null&, Reader::TokenStream& tokenStream) -{ - MatchExpectedToken(Token::TOKEN_NULL, tokenStream); -} - - -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/reader.h b/src/cajun/reader.h deleted file mode 100644 index 451329707..000000000 --- a/src/cajun/reader.h +++ /dev/null @@ -1,148 +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. - -******************************************************************************/ - - - -#pragma once - -#include -#include -#include "elements.h" - -namespace json -{ - -class Reader -{ -public: - // this structure will be reported in one of the exceptions defined below - struct Location - { - Location(); - - unsigned int m_nLine; // document line, zero-indexed - unsigned int m_nLineOffset; // character offset from beginning of line, zero indexed - unsigned int m_nDocOffset; // character offset from entire document, zero indexed - }; - - // thrown during the first phase of reading. generally catches low-level problems such - // as errant characters or corrupt/incomplete documents - class ScanException : public Exception - { - public: - ScanException(const std::string& sMessage, const Reader::Location& locError) : - Exception(sMessage), - m_locError(locError) {} - - Reader::Location m_locError; - }; - - // thrown during the second phase of reading. generally catches higher-level problems such - // as missing commas or brackets - class ParseException : public Exception - { - public: - ParseException(const std::string& sMessage, const Reader::Location& locTokenBegin, const Reader::Location& locTokenEnd) : - Exception(sMessage), - m_locTokenBegin(locTokenBegin), - m_locTokenEnd(locTokenEnd) {} - - Reader::Location m_locTokenBegin; - Reader::Location m_locTokenEnd; - }; - - - // if you know what the document looks like, call one of these... - static void Read(Object& object, std::istream& istr); - static void Read(Array& array, std::istream& istr); - static void Read(String& string, std::istream& istr); - static void Read(Number& number, std::istream& istr); - static void Read(Boolean& boolean, std::istream& istr); - static void Read(Null& null, std::istream& istr); - - // ...otherwise, if you don't know, call this & visit it - static void Read(UnknownElement& elementRoot, std::istream& istr); - -private: - struct Token - { - enum Type - { - TOKEN_OBJECT_BEGIN, // { - TOKEN_OBJECT_END, // } - TOKEN_ARRAY_BEGIN, // [ - TOKEN_ARRAY_END, // ] - TOKEN_NEXT_ELEMENT, // , - TOKEN_MEMBER_ASSIGN, // : - TOKEN_STRING, // "xxx" - TOKEN_NUMBER, // [+/-]000.000[e[+/-]000] - TOKEN_BOOLEAN, // true -or- false - TOKEN_NULL, // null - }; - - Type nType; - std::string sValue; - - // for malformed file debugging - Reader::Location locBegin; - Reader::Location locEnd; - }; - - class InputStream; - class TokenStream; - typedef std::vector Tokens; - - template - static void Read_i(ElementTypeT& element, std::istream& istr); - - // scanning istream into token sequence - void Scan(Tokens& tokens, InputStream& inputStream); - - void EatWhiteSpace(InputStream& inputStream); - std::string MatchString(InputStream& inputStream); - std::string MatchNumber(InputStream& inputStream); - std::string MatchExpectedString(InputStream& inputStream, const std::string& sExpected); - - // parsing token sequence into element structure - void Parse(UnknownElement& element, TokenStream& tokenStream); - void Parse(Object& object, TokenStream& tokenStream); - void Parse(Array& array, TokenStream& tokenStream); - void Parse(String& string, TokenStream& tokenStream); - void Parse(Number& number, TokenStream& tokenStream); - void Parse(Boolean& boolean, TokenStream& tokenStream); - void Parse(Null& null, TokenStream& tokenStream); - - const std::string& MatchExpectedToken(Token::Type nExpected, TokenStream& tokenStream); -}; - - -} // End namespace - - -//#include "reader.inl" diff --git a/src/cajun/visitor.h b/src/cajun/visitor.h deleted file mode 100644 index a06299d10..000000000 --- a/src/cajun/visitor.h +++ /dev/null @@ -1,65 +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. - -******************************************************************************/ - -#pragma once - -#include "elements.h" - -namespace json -{ - - -class Visitor -{ -public: - virtual ~Visitor() {} - - virtual void Visit(Array& array) = 0; - virtual void Visit(Object& object) = 0; - virtual void Visit(Number& number) = 0; - virtual void Visit(String& string) = 0; - virtual void Visit(Boolean& boolean) = 0; - virtual void Visit(Null& null) = 0; -}; - -class ConstVisitor -{ -public: - virtual ~ConstVisitor() {} - - virtual void Visit(const Array& array) = 0; - virtual void Visit(const Object& object) = 0; - virtual void Visit(const Number& number) = 0; - virtual void Visit(const String& string) = 0; - virtual void Visit(const Boolean& boolean) = 0; - virtual void Visit(const Null& null) = 0; -}; - - -} // End namespace diff --git a/src/cajun/writer.cpp b/src/cajun/writer.cpp deleted file mode 100644 index 31974f8ad..000000000 --- a/src/cajun/writer.cpp +++ /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 -#include -#include "writer.h" - -/* - -TODO: -* better documentation -* unicode character encoding - -*/ - -namespace json -{ - - -void Writer::Write(const UnknownElement& elementRoot, std::ostream& ostr) { Write_i(elementRoot, ostr); } -void Writer::Write(const Object& object, std::ostream& ostr) { Write_i(object, ostr); } -void Writer::Write(const Array& array, std::ostream& ostr) { Write_i(array, ostr); } -void Writer::Write(const Number& number, std::ostream& ostr) { Write_i(number, ostr); } -void Writer::Write(const String& string, std::ostream& ostr) { Write_i(string, ostr); } -void Writer::Write(const Boolean& boolean, std::ostream& ostr) { Write_i(boolean, ostr); } -void Writer::Write(const Null& null, std::ostream& ostr) { Write_i(null, ostr); } - - -Writer::Writer(std::ostream& ostr) : - m_ostr(ostr), - m_nTabDepth(0) -{} - -template -void Writer::Write_i(const ElementTypeT& element, std::ostream& ostr) -{ - Writer writer(ostr); - writer.Write_i(element); - ostr.flush(); // all done -} - -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') << ']'; - } -} - -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') << '}'; - } -} - -void Writer::Write_i(const Number& numberElement) -{ - m_ostr << std::setprecision(20) << numberElement.Value(); -} - -void Writer::Write_i(const Boolean& booleanElement) -{ - m_ostr << (booleanElement.Value() ? "true" : "false"); -} - -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 << '"'; -} - -void Writer::Write_i(const Null& ) -{ - m_ostr << "null"; -} - -void Writer::Write_i(const UnknownElement& unknown) -{ - unknown.Accept(*this); -} - -void Writer::Visit(const Array& array) { Write_i(array); } -void Writer::Visit(const Object& object) { Write_i(object); } -void Writer::Visit(const Number& number) { Write_i(number); } -void Writer::Visit(const String& string) { Write_i(string); } -void Writer::Visit(const Boolean& boolean) { Write_i(boolean); } -void Writer::Visit(const Null& null) { Write_i(null); } - - - -} // End namespace diff --git a/src/cajun/writer.h b/src/cajun/writer.h deleted file mode 100644 index 2ac410a9c..000000000 --- a/src/cajun/writer.h +++ /dev/null @@ -1,78 +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. - -******************************************************************************/ - -#pragma once - -#include "elements.h" -#include "visitor.h" - -namespace json -{ - -class Writer : private ConstVisitor -{ -public: - static void Write(const Object& object, std::ostream& ostr); - static void Write(const Array& array, std::ostream& ostr); - static void Write(const String& string, std::ostream& ostr); - static void Write(const Number& number, std::ostream& ostr); - static void Write(const Boolean& boolean, std::ostream& ostr); - static void Write(const Null& null, std::ostream& ostr); - static void Write(const UnknownElement& elementRoot, std::ostream& ostr); - -private: - Writer(std::ostream& ostr); - - template - static void Write_i(const ElementTypeT& element, std::ostream& ostr); - - void Write_i(const Object& object); - void Write_i(const Array& array); - void Write_i(const String& string); - void Write_i(const Number& number); - void Write_i(const Boolean& boolean); - void Write_i(const Null& null); - void Write_i(const UnknownElement& unknown); - - 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); - - std::ostream& m_ostr; - int m_nTabDepth; -}; - - -} // End namespace - - -//#include "writer.inl"