Home | History | Annotate | Download | only in trace_processor
      1 /*
      2  * Copyright (C) 2019 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "src/trace_processor/json_trace_utils.h"
     18 
     19 #include <json/value.h>
     20 #include <limits>
     21 
     22 #if !PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
     23 #error The JSON trace parser is supported only in the standalone build for now.
     24 #endif
     25 
     26 namespace perfetto {
     27 namespace trace_processor {
     28 namespace json_trace_utils {
     29 
     30 // Json trace event timestamps are in us.
     31 // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit#heading=h.nso4gcezn7n1
     32 base::Optional<int64_t> CoerceToNs(const Json::Value& value) {
     33   switch (static_cast<size_t>(value.type())) {
     34     case Json::realValue:
     35       return static_cast<int64_t>(value.asDouble() * 1000);
     36     case Json::uintValue:
     37     case Json::intValue:
     38       return value.asInt64() * 1000;
     39     case Json::stringValue: {
     40       std::string s = value.asString();
     41       char* end;
     42       int64_t n = strtoll(s.c_str(), &end, 10);
     43       if (end != s.data() + s.size())
     44         return base::nullopt;
     45       return n * 1000;
     46     }
     47     default:
     48       return base::nullopt;
     49   }
     50 }
     51 
     52 base::Optional<int64_t> CoerceToInt64(const Json::Value& value) {
     53   switch (static_cast<size_t>(value.type())) {
     54     case Json::realValue:
     55     case Json::uintValue:
     56     case Json::intValue:
     57       return value.asInt64();
     58     case Json::stringValue: {
     59       std::string s = value.asString();
     60       char* end;
     61       int64_t n = strtoll(s.c_str(), &end, 10);
     62       if (end != s.data() + s.size())
     63         return base::nullopt;
     64       return n;
     65     }
     66     default:
     67       return base::nullopt;
     68   }
     69 }
     70 
     71 base::Optional<uint32_t> CoerceToUint32(const Json::Value& value) {
     72   base::Optional<int64_t> result = CoerceToInt64(value);
     73   if (!result.has_value())
     74     return base::nullopt;
     75   int64_t n = result.value();
     76   if (n < 0 || n > std::numeric_limits<uint32_t>::max())
     77     return base::nullopt;
     78   return static_cast<uint32_t>(n);
     79 }
     80 
     81 }  // namespace json_trace_utils
     82 }  // namespace trace_processor
     83 }  // namespace perfetto
     84