1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/json/json_file_value_serializer.h" 6 7#include "base/files/file_util.h" 8#include "base/json/json_string_value_serializer.h" 9#include "base/logging.h" 10#include "build/build_config.h" 11 12using base::FilePath; 13 14const char JSONFileValueDeserializer::kAccessDenied[] = "Access denied."; 15const char JSONFileValueDeserializer::kCannotReadFile[] = "Can't read file."; 16const char JSONFileValueDeserializer::kFileLocked[] = "File locked."; 17const char JSONFileValueDeserializer::kNoSuchFile[] = "File doesn't exist."; 18 19JSONFileValueSerializer::JSONFileValueSerializer( 20 const base::FilePath& json_file_path) 21 : json_file_path_(json_file_path) { 22} 23 24JSONFileValueSerializer::~JSONFileValueSerializer() { 25} 26 27bool JSONFileValueSerializer::Serialize(const base::Value& root) { 28 return SerializeInternal(root, false); 29} 30 31bool JSONFileValueSerializer::SerializeAndOmitBinaryValues( 32 const base::Value& root) { 33 return SerializeInternal(root, true); 34} 35 36bool JSONFileValueSerializer::SerializeInternal(const base::Value& root, 37 bool omit_binary_values) { 38 std::string json_string; 39 JSONStringValueSerializer serializer(&json_string); 40 serializer.set_pretty_print(true); 41 bool result = omit_binary_values ? 42 serializer.SerializeAndOmitBinaryValues(root) : 43 serializer.Serialize(root); 44 if (!result) 45 return false; 46 47 int data_size = static_cast<int>(json_string.size()); 48 if (base::WriteFile(json_file_path_, json_string.data(), data_size) != 49 data_size) 50 return false; 51 52 return true; 53} 54 55JSONFileValueDeserializer::JSONFileValueDeserializer( 56 const base::FilePath& json_file_path) 57 : json_file_path_(json_file_path), 58 allow_trailing_comma_(false), 59 last_read_size_(0U) { 60} 61 62JSONFileValueDeserializer::~JSONFileValueDeserializer() { 63} 64 65int JSONFileValueDeserializer::ReadFileToString(std::string* json_string) { 66 DCHECK(json_string); 67 if (!base::ReadFileToString(json_file_path_, json_string)) { 68#if defined(OS_WIN) 69 int error = ::GetLastError(); 70 if (error == ERROR_SHARING_VIOLATION || error == ERROR_LOCK_VIOLATION) { 71 return JSON_FILE_LOCKED; 72 } else if (error == ERROR_ACCESS_DENIED) { 73 return JSON_ACCESS_DENIED; 74 } 75#endif 76 if (!base::PathExists(json_file_path_)) 77 return JSON_NO_SUCH_FILE; 78 else 79 return JSON_CANNOT_READ_FILE; 80 } 81 82 last_read_size_ = json_string->size(); 83 return JSON_NO_ERROR; 84} 85 86const char* JSONFileValueDeserializer::GetErrorMessageForCode(int error_code) { 87 switch (error_code) { 88 case JSON_NO_ERROR: 89 return ""; 90 case JSON_ACCESS_DENIED: 91 return kAccessDenied; 92 case JSON_CANNOT_READ_FILE: 93 return kCannotReadFile; 94 case JSON_FILE_LOCKED: 95 return kFileLocked; 96 case JSON_NO_SUCH_FILE: 97 return kNoSuchFile; 98 default: 99 NOTREACHED(); 100 return ""; 101 } 102} 103 104std::unique_ptr<base::Value> JSONFileValueDeserializer::Deserialize( 105 int* error_code, 106 std::string* error_str) { 107 std::string json_string; 108 int error = ReadFileToString(&json_string); 109 if (error != JSON_NO_ERROR) { 110 if (error_code) 111 *error_code = error; 112 if (error_str) 113 *error_str = GetErrorMessageForCode(error); 114 return NULL; 115 } 116 117 JSONStringValueDeserializer deserializer(json_string); 118 deserializer.set_allow_trailing_comma(allow_trailing_comma_); 119 return deserializer.Deserialize(error_code, error_str); 120} 121