file_printer.h
1 // Copyright 2018, Beeri 15. All rights reserved.
2 // Author: Roman Gershman (romange@gmail.com)
3 //
4 
5 #pragma once
6 
7 #include <google/protobuf/text_format.h>
8 #include <functional>
9 #include <string>
10 
11 #include "strings/stringpiece.h"
12 #include "util/plang/plang.h"
13 #include "util/sp_task_pool.h"
14 #include "util/status.h"
15 #include "util/pb2json.h"
16 
17 namespace file {
18 class ListReader;
19 } // namespace file
20 
21 namespace util {
22 namespace pprint {
23 
24 class SizeSummarizer;
25 class Printer;
26 
27 class FilePrinter {
28  public:
29  using FieldDescriptor = ::google::protobuf::FieldDescriptor;
30  using Descriptor = ::google::protobuf::Descriptor;
31 
32  using FieldPrinterFactory = std::function<::google::protobuf::TextFormat::FieldValuePrinter*(
33  const FieldDescriptor& fd)>;
34 
35  FilePrinter();
36  virtual ~FilePrinter();
37 
38  void Init(const std::string& fname);
39  util::Status Run();
40 
41  uint64_t count() const {
42  return count_;
43  }
44 
45  void SetJsonPrinterOptions(const Pb2JsonOptions& options) {
46  options_ = options;
47  }
48 
49  void RegisterFieldPrinter(FieldPrinterFactory pred) {
50  field_printer_cb_ = pred;
51  }
52 
53  // Valid only after Init was called.
54  const Descriptor* GetDescriptor() const;
55 
56  protected:
57  virtual void LoadFile(const std::string& fname) = 0;
58 
59  // Returns false if EOF reached, true if Next call succeeded and status code overthise.
60  virtual util::StatusObject<bool> Next(StringPiece* record) = 0;
61 
62  virtual void PostRun() {
63  }
64 
65  std::unique_ptr<const ::google::protobuf::Message> descr_msg_;
66 
67  private:
68  class PrintTask;
69 
70  // TODO: to replace this logic with IoContextPool.
71  // We can use OpenFiberReadFile to read via fiber-friendly files.
72  struct PrintSharedData {
73  std::mutex m;
74  const plang::Expr* expr = nullptr;
75  const Printer* printer = nullptr;
76  SizeSummarizer* size_summarizer = nullptr;
77  };
78 
80 
81  std::unique_ptr<TaskPool> pool_;
82  std::unique_ptr<Printer> printer_;
83  std::unique_ptr<SizeSummarizer> size_summarizer_;
84  std::unique_ptr<plang::Expr> test_expr_;
85 
86  PrintSharedData shared_data_;
87  Pb2JsonOptions options_;
88 
89  typedef std::pair<FieldPrinterFactory,
90  std::unique_ptr<::google::protobuf::TextFormat::FieldValuePrinter>>
91  FieldPrinterType;
92 
93  FieldPrinterFactory field_printer_cb_;
94  uint64_t count_ = 0;
95 };
96 
97 class ListReaderPrinter final : public FilePrinter {
98  protected:
99  void LoadFile(const std::string& fname) override;
100  util::StatusObject<bool> Next(StringPiece* record) override;
101  void PostRun() override;
102 
103  private:
104  std::unique_ptr<file::ListReader> reader_;
105  std::string record_buf_;
106  util::Status st_;
107 };
108 
109 } // namespace pprint
110 } // namespace util