summaryrefslogtreecommitdiffstats
path: root/fbench/src/util/filereader.h
blob: 6b85ad3ba511b4b4e130ad4e89fec0e876875256 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include <fstream>
#include <memory>
#include <vector>

int GetOpt (int argc, char *argv[], const char *optionsString,
            const char* &optionArgument,
            int &optionIndex);

/**
 * This is a wrapper class for std::ifstream that may be used when
 * reading line based text files. An internal buffer is used to
 * improve performance.
 **/
class FileReader
{
private:
  std::unique_ptr<std::ifstream> _backing;
  std::istream      *_file;
  int                _bufsize;
  std::vector<char>  _buf;
  uint64_t           _lastReadPos;
  uint64_t           _nextReadPos;
  int                _bufused;
  int                _bufpos;

  /**
   * Fill the internal buffer with data from the currently open file.
   **/
  void FillBuffer();

  FileReader(const FileReader &);
  FileReader &operator=(const FileReader &);

public:

  /**
   * Creates a  used for disk-access. An
   * internal buffer of 5120 bytes is also created.
   **/
  FileReader();

  /**
   * Frees memory used by the underlying file and the internal buffer.
   **/
  ~FileReader();

  /**
   * Read a single byte from the currently open input file. You should
   * call @ref Open before calling this method. The internal buffer is
   * used to reduce the number of reads performed on the underlying
   * file.
   *
   * @return the read byte or -1 if EOF was reached or an error occurred.
   **/
  int ReadByte()
  {
    if(_bufpos == _bufused)
      FillBuffer();
    return (_bufused > _bufpos) ? (_buf[_bufpos++] & 0x0ff) : -1;
  }

  /**
   * Open a file for reading.
   *
   * @return success(true)/failure(false)
   * @param filename the name of the file to open.
   **/
  bool Open(const char *filename);

  /**
   * Open the standard input for reading.
   *
   * @return success(true)/failure(false)
   **/
  bool OpenStdin();

  /**
   * Reset the file pointer and flush the internal buffer. The next
   * read operation will apply to the beginning of the file.
   *
   * @return success(true)/failure(false)
   **/
  bool Reset();

  /**
   * Works like Reset(), but sets the file pointer to 'pos
   **/
  bool SetFilePos(int64_t pos);

  /**
   * @return size of file in bytes
   **/
  int64_t GetFileSize();

  /**
   * @returns _bufpos
   **/
  uint64_t GetBufPos() const { return _bufpos; }

  uint64_t GetFilePos() const { return _lastReadPos + _bufpos; }

  /**
   * @returns offset of next newline from pos
   **/
  uint64_t FindNewline(int64_t pos);

  /**
   * Read the next line of text from the the currently open file into
   * 'buf'. If the line is longer than ('bufsize' - 1), the first
   * ('bufsize' - 1) bytes will be placed in 'buf' and the true length
   * of the line will be returned. The string placed in 'buf' will be
   * terminated with a null character. Newline characters will be
   * discarded. A line is terminated by either '\n', '\r', "\r\n",
   * "\n\r" or EOF. This method uses @ref ReadByte to read single
   * bytes from the file.
   *
   * @return the actual length of the next line, or -1 if no line was read.
   * @param buf where to put the line.
   * @param bufsize the length of buf.
   **/
  ssize_t ReadLine(char *buf, size_t bufsize);

  /**
   * Close the file.
   **/
  void Close();
};