|  | // Copyright 2015 The Weave Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "src/utils.h" | 
|  |  | 
|  | #include <limits> | 
|  |  | 
|  | #include <base/bind_helpers.h> | 
|  | #include <base/json/json_reader.h> | 
|  |  | 
|  | #include "src/json_error_codes.h" | 
|  |  | 
|  | namespace weave { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | // Truncates a string if it is too long. Used for error reporting with really | 
|  | // long JSON strings. | 
|  | std::string LimitString(const std::string& text, size_t max_len) { | 
|  | if (text.size() <= max_len) | 
|  | return text; | 
|  | return text.substr(0, max_len - 3) + "..."; | 
|  | } | 
|  |  | 
|  | const size_t kMaxStrLen = 1700;  // Log messages are limited to 2000 chars. | 
|  |  | 
|  | const char kErrorCodeKey[] = "code"; | 
|  | const char kErrorMessageKey[] = "message"; | 
|  |  | 
|  | const time_t kJ2000ToTimeT = 946684800; | 
|  |  | 
|  | }  // anonymous namespace | 
|  |  | 
|  | namespace errors { | 
|  | const char kSchemaError[] = "schema_error"; | 
|  | const char kInvalidCategoryError[] = "invalid_category"; | 
|  | const char kInvalidPackageError[] = "invalid_package"; | 
|  | }  // namespace errors | 
|  |  | 
|  | std::unique_ptr<base::DictionaryValue> LoadJsonDict( | 
|  | const std::string& json_string, | 
|  | ErrorPtr* error) { | 
|  | std::unique_ptr<base::DictionaryValue> result; | 
|  | std::string error_message; | 
|  | auto value = base::JSONReader::ReadAndReturnError( | 
|  | json_string, base::JSON_PARSE_RFC, nullptr, &error_message); | 
|  | if (!value) { | 
|  | Error::AddToPrintf(error, FROM_HERE, errors::json::kParseError, | 
|  | "Error parsing JSON string '%s' (%zu): %s", | 
|  | LimitString(json_string, kMaxStrLen).c_str(), | 
|  | json_string.size(), error_message.c_str()); | 
|  | return result; | 
|  | } | 
|  | result = base::DictionaryValue::From(std::move(value)); | 
|  | if (!result) { | 
|  | Error::AddToPrintf(error, FROM_HERE, errors::json::kObjectExpected, | 
|  | "JSON string '%s' is not a JSON object", | 
|  | LimitString(json_string, kMaxStrLen).c_str()); | 
|  | } | 
|  | return result; | 
|  | } | 
|  |  | 
|  | std::unique_ptr<base::DictionaryValue> ErrorInfoToJson(const Error& error) { | 
|  | std::unique_ptr<base::DictionaryValue> output{new base::DictionaryValue}; | 
|  | output->SetString(kErrorMessageKey, error.GetMessage()); | 
|  | output->SetString(kErrorCodeKey, error.GetCode()); | 
|  | return output; | 
|  | } | 
|  |  | 
|  | uint32_t ToJ2000Time(const base::Time& time) { | 
|  | return std::min<int64_t>( | 
|  | std::numeric_limits<int32_t>::max(), | 
|  | std::max<int64_t>(kJ2000ToTimeT, time.ToTimeT()) - kJ2000ToTimeT); | 
|  | } | 
|  |  | 
|  | base::Time FromJ2000Time(uint32_t time) { | 
|  | if (time >= static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) | 
|  | return base::Time::Max(); | 
|  | return base::Time::FromTimeT(time + kJ2000ToTimeT); | 
|  | } | 
|  |  | 
|  | }  // namespace weave |