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