• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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/util/streaming_line_reader.h"
18 
19 #include <cstddef>
20 #include <utility>
21 #include <vector>
22 
23 #include "perfetto/base/logging.h"
24 #include "perfetto/ext/base/string_view.h"
25 
26 namespace perfetto::trace_processor::util {
27 
StreamingLineReader(LinesCallback cb)28 StreamingLineReader::StreamingLineReader(LinesCallback cb)
29     : lines_callback_(std::move(cb)) {}
30 StreamingLineReader::~StreamingLineReader() = default;
31 
BeginWrite(size_t write_buf_size)32 char* StreamingLineReader::BeginWrite(size_t write_buf_size) {
33   PERFETTO_DCHECK(size_before_write_ == 0);
34   size_before_write_ = buf_.size();
35   buf_.resize(size_before_write_ + write_buf_size);
36   return &buf_[size_before_write_];
37 }
38 
EndWrite(size_t size_written)39 void StreamingLineReader::EndWrite(size_t size_written) {
40   PERFETTO_DCHECK(size_before_write_ + size_written <= buf_.size());
41   buf_.resize(size_before_write_ + size_written);
42   size_before_write_ = 0;
43 
44   size_t consumed = Tokenize(base::StringView(buf_.data(), buf_.size()));
45   PERFETTO_DCHECK(consumed <= buf_.size());
46 
47   // Unless we got very lucky, the last line in the chunk just written will be
48   // incomplete. Move it to the beginning of the buffer so it gets glued
49   // together on the next {Begin,End}Write() call.
50   buf_.erase(buf_.begin(), buf_.begin() + static_cast<int64_t>(consumed));
51 }
52 
Tokenize(base::StringView input)53 size_t StreamingLineReader::Tokenize(base::StringView input) {
54   size_t chars_consumed = 0;
55   const char* line_start = input.data();
56   std::vector<base::StringView> lines;
57   lines.reserve(1000);  // An educated guess to avoid silly expansions.
58   for (const char* c = input.data(); c < input.end(); ++c) {
59     if (*c != '\n')
60       continue;
61     lines.emplace_back(line_start, static_cast<size_t>(c - line_start));
62     line_start = c + 1;
63     chars_consumed = static_cast<size_t>(c + 1 - input.data());
64   }  // for(c : input)
65 
66   PERFETTO_DCHECK(lines.empty() ^ (chars_consumed != 0));
67   if (!lines.empty())
68     lines_callback_(lines);
69   return chars_consumed;
70 }
71 
72 }  // namespace perfetto::trace_processor::util
73