gfx/graphite2/src/json.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:7f465d1e3da2
1 /* GRAPHITE2 LICENSING
2
3 Copyright 2011, SIL International
4 All rights reserved.
5
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should also have received a copy of the GNU Lesser General Public
17 License along with this library in the file named "LICENSE".
18 If not, write to the Free Software Foundation, 51 Franklin Street,
19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
20 internet at http://www.fsf.org/licenses/lgpl.html.
21
22 Alternatively, the contents of this file may be used under the terms of the
23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
24 License, as published by the Free Software Foundation, either version 2
25 of the License or (at your option) any later version.
26 */
27 // JSON debug logging
28 // Author: Tim Eves
29
30 #if !defined GRAPHITE2_NTRACING
31
32 #include <stdio.h>
33 #include "inc/json.h"
34
35 using namespace graphite2;
36
37 namespace
38 {
39 enum
40 {
41 seq = ',',
42 obj='}', member=':', empty_obj='{',
43 arr=']', empty_arr='['
44 };
45 }
46
47 const json::_null_t json::null = {};
48
49 inline
50 void json::context(const char current) throw()
51 {
52 fprintf(_stream, "%c", *_context);
53 indent();
54 *_context = current;
55 }
56
57
58 void json::indent(const int d) throw()
59 {
60 if (*_context == member || (_flatten && _flatten < _context))
61 fputc(' ', _stream);
62 else
63 fprintf(_stream, "\n%*s", 4*int(_context - _contexts + d), "");
64 }
65
66
67 inline
68 void json::push_context(const char prefix, const char suffix) throw()
69 {
70 assert(_context - _contexts < ptrdiff_t(sizeof _contexts));
71
72 if (_context == _contexts)
73 *_context = suffix;
74 else
75 context(suffix);
76 *++_context = prefix;
77 }
78
79
80 void json::pop_context() throw()
81 {
82 assert(_context > _contexts);
83
84 if (*_context == seq) indent(-1);
85 else fputc(*_context, _stream);
86
87 fputc(*--_context, _stream);
88 if (_context == _contexts) fputc('\n', _stream);
89 fflush(_stream);
90
91 if (_flatten >= _context) _flatten = 0;
92 *_context = seq;
93 }
94
95
96 // These four functions cannot be inlined as pointers to these
97 // functions are needed for operator << (_context_t) to work.
98 void json::flat(json & j) throw() { if (!j._flatten) j._flatten = j._context; }
99 void json::close(json & j) throw() { j.pop_context(); }
100 void json::object(json & j) throw() { j.push_context('{', '}'); }
101 void json::array(json & j) throw() { j.push_context('[', ']'); }
102 void json::item(json & j) throw()
103 {
104 while (j._context > j._contexts+1 && j._context[-1] != arr)
105 j.pop_context();
106 }
107
108
109 json & json::operator << (json::string s) throw()
110 {
111 const char ctxt = _context[-1] == obj ? *_context == member ? seq : member : seq;
112 context(ctxt);
113 fprintf(_stream, "\"%s\"", s);
114 if (ctxt == member) fputc(' ', _stream);
115
116 return *this;
117 }
118
119 json & json::operator << (json::number f) throw() { context(seq); fprintf(_stream, "%g", f); return *this; }
120 json & json::operator << (json::integer d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; }
121 json & json::operator << (long unsigned d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; }
122 json & json::operator << (json::boolean b) throw() { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
123 json & json::operator << (json::_null_t) throw() { context(seq); fputs("null",_stream); return *this; }
124
125 #endif
126

mercurial