• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "logging/rtc_event_log/encoder/blob_encoding.h"
12 
13 #include <cstdint>
14 
15 #include "logging/rtc_event_log/encoder/var_int.h"
16 #include "rtc_base/checks.h"
17 #include "rtc_base/logging.h"
18 
19 namespace webrtc {
20 
EncodeBlobs(const std::vector<std::string> & blobs)21 std::string EncodeBlobs(const std::vector<std::string>& blobs) {
22   RTC_DCHECK(!blobs.empty());
23 
24   size_t result_length_bound = kMaxVarIntLengthBytes * blobs.size();
25   for (const auto& blob : blobs) {
26     // Providing an input so long that it would cause a wrap-around is an error.
27     RTC_DCHECK_GE(result_length_bound + blob.length(), result_length_bound);
28     result_length_bound += blob.length();
29   }
30 
31   std::string result;
32   result.reserve(result_length_bound);
33 
34   // First, encode all of the lengths.
35   for (absl::string_view blob : blobs) {
36     result += EncodeVarInt(blob.length());
37   }
38 
39   // Second, encode the actual blobs.
40   for (absl::string_view blob : blobs) {
41     result.append(blob.data(), blob.length());
42   }
43 
44   RTC_DCHECK_LE(result.size(), result_length_bound);
45   return result;
46 }
47 
DecodeBlobs(absl::string_view encoded_blobs,size_t num_of_blobs)48 std::vector<absl::string_view> DecodeBlobs(absl::string_view encoded_blobs,
49                                            size_t num_of_blobs) {
50   if (encoded_blobs.empty()) {
51     RTC_LOG(LS_WARNING) << "Corrupt input; empty input.";
52     return std::vector<absl::string_view>();
53   }
54 
55   if (num_of_blobs == 0u) {
56     RTC_LOG(LS_WARNING)
57         << "Corrupt input; number of blobs must be greater than 0.";
58     return std::vector<absl::string_view>();
59   }
60 
61   // Read the lengths of all blobs.
62   std::vector<uint64_t> lengths(num_of_blobs);
63   for (size_t i = 0; i < num_of_blobs; ++i) {
64     bool success = false;
65     std::tie(success, encoded_blobs) = DecodeVarInt(encoded_blobs, &lengths[i]);
66     if (!success) {
67       RTC_LOG(LS_WARNING) << "Corrupt input; varint decoding failed.";
68       return std::vector<absl::string_view>();
69     }
70   }
71 
72   // Read the blobs themselves.
73   std::vector<absl::string_view> blobs(num_of_blobs);
74   for (size_t i = 0; i < num_of_blobs; ++i) {
75     if (lengths[i] > encoded_blobs.length()) {
76       RTC_LOG(LS_WARNING) << "Corrupt input; blob sizes exceed input size.";
77       return std::vector<absl::string_view>();
78     }
79 
80     blobs[i] = encoded_blobs.substr(0, lengths[i]);
81     encoded_blobs = encoded_blobs.substr(lengths[i]);
82   }
83 
84   if (!encoded_blobs.empty()) {
85     RTC_LOG(LS_WARNING) << "Corrupt input; unrecognized trailer.";
86     return std::vector<absl::string_view>();
87   }
88 
89   return blobs;
90 }
91 
92 }  // namespace webrtc
93