• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 using base::FilePath;
13 
14 const char JSONFileValueDeserializer::kAccessDenied[] = "Access denied.";
15 const char JSONFileValueDeserializer::kCannotReadFile[] = "Can't read file.";
16 const char JSONFileValueDeserializer::kFileLocked[] = "File locked.";
17 const char JSONFileValueDeserializer::kNoSuchFile[] = "File doesn't exist.";
18 
JSONFileValueSerializer(const base::FilePath & json_file_path)19 JSONFileValueSerializer::JSONFileValueSerializer(
20     const base::FilePath& json_file_path)
21     : json_file_path_(json_file_path) {
22 }
23 
24 JSONFileValueSerializer::~JSONFileValueSerializer() = default;
25 
Serialize(const base::Value & root)26 bool JSONFileValueSerializer::Serialize(const base::Value& root) {
27   return SerializeInternal(root, false);
28 }
29 
SerializeAndOmitBinaryValues(const base::Value & root)30 bool JSONFileValueSerializer::SerializeAndOmitBinaryValues(
31     const base::Value& root) {
32   return SerializeInternal(root, true);
33 }
34 
SerializeInternal(const base::Value & root,bool omit_binary_values)35 bool JSONFileValueSerializer::SerializeInternal(const base::Value& root,
36                                                 bool omit_binary_values) {
37   std::string json_string;
38   JSONStringValueSerializer serializer(&json_string);
39   serializer.set_pretty_print(true);
40   bool result = omit_binary_values ?
41       serializer.SerializeAndOmitBinaryValues(root) :
42       serializer.Serialize(root);
43   if (!result)
44     return false;
45 
46   int data_size = static_cast<int>(json_string.size());
47   if (base::WriteFile(json_file_path_, json_string.data(), data_size) !=
48       data_size)
49     return false;
50 
51   return true;
52 }
53 
JSONFileValueDeserializer(const base::FilePath & json_file_path,int options)54 JSONFileValueDeserializer::JSONFileValueDeserializer(
55     const base::FilePath& json_file_path,
56     int options)
57     : json_file_path_(json_file_path), options_(options), last_read_size_(0U) {}
58 
59 JSONFileValueDeserializer::~JSONFileValueDeserializer() = default;
60 
ReadFileToString(std::string * json_string)61 int JSONFileValueDeserializer::ReadFileToString(std::string* json_string) {
62   DCHECK(json_string);
63   if (!base::ReadFileToString(json_file_path_, json_string)) {
64 #if defined(OS_WIN)
65     int error = ::GetLastError();
66     if (error == ERROR_SHARING_VIOLATION || error == ERROR_LOCK_VIOLATION) {
67       return JSON_FILE_LOCKED;
68     } else if (error == ERROR_ACCESS_DENIED) {
69       return JSON_ACCESS_DENIED;
70     }
71 #endif
72     if (!base::PathExists(json_file_path_))
73       return JSON_NO_SUCH_FILE;
74     else
75       return JSON_CANNOT_READ_FILE;
76   }
77 
78   last_read_size_ = json_string->size();
79   return JSON_NO_ERROR;
80 }
81 
GetErrorMessageForCode(int error_code)82 const char* JSONFileValueDeserializer::GetErrorMessageForCode(int error_code) {
83   switch (error_code) {
84     case JSON_NO_ERROR:
85       return "";
86     case JSON_ACCESS_DENIED:
87       return kAccessDenied;
88     case JSON_CANNOT_READ_FILE:
89       return kCannotReadFile;
90     case JSON_FILE_LOCKED:
91       return kFileLocked;
92     case JSON_NO_SUCH_FILE:
93       return kNoSuchFile;
94     default:
95       NOTREACHED();
96       return "";
97   }
98 }
99 
Deserialize(int * error_code,std::string * error_str)100 std::unique_ptr<base::Value> JSONFileValueDeserializer::Deserialize(
101     int* error_code,
102     std::string* error_str) {
103   std::string json_string;
104   int error = ReadFileToString(&json_string);
105   if (error != JSON_NO_ERROR) {
106     if (error_code)
107       *error_code = error;
108     if (error_str)
109       *error_str = GetErrorMessageForCode(error);
110     return nullptr;
111   }
112 
113   JSONStringValueDeserializer deserializer(json_string, options_);
114   return deserializer.Deserialize(error_code, error_str);
115 }
116