From 17a4541d67c73d413c9e8f8751cd9c2573933aef Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 28 Nov 2012 09:44:01 +0000 Subject: [PATCH] retrace: Move JSON write implementation to a .cpp file. --- CMakeLists.txt | 6 +- retrace/CMakeLists.txt | 10 +- retrace/glstate_images.cpp | 1 + retrace/glstate_params.py | 1 + retrace/glstate_shaders.cpp | 1 + retrace/json.cpp | 299 ++++++++++++++++++++++++++++++++++++ retrace/json.hpp | 293 ++++++----------------------------- 7 files changed, 358 insertions(+), 253 deletions(-) create mode 100644 retrace/json.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e39bb45..2ace8ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -338,7 +338,9 @@ set_target_properties (common PROPERTIES ) if (ANDROID) - target_link_libraries (common log) + target_link_libraries (common + log + ) endif () @@ -355,7 +357,7 @@ add_subdirectory (retrace) # CLI if (ENABLE_CLI) - add_subdirectory(cli) + add_subdirectory (cli) endif () ############################################################################## diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt index 2e33b54..5a2a608 100644 --- a/retrace/CMakeLists.txt +++ b/retrace/CMakeLists.txt @@ -31,13 +31,13 @@ add_custom_command ( ${CMAKE_SOURCE_DIR}/specs/stdapi.py ) -add_library (retrace_common +add_library (retrace_common STATIC retrace.cpp retrace_main.cpp retrace_stdc.cpp retrace_swizzle.cpp + json.cpp ) - target_link_libraries (retrace_common common ${PNG_LIBRARIES} @@ -46,7 +46,7 @@ target_link_libraries (retrace_common ${GETOPT_LIBRARIES} ) -add_library (glretrace_common +add_library (glretrace_common STATIC glretrace_gl.cpp glretrace_cgl.cpp glretrace_glx.cpp @@ -60,8 +60,10 @@ add_library (glretrace_common glstate_shaders.cpp glws.cpp ) - add_dependencies (glretrace_common glproc) +target_link_libraries (glretrace_common + retrace_common +) if (WIN32 OR APPLE OR X11_FOUND) diff --git a/retrace/glstate_images.cpp b/retrace/glstate_images.cpp index 484b295..f460285 100644 --- a/retrace/glstate_images.cpp +++ b/retrace/glstate_images.cpp @@ -24,6 +24,7 @@ **************************************************************************/ +#include #include #include diff --git a/retrace/glstate_params.py b/retrace/glstate_params.py index c88b6f0..6db4b80 100644 --- a/retrace/glstate_params.py +++ b/retrace/glstate_params.py @@ -253,6 +253,7 @@ class StateDumper: pass def dump(self): + print '#include ' print '#include ' print print '#include "json.hpp"' diff --git a/retrace/glstate_shaders.cpp b/retrace/glstate_shaders.cpp index d32a7b4..aeead3b 100644 --- a/retrace/glstate_shaders.cpp +++ b/retrace/glstate_shaders.cpp @@ -24,6 +24,7 @@ **************************************************************************/ +#include #include #include diff --git a/retrace/json.cpp b/retrace/json.cpp new file mode 100644 index 0000000..e500aa6 --- /dev/null +++ b/retrace/json.cpp @@ -0,0 +1,299 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +/* + * JSON writing functions. + */ + + +#include +#include + +#include "json.hpp" + + +void +JSONWriter::newline(void) { + os << "\n"; + for (int i = 0; i < level; ++i) + os << " "; +} + +void +JSONWriter::separator(void) { + if (value) { + os << ","; + switch (space) { + case '\0': + break; + case '\n': + newline(); + break; + default: + os << space; + break; + } + } else { + if (space == '\n') { + newline(); + } + } +} + +static void +escapeAsciiString(std::ostream &os, const char *str) { + os << "\""; + + const unsigned char *src = (const unsigned char *)str; + unsigned char c; + while ((c = *src++)) { + if ((c == '\"') || + (c == '\\')) { + // escape character + os << '\\' << (unsigned char)c; + } else if ((c >= 0x20 && c <= 0x7e) || + c == '\t' || + c == '\r' || + c == '\n') { + // pass-through character + os << (unsigned char)c; + } else { + assert(0); + os << "?"; + } + } + + os << "\""; +} + +static void +escapeUnicodeString(std::ostream &os, const char *str) { + os << "\""; + + const char *locale = setlocale(LC_CTYPE, ""); + const char *src = str; + mbstate_t state; + + memset(&state, 0, sizeof state); + + do { + // Convert characters one at a time in order to recover from + // conversion errors + wchar_t c; + size_t written = mbsrtowcs(&c, &src, 1, &state); + if (written == 0) { + // completed + break; + } if (written == (size_t)-1) { + // conversion error -- skip + os << "?"; + do { + ++src; + } while (*src & 0x80); + } else if ((c == '\"') || + (c == '\\')) { + // escape character + os << '\\' << (unsigned char)c; + } else if ((c >= 0x20 && c <= 0x7e) || + c == '\t' || + c == '\r' || + c == '\n') { + // pass-through character + os << (unsigned char)c; + } else { + // unicode + os << "\\u" << std::setfill('0') << std::hex << std::setw(4) << (unsigned)c; + os << std::dec; + } + } while (src); + + setlocale(LC_CTYPE, locale); + + os << "\""; +} + +static void +encodeBase64String(std::ostream &os, const unsigned char *bytes, size_t size) { + const char *table64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + unsigned char c0, c1, c2, c3; + char buf[4]; + unsigned written; + + os << "\""; + + written = 0; + while (size >= 3) { + c0 = bytes[0] >> 2; + c1 = ((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xf0) >> 4); + c2 = ((bytes[1] & 0x0f) << 2) | ((bytes[2] & 0xc0) >> 6); + c3 = bytes[2] & 0x3f; + + buf[0] = table64[c0]; + buf[1] = table64[c1]; + buf[2] = table64[c2]; + buf[3] = table64[c3]; + + os.write(buf, 4); + + bytes += 3; + size -= 3; + ++written; + + if (written >= 76/4 && size) { + os << "\n"; + written = 0; + } + } + + if (size > 0) { + c0 = bytes[0] >> 2; + c1 = ((bytes[0] & 0x03) << 4); + buf[2] = '='; + buf[3] = '='; + + if (size > 1) { + c1 |= ((bytes[1] & 0xf0) >> 4); + c2 = ((bytes[1] & 0x0f) << 2); + if (size > 2) { + c2 |= ((bytes[2] & 0xc0) >> 6); + c3 = bytes[2] & 0x3f; + buf[3] = table64[c3]; + } + buf[2] = table64[c2]; + } + buf[1] = table64[c1]; + buf[0] = table64[c0]; + + os.write(buf, 4); + } + + os << "\""; +} + +JSONWriter::JSONWriter(std::ostream &_os) : + os(_os), + level(0), + value(false), + space(0) +{ + beginObject(); +} + +JSONWriter::~JSONWriter() { + endObject(); + newline(); +} + +void +JSONWriter::beginObject() { + separator(); + os << "{"; + ++level; + value = false; +} + +void +JSONWriter::endObject() { + --level; + if (value) + newline(); + os << "}"; + value = true; + space = '\n'; +} + +void +JSONWriter::beginMember(const char * name) { + space = 0; + separator(); + newline(); + escapeAsciiString(os, name); + os << ": "; + value = false; +} + +void +JSONWriter::endMember(void) { + assert(value); + value = true; + space = 0; +} + +void +JSONWriter::beginArray() { + separator(); + os << "["; + ++level; + value = false; + space = 0; +} + +void +JSONWriter::endArray(void) { + --level; + if (space == '\n') { + newline(); + } + os << "]"; + value = true; + space = '\n'; +} + +void +JSONWriter::writeString(const char *s) { + if (!s) { + writeNull(); + return; + } + + separator(); + escapeUnicodeString(os, s); + value = true; + space = ' '; +} + +void +JSONWriter::writeBase64(const void *bytes, size_t size) { + separator(); + encodeBase64String(os, (const unsigned char *)bytes, size); + value = true; + space = ' '; +} + +void +JSONWriter::writeNull(void) { + separator(); + os << "null"; + value = true; + space = ' '; +} + +void +JSONWriter::writeBool(bool b) { + separator(); + os << (b ? "true" : "false"); + value = true; + space = ' '; +} diff --git a/retrace/json.hpp b/retrace/json.hpp index 0431cf7..9433800 100644 --- a/retrace/json.hpp +++ b/retrace/json.hpp @@ -24,13 +24,12 @@ **************************************************************************/ /* - * Trace writing functions. + * JSON writing functions. */ #ifndef _JSON_HPP_ #define _JSON_HPP_ -#include #include #include @@ -57,277 +56,71 @@ private: bool value; char space; - void newline(void) { - os << "\n"; - for (int i = 0; i < level; ++i) - os << " "; - } - - void separator(void) { - if (value) { - os << ","; - switch (space) { - case '\0': - break; - case '\n': - newline(); - break; - default: - os << space; - break; - } - } else { - if (space == '\n') { - newline(); - } - } - } - - void escapeAsciiString(const char *str) { - os << "\""; - - const unsigned char *src = (const unsigned char *)str; - unsigned char c; - while ((c = *src++)) { - if ((c == '\"') || - (c == '\\')) { - // escape character - os << '\\' << (unsigned char)c; - } else if ((c >= 0x20 && c <= 0x7e) || - c == '\t' || - c == '\r' || - c == '\n') { - // pass-through character - os << (unsigned char)c; - } else { - assert(0); - os << "?"; - } - } - - os << "\""; - } - - void escapeUnicodeString(const char *str) { - os << "\""; - - const char *locale = setlocale(LC_CTYPE, ""); - const char *src = str; - mbstate_t state; - - memset(&state, 0, sizeof state); - - do { - // Convert characters one at a time in order to recover from - // conversion errors - wchar_t c; - size_t written = mbsrtowcs(&c, &src, 1, &state); - if (written == 0) { - // completed - break; - } if (written == (size_t)-1) { - // conversion error -- skip - os << "?"; - do { - ++src; - } while (*src & 0x80); - } else if ((c == '\"') || - (c == '\\')) { - // escape character - os << '\\' << (unsigned char)c; - } else if ((c >= 0x20 && c <= 0x7e) || - c == '\t' || - c == '\r' || - c == '\n') { - // pass-through character - os << (unsigned char)c; - } else { - // unicode - os << "\\u" << std::setfill('0') << std::hex << std::setw(4) << (unsigned)c; - os << std::dec; - } - } while (src); + void + newline(void); - setlocale(LC_CTYPE, locale); - - os << "\""; - } - - void encodeBase64String(const unsigned char *bytes, size_t size) { - const char *table64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - unsigned char c0, c1, c2, c3; - char buf[4]; - unsigned written; - - os << "\""; - - written = 0; - while (size >= 3) { - c0 = bytes[0] >> 2; - c1 = ((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xf0) >> 4); - c2 = ((bytes[1] & 0x0f) << 2) | ((bytes[2] & 0xc0) >> 6); - c3 = bytes[2] & 0x3f; - - buf[0] = table64[c0]; - buf[1] = table64[c1]; - buf[2] = table64[c2]; - buf[3] = table64[c3]; - - os.write(buf, 4); - - bytes += 3; - size -= 3; - ++written; - - if (written >= 76/4 && size) { - os << "\n"; - written = 0; - } - } - - if (size > 0) { - c0 = bytes[0] >> 2; - c1 = ((bytes[0] & 0x03) << 4); - buf[2] = '='; - buf[3] = '='; - - if (size > 1) { - c1 |= ((bytes[1] & 0xf0) >> 4); - c2 = ((bytes[1] & 0x0f) << 2); - if (size > 2) { - c2 |= ((bytes[2] & 0xc0) >> 6); - c3 = bytes[2] & 0x3f; - buf[3] = table64[c3]; - } - buf[2] = table64[c2]; - } - buf[1] = table64[c1]; - buf[0] = table64[c0]; - - os.write(buf, 4); - } - - os << "\""; - } + void + separator(void); public: - JSONWriter(std::ostream &_os) : - os(_os), - level(0), - value(false), - space(0) - { - beginObject(); - } + JSONWriter(std::ostream &_os); - ~JSONWriter() { - endObject(); - newline(); - } + ~JSONWriter(); - inline void beginObject() { - separator(); - os << "{"; - ++level; - value = false; - } + void + beginObject(); - inline void endObject() { - --level; - if (value) - newline(); - os << "}"; - value = true; - space = '\n'; - } + void + endObject(); - inline void beginMember(const char * name) { - space = 0; - separator(); - newline(); - escapeAsciiString(name); - os << ": "; - value = false; - } + void + beginMember(const char * name); - inline void beginMember(const std::string &name) { + inline void + beginMember(const std::string &name) { beginMember(name.c_str()); } - inline void endMember(void) { - assert(value); - value = true; - space = 0; - } + void + endMember(void); - inline void beginArray() { - separator(); - os << "["; - ++level; - value = false; - space = 0; - } + void + beginArray(); - inline void endArray(void) { - --level; - if (space == '\n') { - newline(); - } - os << "]"; - value = true; - space = '\n'; - } + void + endArray(void); - inline void writeString(const char *s) { - if (!s) { - writeNull(); - return; - } + void + writeString(const char *s); - separator(); - escapeUnicodeString(s); - value = true; - space = ' '; - } - - inline void writeString(const std::string &s) { + inline void + writeString(const std::string &s) { writeString(s.c_str()); } - inline void writeBase64(const void *bytes, size_t size) { - separator(); - encodeBase64String((const unsigned char *)bytes, size); - value = true; - space = ' '; - } + void + writeBase64(const void *bytes, size_t size); - inline void writeNull(void) { - separator(); - os << "null"; - value = true; - space = ' '; - } - - inline void writeBool(bool b) { - separator(); - os << (b ? "true" : "false"); - value = true; - space = ' '; - } + void + writeNull(void); + void + writeBool(bool b); /** * Special case for char to prevent it to be written as a literal * character. */ - inline void writeInt(signed char n) { + inline void + writeInt(signed char n) { separator(); os << std::dec << static_cast(n); value = true; space = ' '; } - inline void writeInt(unsigned char n) { + inline void + writeInt(unsigned char n) { separator(); os << std::dec << static_cast(n); value = true; @@ -335,14 +128,17 @@ public: } template - inline void writeInt(T n) { + inline void + writeInt(T n) { separator(); os << std::dec << n; value = true; space = ' '; } + template - inline void writeFloat(T n) { + void + writeFloat(T n) { separator(); if (isnan(n)) { // NaN is non-standard but widely supported @@ -360,20 +156,23 @@ public: space = ' '; } - inline void writeStringMember(const char *name, const char *s) { + inline void + writeStringMember(const char *name, const char *s) { beginMember(name); writeString(s); endMember(); } - inline void writeBoolMember(const char *name, bool b) { + inline void + writeBoolMember(const char *name, bool b) { beginMember(name); writeBool(b); endMember(); } template - inline void writeIntMember(const char *name, T n) { + inline void + writeIntMember(const char *name, T n) { beginMember(name); writeInt(n); endMember(); -- 2.43.0