| // Copyright 2009 Google Inc. |
| // Author: James deBoer |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <config.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <sstream> |
| #include <string> |
| #include "jsonwriter.h" |
| #include "google/output_string.h" |
| |
| namespace open_vcdiff { |
| |
| JSONCodeTableWriter::JSONCodeTableWriter() |
| : output_called_(false) {} |
| JSONCodeTableWriter::~JSONCodeTableWriter() {} |
| |
| bool JSONCodeTableWriter::Init(size_t /*dictionary_size*/) { |
| output_ = "["; |
| target_length_ = 0; |
| return true; |
| } |
| |
| void JSONCodeTableWriter::Output(OutputStringInterface* out) { |
| output_called_ = true; |
| out->append(output_.data(), output_.size()); |
| output_ = ""; |
| target_length_ = 0; |
| } |
| |
| void JSONCodeTableWriter::FinishEncoding(OutputStringInterface* out) { |
| if (output_called_) { |
| out->append("]", 1); |
| } |
| } |
| |
| void JSONCodeTableWriter::JSONEscape(const char* data, |
| size_t size, |
| string* out) { |
| for (size_t i = 0; i < size; ++i) { |
| const char c = data[i]; |
| switch (c) { |
| case '"': out->append("\\\"", 2); break; |
| case '\\': out->append("\\\\", 2); break; |
| case '\b': out->append("\\b", 2); break; |
| case '\f': out->append("\\f", 2); break; |
| case '\n': out->append("\\n", 2); break; |
| case '\r': out->append("\\r", 2); break; |
| case '\t': out->append("\\t", 2); break; |
| default: |
| // encode zero as unicode, also all control codes. |
| if (c < 32 || c >= 127) { |
| char unicode_code[8] = ""; |
| snprintf(unicode_code, sizeof(unicode_code), "\\u%04x", c); |
| out->append(unicode_code, strlen(unicode_code)); |
| } else { |
| out->push_back(c); |
| } |
| } |
| } |
| } |
| |
| void JSONCodeTableWriter::Add(const char* data, size_t size) { |
| output_.push_back('\"'); |
| JSONEscape(data, size, &output_); |
| output_.append("\",", 2); |
| target_length_ += size; |
| } |
| |
| void JSONCodeTableWriter::Copy(int32_t offset, size_t size) { |
| std::ostringstream copy_code; |
| copy_code << offset << "," << size << ","; |
| output_.append(copy_code.str()); |
| target_length_ += size; |
| } |
| |
| void JSONCodeTableWriter::Run(size_t size, unsigned char byte) { |
| output_.push_back('\"'); |
| output_.append(string(size, byte).data(), size); |
| output_.append("\",", 2); |
| target_length_ += size; |
| } |
| |
| size_t JSONCodeTableWriter::target_length() const { |
| return target_length_; |
| } |
| |
| void JSONCodeTableWriter::WriteHeader(OutputStringInterface *, |
| VCDiffFormatExtensionFlags) { |
| // The JSON format does not need a header. |
| } |
| |
| } // namespace open_vcdiff |