1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/graphite2/src/json.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,126 @@ 1.4 +/* GRAPHITE2 LICENSING 1.5 + 1.6 + Copyright 2011, SIL International 1.7 + All rights reserved. 1.8 + 1.9 + This library is free software; you can redistribute it and/or modify 1.10 + it under the terms of the GNU Lesser General Public License as published 1.11 + by the Free Software Foundation; either version 2.1 of License, or 1.12 + (at your option) any later version. 1.13 + 1.14 + This program is distributed in the hope that it will be useful, 1.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.17 + Lesser General Public License for more details. 1.18 + 1.19 + You should also have received a copy of the GNU Lesser General Public 1.20 + License along with this library in the file named "LICENSE". 1.21 + If not, write to the Free Software Foundation, 51 Franklin Street, 1.22 + Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 1.23 + internet at http://www.fsf.org/licenses/lgpl.html. 1.24 + 1.25 +Alternatively, the contents of this file may be used under the terms of the 1.26 +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public 1.27 +License, as published by the Free Software Foundation, either version 2 1.28 +of the License or (at your option) any later version. 1.29 +*/ 1.30 +// JSON debug logging 1.31 +// Author: Tim Eves 1.32 + 1.33 +#if !defined GRAPHITE2_NTRACING 1.34 + 1.35 +#include <stdio.h> 1.36 +#include "inc/json.h" 1.37 + 1.38 +using namespace graphite2; 1.39 + 1.40 +namespace 1.41 +{ 1.42 + enum 1.43 + { 1.44 + seq = ',', 1.45 + obj='}', member=':', empty_obj='{', 1.46 + arr=']', empty_arr='[' 1.47 + }; 1.48 +} 1.49 + 1.50 +const json::_null_t json::null = {}; 1.51 + 1.52 +inline 1.53 +void json::context(const char current) throw() 1.54 +{ 1.55 + fprintf(_stream, "%c", *_context); 1.56 + indent(); 1.57 + *_context = current; 1.58 +} 1.59 + 1.60 + 1.61 +void json::indent(const int d) throw() 1.62 +{ 1.63 + if (*_context == member || (_flatten && _flatten < _context)) 1.64 + fputc(' ', _stream); 1.65 + else 1.66 + fprintf(_stream, "\n%*s", 4*int(_context - _contexts + d), ""); 1.67 +} 1.68 + 1.69 + 1.70 +inline 1.71 +void json::push_context(const char prefix, const char suffix) throw() 1.72 +{ 1.73 + assert(_context - _contexts < ptrdiff_t(sizeof _contexts)); 1.74 + 1.75 + if (_context == _contexts) 1.76 + *_context = suffix; 1.77 + else 1.78 + context(suffix); 1.79 + *++_context = prefix; 1.80 +} 1.81 + 1.82 + 1.83 +void json::pop_context() throw() 1.84 +{ 1.85 + assert(_context > _contexts); 1.86 + 1.87 + if (*_context == seq) indent(-1); 1.88 + else fputc(*_context, _stream); 1.89 + 1.90 + fputc(*--_context, _stream); 1.91 + if (_context == _contexts) fputc('\n', _stream); 1.92 + fflush(_stream); 1.93 + 1.94 + if (_flatten >= _context) _flatten = 0; 1.95 + *_context = seq; 1.96 +} 1.97 + 1.98 + 1.99 +// These four functions cannot be inlined as pointers to these 1.100 +// functions are needed for operator << (_context_t) to work. 1.101 +void json::flat(json & j) throw() { if (!j._flatten) j._flatten = j._context; } 1.102 +void json::close(json & j) throw() { j.pop_context(); } 1.103 +void json::object(json & j) throw() { j.push_context('{', '}'); } 1.104 +void json::array(json & j) throw() { j.push_context('[', ']'); } 1.105 +void json::item(json & j) throw() 1.106 +{ 1.107 + while (j._context > j._contexts+1 && j._context[-1] != arr) 1.108 + j.pop_context(); 1.109 +} 1.110 + 1.111 + 1.112 +json & json::operator << (json::string s) throw() 1.113 +{ 1.114 + const char ctxt = _context[-1] == obj ? *_context == member ? seq : member : seq; 1.115 + context(ctxt); 1.116 + fprintf(_stream, "\"%s\"", s); 1.117 + if (ctxt == member) fputc(' ', _stream); 1.118 + 1.119 + return *this; 1.120 +} 1.121 + 1.122 +json & json::operator << (json::number f) throw() { context(seq); fprintf(_stream, "%g", f); return *this; } 1.123 +json & json::operator << (json::integer d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; } 1.124 +json & json::operator << (long unsigned d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; } 1.125 +json & json::operator << (json::boolean b) throw() { context(seq); fputs(b ? "true" : "false", _stream); return *this; } 1.126 +json & json::operator << (json::_null_t) throw() { context(seq); fputs("null",_stream); return *this; } 1.127 + 1.128 +#endif 1.129 +