aboutsummaryrefslogtreecommitdiff
path: root/src/unstable/json.h
blob: 14cb5722e52aeec95f9e64ca0285ccfb39adf36a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef BU_JSON_H
#define BU_JSON_H

#include "bu/hash.h"
#include "bu/list.h"
#include "bu/array.h"
#include "bu/string.h"
#include "bu/utfstring.h"

namespace Bu
{
    class Stream;
    class Formatter;
    typedef Bu::List<Bu::UtfString> UtfStringList;

    class Json
    {
    private:
        class ParseState
        {
        public:
            ParseState( Bu::Stream &sInput ) :
                c( 0 ), sInput( sInput ), iLine( 1 ), iChar( 0 )
            {
            }

            void error( const Bu::String &sTxt );

            Bu::UtfChar c;
            Bu::Stream &sInput;
            int iLine;
            int iChar;
        };
        Json( ParseState &ps );
        typedef Bu::Hash<Bu::UtfString, Json *> JsonHash;
        typedef Bu::Array<Json *> JsonList;

    public:
        typedef JsonList::iterator iterator;
        typedef JsonList::const_iterator const_iterator;
        enum Type
        {
            Invalid,
            Object,
            Array,
            String,
            Number,
            Boolean,
            Null
        };

    public:
        Json();
        Json( const Bu::UtfString &sValue );
        Json( const Bu::String &sValue );
        Json( const char *sValue );
        Json( double dValue );
        Json( bool bValue );
        Json( Type eType );
        Json( Bu::Stream &sInput );
        Json( const Json &rSrc );
        virtual ~Json();

        Type getType() const;
        Bu::UtfString getString() const;
        double getNumber() const;
        bool getBoolean() const;
        bool isNull() const;
        Json &operator[]( const Bu::UtfString &sKey ) const;
        Json &operator[]( int iIndex ) const;
        int getSize() const;
        Bu::UtfStringList getKeys() const;
        iterator begin();
        const_iterator begin() const;
        iterator end();
        const_iterator end() const;

        bool has( const Bu::String &sKey ) const;
        Json &insert( const Bu::String &sKey, Bu::Json *pObj );
        Json &insert( const Bu::String &sKey, const Bu::Json &rObj );
        Json &insert( const Bu::String &sKey, const Bu::String &sValue );
        Json &insert( const Bu::String &sKey, const char *sValue );
        Json &insert( const Bu::String &sKey, double dValue );
        Json &insert( const Bu::String &sKey, bool bValue );
        Json &insertObject( const Bu::String &sKey );
        Json &insertArray( const Bu::String &sKey );
        Json &insertNull( const Bu::String &sKey );
        Json &append( Bu::Json *pObj );
        Json &append( const Bu::String &sValue );
        Json &append( const char *sValue );
        Json &append( double dValue );
        Json &append( bool bValue );
        Json &appendObject();
        Json &appendArray();
        Json &appendNull();

        void parse( Bu::Stream &sInput );
        void parse( const Bu::String &sInput );
        void reset();

        void write( Bu::Stream &sOutput ) const;
        void writeStable( Bu::Stream &sOutput ) const;
        Bu::String toString() const;
        Bu::String toStringStable() const;

        Bu::Json &operator=( const Bu::Json &rSrc );
        bool operator==( const Bu::String &rRhs );

    private:
        void parse( ParseState &ps );
        void parseString( ParseState &ps, Bu::UtfString &sOut );
        void parseString( ParseState &ps );
        void parseObject( ParseState &ps );
        void parseArray( ParseState &ps );
        void parseNumber( ParseState &ps );
        void parseLiteral( ParseState &ps );
        bool readChar( ParseState &ps );
        void readChar( ParseState &ps, const char *sSection );
        bool isWs( Bu::UtfChar c );
        void skipWs( ParseState &ps );
        void writeStr( const Bu::UtfString &sStr, Bu::Stream &sOutput ) const;

    private:
        Type eType;
        union DatUnion
        {
            DatUnion() : pObject( NULL ) { }
            DatUnion( const Bu::String &sValue ) :
                pString( new Bu::UtfString( sValue ) ) { }
            DatUnion( const Bu::UtfString &sValue ) :
                pString( new Bu::UtfString( sValue ) ) { }
            DatUnion( const char *sValue ) :
                pString( new Bu::UtfString( sValue ) ) { }
            DatUnion( double dValue ) : dNumber( dValue ) { }
            DatUnion( bool bValue ) : bBoolean( bValue ) { }
            JsonHash *pObject;
            JsonList *pArray;
            Bu::UtfString *pString;
            double dNumber;
            bool bBoolean;
        } uDat;
    };

    Bu::Formatter &operator<<( Bu::Formatter &f, const Bu::Json &j );
}

#endif