15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_JSON_JSON_FILE_VALUE_SERIALIZER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_JSON_JSON_FILE_VALUE_SERIALIZER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT JSONFileValueSerializer : public base::ValueSerializer {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // json_file_patch is the path of a file that will be source of the
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deserialization or the destination of the serialization.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When deserializing, the file should exist, but when serializing, the
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // serializer will attempt to create the file at the specified location.
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit JSONFileValueSerializer(const base::FilePath& json_file_path)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : json_file_path_(json_file_path),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      allow_trailing_comma_(false) {}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~JSONFileValueSerializer() {}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DO NOT USE except in unit tests to verify the file was written properly.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should never serialize directly to a file since this will block the
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread. Instead, serialize to a string and write to the file you want on
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the file thread.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to serialize the data structure represented by Value into
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSON.  If the return value is true, the result will have been written
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into the file whose name was passed into the constructor.
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool Serialize(const base::Value& root) OVERRIDE;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Equivalent to Serialize(root) except binary values are omitted from the
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // output.
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool SerializeAndOmitBinaryValues(const base::Value& root);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to deserialize the data structure encoded in the file passed
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in to the constructor into a structure of Value objects.  If the return
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value is NULL, and if |error_code| is non-null, |error_code| will
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contain an integer error code (either JsonFileError or JsonParseError).
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |error_message| is non-null, it will be filled in with a formatted
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error message including the location of the error if appropriate.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The caller takes ownership of the returned value.
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual base::Value* Deserialize(int* error_code,
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                   std::string* error_message) OVERRIDE;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This enum is designed to safely overlap with JSONReader::JsonParseError.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum JsonFileError {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JSON_NO_ERROR = 0,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JSON_ACCESS_DENIED = 1000,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JSON_CANNOT_READ_FILE,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JSON_FILE_LOCKED,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JSON_NO_SUCH_FILE
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // File-specific error messages that can be returned.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kAccessDenied;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kCannotReadFile;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kFileLocked;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kNoSuchFile;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert an error code into an error message.  |error_code| is assumed to
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be a JsonFileError.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* GetErrorMessageForCode(int error_code);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_allow_trailing_comma(bool new_value) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    allow_trailing_comma_ = new_value;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool SerializeInternal(const base::Value& root, bool omit_binary_values);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath json_file_path_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool allow_trailing_comma_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // A wrapper for ReadFileToString which returns a non-zero JsonFileError if
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // there were file errors.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ReadFileToString(std::string* json_string);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(JSONFileValueSerializer);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_JSON_JSON_FILE_VALUE_SERIALIZER_H_
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89