1// Copyright 2009 Google Inc. 2// Author: James deBoer 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15 16#include <config.h> 17#include <stdio.h> 18#include <string.h> 19#include <sstream> 20#include <string> 21#include "jsonwriter.h" 22#include "google/output_string.h" 23 24namespace open_vcdiff { 25 26JSONCodeTableWriter::JSONCodeTableWriter() 27 : output_called_(false) {} 28JSONCodeTableWriter::~JSONCodeTableWriter() {} 29 30bool JSONCodeTableWriter::Init(size_t /*dictionary_size*/) { 31 output_ = "["; 32 target_length_ = 0; 33 return true; 34} 35 36void JSONCodeTableWriter::Output(OutputStringInterface* out) { 37 output_called_ = true; 38 out->append(output_.data(), output_.size()); 39 output_ = ""; 40 target_length_ = 0; 41} 42 43void JSONCodeTableWriter::FinishEncoding(OutputStringInterface* out) { 44 if (output_called_) { 45 out->append("]", 1); 46 } 47} 48 49void JSONCodeTableWriter::JSONEscape(const char* data, 50 size_t size, 51 string* out) { 52 for (size_t i = 0; i < size; ++i) { 53 const char c = data[i]; 54 switch (c) { 55 case '"': out->append("\\\"", 2); break; 56 case '\\': out->append("\\\\", 2); break; 57 case '\b': out->append("\\b", 2); break; 58 case '\f': out->append("\\f", 2); break; 59 case '\n': out->append("\\n", 2); break; 60 case '\r': out->append("\\r", 2); break; 61 case '\t': out->append("\\t", 2); break; 62 default: 63 // encode zero as unicode, also all control codes. 64 if (c < 32 || c >= 127) { 65 char unicode_code[8] = ""; 66 snprintf(unicode_code, sizeof(unicode_code), "\\u%04x", c); 67 out->append(unicode_code, strlen(unicode_code)); 68 } else { 69 out->push_back(c); 70 } 71 } 72 } 73} 74 75void JSONCodeTableWriter::Add(const char* data, size_t size) { 76 output_.push_back('\"'); 77 JSONEscape(data, size, &output_); 78 output_.append("\",", 2); 79 target_length_ += size; 80} 81 82void JSONCodeTableWriter::Copy(int32_t offset, size_t size) { 83 std::ostringstream copy_code; 84 copy_code << offset << "," << size << ","; 85 output_.append(copy_code.str()); 86 target_length_ += size; 87} 88 89void JSONCodeTableWriter::Run(size_t size, unsigned char byte) { 90 output_.push_back('\"'); 91 output_.append(string(size, byte).data(), size); 92 output_.append("\",", 2); 93 target_length_ += size; 94} 95 96size_t JSONCodeTableWriter::target_length() const { 97 return target_length_; 98} 99 100void JSONCodeTableWriter::WriteHeader(OutputStringInterface *, 101 VCDiffFormatExtensionFlags) { 102 // The JSON format does not need a header. 103} 104 105} // namespace open_vcdiff 106