forked from mia/Aegisub
Move cajun implementations from .inl files included by the headers to .cpp files
Originally committed to SVN as r6004.
This commit is contained in:
parent
c601351a50
commit
a78417177a
13 changed files with 263 additions and 264 deletions
|
@ -505,32 +505,32 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Cajun"
|
Name="Cajun"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\libaegisub\common\cajun\elements.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\cajun\elements.h"
|
RelativePath="..\..\libaegisub\include\libaegisub\cajun\elements.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\cajun\elements.inl"
|
RelativePath="..\..\libaegisub\common\cajun\reader.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\cajun\reader.h"
|
RelativePath="..\..\libaegisub\include\libaegisub\cajun\reader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\cajun\reader.inl"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\cajun\visitor.h"
|
RelativePath="..\..\libaegisub\include\libaegisub\cajun\visitor.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\cajun\writer.h"
|
RelativePath="..\..\libaegisub\common\cajun\writer.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\cajun\writer.inl"
|
RelativePath="..\..\libaegisub\include\libaegisub\cajun\writer.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
|
|
@ -83,6 +83,9 @@
|
||||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
<PrecompiledHeaderFile>lagi_pre.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>lagi_pre.h</PrecompiledHeaderFile>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="$(SrcDir)common\cajun\elements.cpp" />
|
||||||
|
<ClCompile Include="$(SrcDir)common\cajun\reader.cpp" />
|
||||||
|
<ClCompile Include="$(SrcDir)common\cajun\writer.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)common\charset.cpp" />
|
<ClCompile Include="$(SrcDir)common\charset.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)common\charset_conv.cpp" />
|
<ClCompile Include="$(SrcDir)common\charset_conv.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)common\charset_ucd.cpp" />
|
<ClCompile Include="$(SrcDir)common\charset_ucd.cpp" />
|
||||||
|
@ -107,8 +110,5 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="$(SrcDir)include\libaegisub\charsets.def" />
|
<None Include="$(SrcDir)include\libaegisub\charsets.def" />
|
||||||
<None Include="$(SrcDir)include\libaegisub\cajun\elements.inl" />
|
|
||||||
<None Include="$(SrcDir)include\libaegisub\cajun\reader.inl" />
|
|
||||||
<None Include="$(SrcDir)include\libaegisub\cajun\writer.inl" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -193,19 +193,19 @@
|
||||||
<ClCompile Include="$(SrcDir)common\util.cpp">
|
<ClCompile Include="$(SrcDir)common\util.cpp">
|
||||||
<Filter>Source Files\Common</Filter>
|
<Filter>Source Files\Common</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="$(SrcDir)common\cajun\elements.cpp">
|
||||||
|
<Filter>cajun</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="$(SrcDir)common\cajun\reader.cpp">
|
||||||
|
<Filter>cajun</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="$(SrcDir)common\cajun\writer.cpp">
|
||||||
|
<Filter>cajun</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="$(SrcDir)include\libaegisub\charsets.def">
|
<None Include="$(SrcDir)include\libaegisub\charsets.def">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(SrcDir)include\libaegisub\cajun\elements.inl">
|
|
||||||
<Filter>cajun</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="$(SrcDir)include\libaegisub\cajun\reader.inl">
|
|
||||||
<Filter>cajun</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="$(SrcDir)include\libaegisub\cajun\writer.inl">
|
|
||||||
<Filter>cajun</Filter>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -20,6 +20,9 @@ common/charset_conv.o: CXXFLAGS += $(CFLAGS_ICONV)
|
||||||
unix/path.o: CXXFLAGS += -DP_DATA=\"$(P_DATA)\" -DP_DOC=\"$(P_DOC)\" -DP_LOCALE=\"$(P_LOCALE)\"
|
unix/path.o: CXXFLAGS += -DP_DATA=\"$(P_DATA)\" -DP_DOC=\"$(P_DOC)\" -DP_LOCALE=\"$(P_LOCALE)\"
|
||||||
|
|
||||||
SRC = \
|
SRC = \
|
||||||
|
common/cajun/elements.cpp \
|
||||||
|
common/cajun/reader.cpp \
|
||||||
|
common/cajun/writer.cpp \
|
||||||
common/charset.cpp \
|
common/charset.cpp \
|
||||||
common/charset_conv.cpp \
|
common/charset_conv.cpp \
|
||||||
common/charset_ucd.cpp \
|
common/charset_ucd.cpp \
|
||||||
|
|
174
aegisub/libaegisub/common/cajun/elements.cpp
Normal file
174
aegisub/libaegisub/common/cajun/elements.cpp
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/**********************************************
|
||||||
|
|
||||||
|
License: BSD
|
||||||
|
Project Webpage: http://cajun-jsonapi.sourceforge.net/
|
||||||
|
Author: Terry Caton
|
||||||
|
***********************************************/
|
||||||
|
|
||||||
|
#include "libaegisub/cajun/elements.h"
|
||||||
|
|
||||||
|
#include "libaegisub/cajun/visitor.h"
|
||||||
|
|
||||||
|
#ifndef LAGI_PRE
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace json
|
||||||
|
{
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// UnknownElement members
|
||||||
|
class CastVisitor : public ConstVisitor
|
||||||
|
{
|
||||||
|
virtual void Visit(const Array&) { }
|
||||||
|
virtual void Visit(const Object&) { }
|
||||||
|
virtual void Visit(const Number&) { }
|
||||||
|
virtual void Visit(const String&) { }
|
||||||
|
virtual void Visit(const Boolean&) { }
|
||||||
|
virtual void Visit(const Null&) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ElementTypeT>
|
||||||
|
class CastVisitor_T : public CastVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const ElementTypeT *element;
|
||||||
|
CastVisitor_T() : element(0) { }
|
||||||
|
|
||||||
|
// we don't know what this is, but it overrides one of the base's no-op functions
|
||||||
|
void Visit(const ElementTypeT& element) { this->element = &element; }
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
CastVisitor_T<ElementTypeT> castVisitor;
|
||||||
|
imp.Accept(castVisitor);
|
||||||
|
return castVisitor.element && m_Element == *castVisitor.element;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ElementTypeT m_Element;
|
||||||
|
};
|
||||||
|
|
||||||
|
UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {}
|
||||||
|
UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {}
|
||||||
|
UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {}
|
||||||
|
UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T<Array>(array) ) {}
|
||||||
|
UnknownElement::UnknownElement(double number) : m_pImp( new Imp_T<Number>(number) ) {}
|
||||||
|
UnknownElement::UnknownElement(int number) : m_pImp( new Imp_T<Number>(number) ) {}
|
||||||
|
UnknownElement::UnknownElement(long number) : m_pImp( new Imp_T<Number>(number) ) {}
|
||||||
|
UnknownElement::UnknownElement(bool boolean) : m_pImp( new Imp_T<Boolean>(boolean) ) {}
|
||||||
|
UnknownElement::UnknownElement(const char *string) : m_pImp( new Imp_T<String>(string) ) {}
|
||||||
|
UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T<String>(string) ) {}
|
||||||
|
UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T<Null>(null) ) {}
|
||||||
|
|
||||||
|
UnknownElement::~UnknownElement() { delete m_pImp; }
|
||||||
|
|
||||||
|
UnknownElement::operator const Object& () const { return CastTo<Object>(); }
|
||||||
|
UnknownElement::operator const Array& () const { return CastTo<Array>(); }
|
||||||
|
UnknownElement::operator const Number& () const { return CastTo<Number>(); }
|
||||||
|
UnknownElement::operator const Boolean& () const { return CastTo<Boolean>(); }
|
||||||
|
UnknownElement::operator const String& () const { return CastTo<String>(); }
|
||||||
|
UnknownElement::operator const Null& () const { return CastTo<Null>(); }
|
||||||
|
|
||||||
|
UnknownElement::operator Object& () { return ConvertTo<Object>(); }
|
||||||
|
UnknownElement::operator Array& () { return ConvertTo<Array>(); }
|
||||||
|
UnknownElement::operator Number& () { return ConvertTo<Number>(); }
|
||||||
|
UnknownElement::operator Boolean& () { return ConvertTo<Boolean>(); }
|
||||||
|
UnknownElement::operator String& () { return ConvertTo<String>(); }
|
||||||
|
UnknownElement::operator Null& () { return ConvertTo<Null>(); }
|
||||||
|
|
||||||
|
UnknownElement& UnknownElement::operator = (const UnknownElement& unknown)
|
||||||
|
{
|
||||||
|
delete m_pImp;
|
||||||
|
m_pImp = unknown.m_pImp->Clone();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnknownElement& UnknownElement::operator[] (const std::string& key)
|
||||||
|
{
|
||||||
|
// the people want an object. make us one if we aren't already
|
||||||
|
return ConvertTo<Object>()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
const UnknownElement& UnknownElement::operator[] (const std::string& key) const
|
||||||
|
{
|
||||||
|
// throws if we aren't an object
|
||||||
|
Object const& obj = CastTo<Object>();
|
||||||
|
Object::const_iterator it = obj.find(key);
|
||||||
|
if (it == obj.end())
|
||||||
|
throw Exception("Object member not found: " + key);
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnknownElement& UnknownElement::operator[] (size_t index)
|
||||||
|
{
|
||||||
|
// the people want an array. make us one if we aren't already
|
||||||
|
return ConvertTo<Array>()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const UnknownElement& UnknownElement::operator[] (size_t index) const
|
||||||
|
{
|
||||||
|
// throws if we aren't an array
|
||||||
|
return CastTo<Array>()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ElementTypeT>
|
||||||
|
const ElementTypeT& UnknownElement::CastTo() const
|
||||||
|
{
|
||||||
|
CastVisitor_T<ElementTypeT> castVisitor;
|
||||||
|
m_pImp->Accept(castVisitor);
|
||||||
|
if (!castVisitor.element)
|
||||||
|
throw Exception("Bad cast");
|
||||||
|
return *castVisitor.element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ElementTypeT>
|
||||||
|
ElementTypeT& UnknownElement::ConvertTo()
|
||||||
|
{
|
||||||
|
CastVisitor_T<ElementTypeT> castVisitor;
|
||||||
|
Accept(castVisitor);
|
||||||
|
if (!castVisitor.element)
|
||||||
|
{
|
||||||
|
// we're not the right type. fix it & try again
|
||||||
|
*this = ElementTypeT();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace
|
|
@ -6,9 +6,13 @@ Author: Terry Caton
|
||||||
|
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
||||||
|
#include "libaegisub/cajun/reader.h"
|
||||||
|
|
||||||
|
#ifndef LAGI_PRE
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -21,13 +25,12 @@ TODO:
|
||||||
namespace json
|
namespace json
|
||||||
{
|
{
|
||||||
|
|
||||||
|
std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) {
|
||||||
inline std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) {
|
|
||||||
Reader::Read(elementRoot, istr);
|
Reader::Read(elementRoot, istr);
|
||||||
return istr;
|
return istr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Reader::Location::Location() :
|
Reader::Location::Location() :
|
||||||
m_nLine(0),
|
m_nLine(0),
|
||||||
m_nLineOffset(0),
|
m_nLineOffset(0),
|
||||||
m_nDocOffset(0)
|
m_nDocOffset(0)
|
||||||
|
@ -102,13 +105,13 @@ public:
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// Reader (finally)
|
// Reader (finally)
|
||||||
inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); }
|
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); }
|
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); }
|
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); }
|
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); }
|
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); }
|
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); }
|
void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); }
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
||||||
|
@ -129,7 +132,7 @@ void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
||||||
{
|
{
|
||||||
while (EatWhiteSpace(inputStream), !inputStream.EOS())
|
while (EatWhiteSpace(inputStream), !inputStream.EOS())
|
||||||
{
|
{
|
||||||
|
@ -227,13 +230,13 @@ inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::EatWhiteSpace(InputStream& inputStream)
|
void Reader::EatWhiteSpace(InputStream& inputStream)
|
||||||
{
|
{
|
||||||
while (!inputStream.EOS() && ::isspace(inputStream.Peek()))
|
while (!inputStream.EOS() && ::isspace(inputStream.Peek()))
|
||||||
inputStream.Get();
|
inputStream.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Reader::MatchExpectedString(const std::string& sExpected, InputStream& inputStream)
|
void Reader::MatchExpectedString(const std::string& sExpected, InputStream& inputStream)
|
||||||
{
|
{
|
||||||
std::string::const_iterator it(sExpected.begin()),
|
std::string::const_iterator it(sExpected.begin()),
|
||||||
itEnd(sExpected.end());
|
itEnd(sExpected.end());
|
||||||
|
@ -249,7 +252,7 @@ inline void Reader::MatchExpectedString(const std::string& sExpected, InputStrea
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::MatchString(std::string& string, InputStream& inputStream)
|
void Reader::MatchString(std::string& string, InputStream& inputStream)
|
||||||
{
|
{
|
||||||
MatchExpectedString("\"", inputStream);
|
MatchExpectedString("\"", inputStream);
|
||||||
|
|
||||||
|
@ -287,7 +290,7 @@ inline void Reader::MatchString(std::string& string, InputStream& inputStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::MatchNumber(std::string& sNumber, InputStream& inputStream)
|
void Reader::MatchNumber(std::string& sNumber, InputStream& inputStream)
|
||||||
{
|
{
|
||||||
const char sNumericChars[] = "0123456789.eE-+";
|
const char sNumericChars[] = "0123456789.eE-+";
|
||||||
std::set<char> numericChars;
|
std::set<char> numericChars;
|
||||||
|
@ -301,7 +304,7 @@ inline void Reader::MatchNumber(std::string& sNumber, InputStream& inputStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream)
|
void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
if (tokenStream.EOS()) {
|
if (tokenStream.EOS()) {
|
||||||
throw ParseException("Unexpected end of token stream", Location(), Location()); // nowhere to point to
|
throw ParseException("Unexpected end of token stream", Location(), Location()); // nowhere to point to
|
||||||
|
@ -360,7 +363,7 @@ inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
|
void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
MatchExpectedToken(Token::TOKEN_OBJECT_BEGIN, tokenStream);
|
MatchExpectedToken(Token::TOKEN_OBJECT_BEGIN, tokenStream);
|
||||||
|
|
||||||
|
@ -396,7 +399,7 @@ inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Array& array, Reader::TokenStream& tokenStream)
|
void Reader::Parse(Array& array, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
MatchExpectedToken(Token::TOKEN_ARRAY_BEGIN, tokenStream);
|
MatchExpectedToken(Token::TOKEN_ARRAY_BEGIN, tokenStream);
|
||||||
|
|
||||||
|
@ -419,13 +422,13 @@ inline void Reader::Parse(Array& array, Reader::TokenStream& tokenStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(String& string, Reader::TokenStream& tokenStream)
|
void Reader::Parse(String& string, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Number& number, Reader::TokenStream& tokenStream)
|
void Reader::Parse(Number& number, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
const Token& currentToken = tokenStream.Peek(); // might need this later for throwing exception
|
const Token& currentToken = tokenStream.Peek(); // might need this later for throwing exception
|
||||||
const std::string& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream);
|
const std::string& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream);
|
||||||
|
@ -444,20 +447,20 @@ inline void Reader::Parse(Number& number, Reader::TokenStream& tokenStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream)
|
void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream);
|
const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream);
|
||||||
boolean = (sValue == "true");
|
boolean = (sValue == "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(Null&, Reader::TokenStream& tokenStream)
|
void Reader::Parse(Null&, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
MatchExpectedToken(Token::TOKEN_NULL, tokenStream);
|
MatchExpectedToken(Token::TOKEN_NULL, tokenStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& Reader::MatchExpectedToken(Token::Type nExpected, Reader::TokenStream& tokenStream)
|
const std::string& Reader::MatchExpectedToken(Token::Type nExpected, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
if (tokenStream.EOS())
|
if (tokenStream.EOS())
|
||||||
{
|
{
|
|
@ -6,9 +6,12 @@ Author: Terry Caton
|
||||||
|
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
||||||
#include "writer.h"
|
#include "libaegisub/cajun/writer.h"
|
||||||
|
|
||||||
|
#ifndef LAGI_PRE
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -21,20 +24,12 @@ TODO:
|
||||||
namespace json
|
namespace json
|
||||||
{
|
{
|
||||||
|
|
||||||
inline Writer::Writer(std::ostream& ostr) :
|
Writer::Writer(std::ostream& ostr) :
|
||||||
m_ostr(ostr),
|
m_ostr(ostr),
|
||||||
m_nTabDepth(0)
|
m_nTabDepth(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
void Writer::Write(const Array& array)
|
||||||
void Writer::Write(const ElementTypeT& element, std::ostream& ostr)
|
|
||||||
{
|
|
||||||
Writer writer(ostr);
|
|
||||||
writer.Write(element);
|
|
||||||
ostr.flush(); // all done
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Writer::Write(const Array& array)
|
|
||||||
{
|
{
|
||||||
if (array.empty())
|
if (array.empty())
|
||||||
m_ostr << "[]";
|
m_ostr << "[]";
|
||||||
|
@ -59,7 +54,7 @@ inline void Writer::Write(const Array& array)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Writer::Write(const Object& object)
|
void Writer::Write(const Object& object)
|
||||||
{
|
{
|
||||||
if (object.empty())
|
if (object.empty())
|
||||||
m_ostr << "{}";
|
m_ostr << "{}";
|
||||||
|
@ -83,17 +78,17 @@ inline void Writer::Write(const Object& object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Writer::Write(const Number& numberElement)
|
void Writer::Write(const Number& numberElement)
|
||||||
{
|
{
|
||||||
m_ostr << std::setprecision(20) << numberElement;
|
m_ostr << std::setprecision(20) << numberElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Writer::Write(const Boolean& booleanElement)
|
void Writer::Write(const Boolean& booleanElement)
|
||||||
{
|
{
|
||||||
m_ostr << (booleanElement ? "true" : "false");
|
m_ostr << (booleanElement ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Writer::Write(const String& stringElement)
|
void Writer::Write(const String& stringElement)
|
||||||
{
|
{
|
||||||
m_ostr << '"';
|
m_ostr << '"';
|
||||||
|
|
||||||
|
@ -118,21 +113,21 @@ inline void Writer::Write(const String& stringElement)
|
||||||
m_ostr << '"';
|
m_ostr << '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Writer::Write(const Null& )
|
void Writer::Write(const Null& )
|
||||||
{
|
{
|
||||||
m_ostr << "null";
|
m_ostr << "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Writer::Write(const UnknownElement& unknown)
|
void Writer::Write(const UnknownElement& unknown)
|
||||||
{
|
{
|
||||||
unknown.Accept(*this);
|
unknown.Accept(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Writer::Visit(const Array& array) { Write(array); }
|
void Writer::Visit(const Array& array) { Write(array); }
|
||||||
inline void Writer::Visit(const Object& object) { Write(object); }
|
void Writer::Visit(const Object& object) { Write(object); }
|
||||||
inline void Writer::Visit(const Number& number) { Write(number); }
|
void Writer::Visit(const Number& number) { Write(number); }
|
||||||
inline void Writer::Visit(const String& string) { Write(string); }
|
void Writer::Visit(const String& string) { Write(string); }
|
||||||
inline void Writer::Visit(const Boolean& boolean) { Write(boolean); }
|
void Writer::Visit(const Boolean& boolean) { Write(boolean); }
|
||||||
inline void Writer::Visit(const Null& null) { Write(null); }
|
void Writer::Visit(const Null& null) { Write(null); }
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
|
@ -8,11 +8,13 @@ Author: Terry Caton
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef LAGI_PRE
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace json
|
namespace json
|
||||||
{
|
{
|
||||||
|
@ -115,11 +117,6 @@ private:
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
class Imp_T;
|
class Imp_T;
|
||||||
|
|
||||||
class CastVisitor;
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
class CastVisitor_T;
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
const ElementTypeT& CastTo() const;
|
const ElementTypeT& CastTo() const;
|
||||||
|
|
||||||
|
@ -139,6 +136,3 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
||||||
|
|
||||||
#include "elements.inl"
|
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
/**********************************************
|
|
||||||
|
|
||||||
License: BSD
|
|
||||||
Project Webpage: http://cajun-jsonapi.sourceforge.net/
|
|
||||||
Author: Terry Caton
|
|
||||||
|
|
||||||
***********************************************/
|
|
||||||
|
|
||||||
#include "visitor.h"
|
|
||||||
#include <cassert>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace json
|
|
||||||
{
|
|
||||||
|
|
||||||
/////////////////////////
|
|
||||||
// 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
|
|
||||||
{
|
|
||||||
CastVisitor_T<ElementTypeT> castVisitor;
|
|
||||||
imp.Accept(castVisitor);
|
|
||||||
return castVisitor.element && m_Element == *castVisitor.element;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ElementTypeT m_Element;
|
|
||||||
};
|
|
||||||
|
|
||||||
class UnknownElement::CastVisitor : public ConstVisitor
|
|
||||||
{
|
|
||||||
virtual void Visit(const Array&) {}
|
|
||||||
virtual void Visit(const Object&) {}
|
|
||||||
virtual void Visit(const Number&) {}
|
|
||||||
virtual void Visit(const String&) {}
|
|
||||||
virtual void Visit(const Boolean&) {}
|
|
||||||
virtual void Visit(const Null&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
class UnknownElement::CastVisitor_T : public CastVisitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const ElementTypeT *element;
|
|
||||||
CastVisitor_T() : element(0) { }
|
|
||||||
|
|
||||||
// we don't know what this is, but it overrides one of the base's no-op functions
|
|
||||||
void Visit(const ElementTypeT& element) { this->element = &element; }
|
|
||||||
};
|
|
||||||
|
|
||||||
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(double number) : m_pImp( new Imp_T<Number>(number) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(int number) : m_pImp( new Imp_T<Number>(number) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(long number) : m_pImp( new Imp_T<Number>(number) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(bool boolean) : m_pImp( new Imp_T<Boolean>(boolean) ) {}
|
|
||||||
inline UnknownElement::UnknownElement(const char *string) : m_pImp( new Imp_T<String>(string) ) {}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
delete m_pImp;
|
|
||||||
m_pImp = unknown.m_pImp->Clone();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline UnknownElement& UnknownElement::operator[] (const std::string& key)
|
|
||||||
{
|
|
||||||
// the people want an object. make us one if we aren't already
|
|
||||||
return ConvertTo<Object>()[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const UnknownElement& UnknownElement::operator[] (const std::string& key) const
|
|
||||||
{
|
|
||||||
// throws if we aren't an object
|
|
||||||
Object const& obj = CastTo<Object>();
|
|
||||||
Object::const_iterator it = obj.find(key);
|
|
||||||
if (it == obj.end())
|
|
||||||
throw Exception("Object member not found: " + key);
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline UnknownElement& UnknownElement::operator[] (size_t index)
|
|
||||||
{
|
|
||||||
// the people want an array. make us one if we aren't already
|
|
||||||
return ConvertTo<Array>()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const UnknownElement& UnknownElement::operator[] (size_t index) const
|
|
||||||
{
|
|
||||||
// throws if we aren't an array
|
|
||||||
return CastTo<Array>()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
const ElementTypeT& UnknownElement::CastTo() const
|
|
||||||
{
|
|
||||||
CastVisitor_T<ElementTypeT> castVisitor;
|
|
||||||
m_pImp->Accept(castVisitor);
|
|
||||||
if (!castVisitor.element)
|
|
||||||
throw Exception("Bad cast");
|
|
||||||
return *castVisitor.element;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
ElementTypeT& UnknownElement::ConvertTo()
|
|
||||||
{
|
|
||||||
CastVisitor_T<ElementTypeT> castVisitor;
|
|
||||||
Accept(castVisitor);
|
|
||||||
if (!castVisitor.element)
|
|
||||||
{
|
|
||||||
// we're not the right type. fix it & try again
|
|
||||||
*this = ElementTypeT();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace
|
|
|
@ -9,8 +9,11 @@ Author: Terry Caton
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "elements.h"
|
#include "elements.h"
|
||||||
|
|
||||||
|
#ifndef LAGI_PRE
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace json
|
namespace json
|
||||||
{
|
{
|
||||||
|
@ -118,8 +121,4 @@ private:
|
||||||
const std::string& MatchExpectedToken(Token::Type nExpected, TokenStream& tokenStream);
|
const std::string& MatchExpectedToken(Token::Type nExpected, TokenStream& tokenStream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // End namespace
|
} // End namespace
|
||||||
|
|
||||||
|
|
||||||
#include "reader.inl"
|
|
||||||
|
|
|
@ -18,7 +18,12 @@ class Writer : private ConstVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
static void Write(const ElementTypeT& element, std::ostream& ostr);
|
static void Write(const ElementTypeT& element, std::ostream& ostr)
|
||||||
|
{
|
||||||
|
Writer writer(ostr);
|
||||||
|
writer.Write(element);
|
||||||
|
ostr.flush(); // all done
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Writer(std::ostream& ostr);
|
Writer(std::ostream& ostr);
|
||||||
|
@ -30,12 +35,12 @@ private:
|
||||||
void Write(const Null& null);
|
void Write(const Null& null);
|
||||||
void Write(const UnknownElement& unknown);
|
void Write(const UnknownElement& unknown);
|
||||||
|
|
||||||
virtual void Visit(const Array& array);
|
void Visit(const Array& array);
|
||||||
virtual void Visit(const Object& object);
|
void Visit(const Object& object);
|
||||||
virtual void Visit(const Number& number);
|
void Visit(const Number& number);
|
||||||
virtual void Visit(const String& string);
|
void Visit(const String& string);
|
||||||
virtual void Visit(const Boolean& boolean);
|
void Visit(const Boolean& boolean);
|
||||||
virtual void Visit(const Null& null);
|
void Visit(const Null& null);
|
||||||
|
|
||||||
std::ostream& m_ostr;
|
std::ostream& m_ostr;
|
||||||
int m_nTabDepth;
|
int m_nTabDepth;
|
||||||
|
@ -43,5 +48,3 @@ private:
|
||||||
|
|
||||||
|
|
||||||
} // End namespace
|
} // End namespace
|
||||||
|
|
||||||
#include "writer.inl"
|
|
||||||
|
|
|
@ -38,13 +38,16 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,6 @@
|
||||||
// Setup
|
// Setup
|
||||||
#define AGI_PRE
|
#define AGI_PRE
|
||||||
|
|
||||||
// Common C++
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
// General headers
|
// General headers
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
Loading…
Reference in a new issue