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