Coverage Report

Created: 2025-03-11 06:23

/proc/self/cwd/pw_tokenizer/pw_tokenizer_private/csv.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2024 The Pigweed Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
// use this file except in compliance with the License. You may obtain a copy of
5
// the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
// License for the specific language governing permissions and limitations under
13
// the License.
14
#pragma once
15
16
#include <optional>
17
#include <string>
18
#include <vector>
19
20
namespace pw::tokenizer {
21
namespace internal {
22
23
class CsvParser {
24
 public:
25
0
  CsvParser() : state_(kNewEntry), line_(1u) {}
26
27
  [[nodiscard]] std::optional<std::vector<std::string>> ParseCharacter(
28
0
      char ch) {
29
0
    return ParseCharacterOrEof(ch);
30
0
  }
31
32
0
  [[nodiscard]] std::optional<std::vector<std::string>> Flush() {
33
0
    return ParseCharacterOrEof(kEndOfFile);
34
0
  }
35
36
 private:
37
  static constexpr int kEndOfFile = -1;
38
39
  std::optional<std::vector<std::string>> FinishLine();
40
41
  std::optional<std::vector<std::string>> ParseCharacterOrEof(int ch);
42
43
  enum {
44
    kNewEntry,
45
    kUnquotedEntry,
46
    kQuotedEntry,
47
    kQuotedEntryQuote,
48
    kError,
49
  } state_;
50
51
  std::vector<std::string> line_;
52
};
53
54
}  // namespace internal
55
56
/// Parses a CSV file, calling the provided function for each line.
57
///
58
/// Errors are logged and the involved lines are skipped.
59
template <typename Function>
60
0
void ParseCsv(std::string_view csv, Function handle_line) {
61
0
  internal::CsvParser parser;
62
0
  for (char ch : csv) {
63
0
    if (auto line = parser.ParseCharacter(ch); line.has_value()) {
64
0
      handle_line(std::move(*line));
65
0
    }
66
0
  }
67
0
  auto line = parser.Flush();
68
0
  if (line.has_value()) {
69
0
    handle_line(std::move(*line));
70
0
  }
71
0
}
72
73
/// Parses a CSV file. Returns the results as a single nested std::vector of
74
/// std::string.
75
[[nodiscard]] inline std::vector<std::vector<std::string>> ParseCsv(
76
0
    std::string_view csv) {
77
0
  std::vector<std::vector<std::string>> result;
78
0
  ParseCsv(csv, [&result](std::vector<std::string>&& line) {
79
0
    result.push_back(std::move(line));
80
0
  });
81
0
  return result;
82
0
}
83
84
}  // namespace pw::tokenizer