diff options
Diffstat (limited to 'src/google/protobuf/util/internal/json_objectwriter.cc')
-rw-r--r-- | src/google/protobuf/util/internal/json_objectwriter.cc | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/google/protobuf/util/internal/json_objectwriter.cc b/src/google/protobuf/util/internal/json_objectwriter.cc new file mode 100644 index 00000000..d14ae10a --- /dev/null +++ b/src/google/protobuf/util/internal/json_objectwriter.cc @@ -0,0 +1,175 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/util/internal/json_objectwriter.h> + +#include <math.h> + +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/util/internal/utility.h> +#include <google/protobuf/util/internal/json_escaping.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace util { +namespace converter { + +using strings::ArrayByteSource; + +JsonObjectWriter::~JsonObjectWriter() { + if (!element_->is_root()) { + GOOGLE_LOG(WARNING) << "JsonObjectWriter was not fully closed."; + } +} + +JsonObjectWriter* JsonObjectWriter::StartObject(StringPiece name) { + WritePrefix(name); + WriteChar('{'); + Push(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::EndObject() { + Pop(); + WriteChar('}'); + if (element()->is_root()) NewLine(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::StartList(StringPiece name) { + WritePrefix(name); + WriteChar('['); + Push(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::EndList() { + Pop(); + WriteChar(']'); + if (element()->is_root()) NewLine(); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name, + const bool value) { + return RenderSimple(name, value ? "true" : "false"); +} + +JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name, + const int32 value) { + return RenderSimple(name, SimpleItoa(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderUint32(StringPiece name, + const uint32 value) { + return RenderSimple(name, SimpleItoa(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name, + const int64 value) { + WritePrefix(name); + WriteChar('"'); + stream_->WriteString(SimpleItoa(value)); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderUint64(StringPiece name, + const uint64 value) { + WritePrefix(name); + WriteChar('"'); + stream_->WriteString(SimpleItoa(value)); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderDouble(StringPiece name, + const double value) { + if (isfinite(value)) return RenderSimple(name, SimpleDtoa(value)); + + // Render quoted with NaN/Infinity-aware DoubleAsString. + return RenderString(name, DoubleAsString(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderFloat(StringPiece name, + const float value) { + if (isfinite(value)) return RenderSimple(name, SimpleFtoa(value)); + + // Render quoted with NaN/Infinity-aware FloatAsString. + return RenderString(name, FloatAsString(value)); +} + +JsonObjectWriter* JsonObjectWriter::RenderString(StringPiece name, + StringPiece value) { + WritePrefix(name); + WriteChar('"'); + ArrayByteSource source(value); + JsonEscaping::Escape(&source, &sink_); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderBytes(StringPiece name, + StringPiece value) { + WritePrefix(name); + string base64; + WebSafeBase64EscapeWithPadding(value, &base64); + WriteChar('"'); + // TODO(wpoon): Consider a ByteSink solution that writes the base64 bytes + // directly to the stream, rather than first putting them + // into a string and then writing them to the stream. + stream_->WriteRaw(base64.data(), base64.size()); + WriteChar('"'); + return this; +} + +JsonObjectWriter* JsonObjectWriter::RenderNull(StringPiece name) { + return RenderSimple(name, "null"); +} + +void JsonObjectWriter::WritePrefix(StringPiece name) { + bool not_first = !element()->is_first(); + if (not_first) WriteChar(','); + if (not_first || !element()->is_root()) NewLine(); + if (!name.empty()) { + WriteChar('"'); + ArrayByteSource source(name); + JsonEscaping::Escape(&source, &sink_); + stream_->WriteString("\":"); + if (!indent_string_.empty()) WriteChar(' '); + } +} + +} // namespace converter +} // namespace util +} // namespace protobuf +} // namespace google |