blob: 5a9c1546a94a0a5f510d9b6fea55c26c0c37a59a [file] [log] [blame]
Alex Vakulenkob04936f2014-09-19 14:53:58 -07001// Copyright 2014 The Chromium OS 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 "buffet/utils.h"
6
7#include <map>
8#include <string>
9
10#include <base/files/file_util.h>
11#include <base/json/json_reader.h>
12#include <chromeos/errors/error_codes.h>
13
14namespace buffet {
15
Alex Vakulenko36c85aa2015-04-09 09:06:39 -070016namespace {
17
18// Truncates a string if it is too long. Used for error reporting with really
19// long JSON strings.
20std::string LimitString(const std::string& text, size_t max_len) {
21 if (text.size() <= max_len)
22 return text;
23 return text.substr(0, max_len - 3) + "...";
24}
25
26const size_t kMaxStrLen = 1700; // Log messages are limited to 2000 chars.
27
28} // anonymous namespace
29
Alex Vakulenkob04936f2014-09-19 14:53:58 -070030const char kErrorDomainBuffet[] = "buffet";
31const char kFileReadError[] = "file_read_error";
Alex Vakulenko07216fe2014-09-19 15:31:09 -070032const char kInvalidCategoryError[] = "invalid_category";
33const char kInvalidPackageError[] = "invalid_package";
Alex Vakulenkob04936f2014-09-19 14:53:58 -070034
35std::unique_ptr<const base::DictionaryValue> LoadJsonDict(
36 const base::FilePath& json_file_path, chromeos::ErrorPtr* error) {
Alex Vakulenkob04936f2014-09-19 14:53:58 -070037 std::string json_string;
38 if (!base::ReadFileToString(json_file_path, &json_string)) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080039 chromeos::errors::system::AddSystemError(error, FROM_HERE, errno);
40 chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomainBuffet,
Alex Vakulenkob04936f2014-09-19 14:53:58 -070041 kFileReadError,
42 "Failed to read file '%s'",
43 json_file_path.value().c_str());
Alex Vakulenko9e2f8cd2015-04-07 16:28:09 -070044 return {};
Alex Vakulenkob04936f2014-09-19 14:53:58 -070045 }
Alex Vakulenko9e2f8cd2015-04-07 16:28:09 -070046 return LoadJsonDict(json_string, error);
47}
48
49std::unique_ptr<const base::DictionaryValue> LoadJsonDict(
50 const std::string& json_string, chromeos::ErrorPtr* error) {
51 std::unique_ptr<const base::DictionaryValue> result;
Alex Vakulenkob04936f2014-09-19 14:53:58 -070052 std::string error_message;
53 base::Value* value = base::JSONReader::ReadAndReturnError(
54 json_string, base::JSON_PARSE_RFC, nullptr, &error_message);
55 if (!value) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080056 chromeos::Error::AddToPrintf(error, FROM_HERE,
57 chromeos::errors::json::kDomain,
Alex Vakulenkob04936f2014-09-19 14:53:58 -070058 chromeos::errors::json::kParseError,
Alex Vakulenko9e2f8cd2015-04-07 16:28:09 -070059 "Error parsing JSON string '%s': %s",
Alex Vakulenko36c85aa2015-04-09 09:06:39 -070060 LimitString(json_string, kMaxStrLen).c_str(),
Alex Vakulenkob04936f2014-09-19 14:53:58 -070061 error_message.c_str());
62 return result;
63 }
64 const base::DictionaryValue* dict_value = nullptr;
65 if (!value->GetAsDictionary(&dict_value)) {
66 delete value;
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080067 chromeos::Error::AddToPrintf(error, FROM_HERE,
68 chromeos::errors::json::kDomain,
Alex Vakulenkob04936f2014-09-19 14:53:58 -070069 chromeos::errors::json::kObjectExpected,
Alex Vakulenko9e2f8cd2015-04-07 16:28:09 -070070 "JSON string '%s' is not a JSON object",
Alex Vakulenko36c85aa2015-04-09 09:06:39 -070071 LimitString(json_string, kMaxStrLen).c_str());
Alex Vakulenkob04936f2014-09-19 14:53:58 -070072 return result;
73 }
74 result.reset(dict_value);
75 return result;
76}
77
78} // namespace buffet