1 //  Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 #pragma once
7 #include <array>
8 
9 #include "file/sequence_file_reader.h"
10 
11 namespace ROCKSDB_NAMESPACE {
12 
13 // A wrapper on top of Env::SequentialFile for reading text lines from a file.
14 // Lines are delimited by '\n'. The last line may or may not include a
15 // trailing newline. Uses SequentialFileReader internally.
16 class LineFileReader {
17  private:
18   std::array<char, 8192> buf_;
19   SequentialFileReader sfr_;
20   Status status_;
21   const char* buf_begin_ = buf_.data();
22   const char* buf_end_ = buf_.data();
23   size_t line_number_ = 0;
24   bool at_eof_ = false;
25 
26  public:
27   // See SequentialFileReader constructors
28   template <typename... Args>
LineFileReader(Args &&...args)29   explicit LineFileReader(Args&&... args)
30       : sfr_(std::forward<Args&&>(args)...) {}
31 
32   static Status Create(const std::shared_ptr<FileSystem>& fs,
33                        const std::string& fname, const FileOptions& file_opts,
34                        std::unique_ptr<LineFileReader>* reader,
35                        IODebugContext* dbg);
36 
37   LineFileReader(const LineFileReader&) = delete;
38   LineFileReader& operator=(const LineFileReader&) = delete;
39 
40   // Reads another line from the file, returning true on success and saving
41   // the line to `out`, without delimiter, or returning false on failure. You
42   // must check GetStatus() to determine whether the failure was just
43   // end-of-file (OK status) or an I/O error (another status).
44   bool ReadLine(std::string* out);
45 
46   // Returns the number of the line most recently returned from ReadLine.
47   // Return value is unspecified if ReadLine has returned false due to
48   // I/O error. After ReadLine returns false due to end-of-file, return
49   // value is the last returned line number, or equivalently the total
50   // number of lines returned.
GetLineNumber()51   size_t GetLineNumber() const { return line_number_; }
52 
53   // Returns any error encountered during read. The error is considered
54   // permanent and no retry or recovery is attempted with the same
55   // LineFileReader.
GetStatus()56   const Status& GetStatus() const { return status_; }
57 };
58 
59 }  // namespace ROCKSDB_NAMESPACE
60