00001 #ifndef UTIL_FILE_PIECE__
00002 #define UTIL_FILE_PIECE__
00003
00004 #include "util/ersatz_progress.hh"
00005 #include "util/exception.hh"
00006 #include "util/file.hh"
00007 #include "util/mmap.hh"
00008 #include "util/read_compressed.hh"
00009 #include "util/string_piece.hh"
00010
00011 #include <cstddef>
00012 #include <iosfwd>
00013 #include <string>
00014
00015 #include <stdint.h>
00016
00017 namespace util {
00018
00019 class ParseNumberException : public Exception {
00020 public:
00021 explicit ParseNumberException(StringPiece value) throw();
00022 ~ParseNumberException() throw() {}
00023 };
00024
00025 extern const bool kSpaces[256];
00026
00027
00028 class FilePiece {
00029 public:
00030
00031 explicit FilePiece(const char *file, std::ostream *show_progress = NULL, std::size_t min_buffer = 1048576);
00032
00033 explicit FilePiece(int fd, const char *name = NULL, std::ostream *show_progress = NULL, std::size_t min_buffer = 1048576);
00034
00035
00036
00037
00038
00039
00040 explicit FilePiece(std::istream &stream, const char *name = NULL, std::size_t min_buffer = 1048576);
00041
00042 ~FilePiece();
00043
00044 char get() {
00045 if (position_ == position_end_) {
00046 Shift();
00047 if (at_end_) throw EndOfFileException();
00048 }
00049 return *(position_++);
00050 }
00051
00052
00053 StringPiece ReadDelimited(const bool *delim = kSpaces) {
00054 SkipSpaces(delim);
00055 return Consume(FindDelimiterOrEOF(delim));
00056 }
00057
00058
00059
00060 StringPiece ReadLine(char delim = '\n');
00061
00062 float ReadFloat();
00063 double ReadDouble();
00064 long int ReadLong();
00065 unsigned long int ReadULong();
00066
00067
00068 void SkipSpaces(const bool *delim = kSpaces) {
00069 for (; ; ++position_) {
00070 if (position_ == position_end_) Shift();
00071 if (!delim[static_cast<unsigned char>(*position_)]) return;
00072 }
00073 }
00074
00075 uint64_t Offset() const {
00076 return position_ - data_.begin() + mapped_offset_;
00077 }
00078
00079 const std::string &FileName() const { return file_name_; }
00080
00081 private:
00082 void InitializeNoRead(const char *name, std::size_t min_buffer);
00083
00084 void Initialize(const char *name, std::ostream *show_progress, std::size_t min_buffer);
00085
00086 template <class T> T ReadNumber();
00087
00088 StringPiece Consume(const char *to) {
00089 StringPiece ret(position_, to - position_);
00090 position_ = to;
00091 return ret;
00092 }
00093
00094 const char *FindDelimiterOrEOF(const bool *delim = kSpaces);
00095
00096 void Shift();
00097
00098 void MMapShift(uint64_t desired_begin);
00099
00100 void TransitionToRead();
00101 void ReadShift();
00102
00103 const char *position_, *last_space_, *position_end_;
00104
00105 scoped_fd file_;
00106 const uint64_t total_size_;
00107 const uint64_t page_;
00108
00109 std::size_t default_map_size_;
00110 uint64_t mapped_offset_;
00111
00112
00113 scoped_memory data_;
00114
00115 bool at_end_;
00116 bool fallback_to_read_;
00117
00118 ErsatzProgress progress_;
00119
00120 std::string file_name_;
00121
00122 ReadCompressed fell_back_;
00123 };
00124
00125 }
00126
00127 #endif // UTIL_FILE_PIECE__