00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __BUF_STREAM_HH
00019 # define __BUF_STREAM_HH
00020
00021 # include <forward_list>
00022 # include <istream>
00023 # include <sstream>
00024 # include "hash/hash_addr.hh"
00025
00026 namespace aurelia {
00027
00028 struct rc_char {
00029 int refs;
00030 char c;
00031 rc_char(char c): refs(0), c(c){}
00032 rc_char(const rc_char& other): refs(other.refs), c(other.c) {}
00033 };
00034
00035 struct buf_stream;
00036
00037 struct buf_stream_iterator {
00038 private:
00039 buf_stream* s;
00040 std::forward_list<rc_char>::iterator i;
00041 int pos;
00042
00043 friend class buf_stream;
00044 explicit buf_stream_iterator(buf_stream* s,
00045 const std::forward_list<rc_char>::iterator& i,
00046 int pos);
00047 public:
00048 unsigned hash() const;
00049
00050 int get_pos() const {
00051 return pos;
00052 }
00053
00054 bool operator==(const buf_stream_iterator& other) const;
00055
00056 bool operator!=(const buf_stream_iterator& other) const {
00057 return !(*this == other);
00058 }
00059
00060 bool operator<(const buf_stream_iterator& other) const {
00061 return pos < other.pos;
00062 }
00063
00064 ~buf_stream_iterator();
00065
00066 buf_stream_iterator& operator++();
00067
00068 buf_stream_iterator(const buf_stream_iterator&);
00069 buf_stream_iterator(buf_stream_iterator&&);
00070
00071 char operator*() const {
00072 return (*i).c;
00073 }
00074
00075 bool eof() const;
00076
00077 buf_stream_iterator& operator=(const buf_stream_iterator& other) {
00078 return *this = buf_stream_iterator(other);
00079 }
00080
00081 buf_stream_iterator& operator=(buf_stream_iterator&& other);
00082
00083 bool eat(const std::string& s) {
00084 std::string::const_iterator i = s.begin();
00085 buf_stream_iterator t(*this);
00086 while (!t.eof() && (i != s.end())) {
00087 if (*i != *t)
00088 return false;
00089 ++i;
00090 ++t;
00091 }
00092 if (i != s.end())
00093 return false;
00094 *this = t;
00095 return true;
00096 }
00097 };
00098
00099 struct buf_stream {
00100 private:
00101 std::istream* real_stream;
00102 std::forward_list<rc_char> buf;
00103 int start;
00104 unsigned _hash;
00105 #ifndef NDEBUG
00106 int size;
00107 #endif
00108
00109 public:
00110 buf_stream(const buf_stream&) = delete;
00111 buf_stream(buf_stream&&) = delete;
00112
00113 #ifndef NDEBUG
00114 int buffer_start() const {
00115 return start;
00116 }
00117
00118
00119 int buffer_size() const {
00120 return size;
00121 }
00122 #endif
00123
00124 explicit buf_stream(std::istream& s): real_stream(&s)
00125 , start(0)
00126 #ifndef NDEBUG
00127 , size(0)
00128 #endif
00129 {
00130 _hash = hash_addr(s);
00131 }
00132
00133 unsigned hash() const {
00134 return _hash;
00135 }
00136
00137 buf_stream& operator=(const buf_stream&) = delete;
00138 buf_stream& operator=(buf_stream&&) = delete;
00139
00140 buf_stream_iterator begin() {
00141 std::forward_list<rc_char>::iterator i = buf.begin();
00142 if (i == buf.end()) {
00143 char c = real_stream->get();
00144 #ifndef NDEBUG
00145 size++,
00146 #endif
00147 buf.push_front(rc_char(c));
00148 }
00149 return buf_stream_iterator(this, buf.begin(), start);
00150 }
00151
00152 buf_stream_iterator end() {
00153 std::forward_list<rc_char>::iterator i = buf.end();
00154 return buf_stream_iterator(this, i, -1);
00155 }
00156
00157 std::forward_list<rc_char>::iterator buf_end() {
00158 return buf.end();
00159 }
00160
00161 void cleanup () {
00162 std::forward_list<rc_char>::iterator i = buf.begin();
00163 while (i != buf.end()) {
00164 if ((*i++).refs == 0) {
00165 start++;
00166 #ifndef NDEBUG
00167 size--;
00168 #endif
00169 buf.pop_front();
00170 }
00171 else return ;
00172 }
00173 }
00174
00175 bool is_end(const std::forward_list<rc_char>::iterator& i) const {
00176 return i == buf.end();
00177 }
00178
00179 void next(std::forward_list<rc_char>::iterator& i) {
00180 std::forward_list<rc_char>::iterator next = i;
00181 ++next;
00182 if (next == buf.end()) {
00183 char c = real_stream->get();
00184 if (!real_stream->good()) {
00185 i = next;
00186 return ;
00187 }
00188 buf.insert_after(i,rc_char(c));
00189 #ifndef NDEBUG
00190 size++;
00191 #endif
00192 ++i;
00193 return ;
00194 }
00195 i = next;
00196 }
00197 };
00198
00199 buf_stream_iterator::buf_stream_iterator(buf_stream* s,
00200 const std::forward_list<rc_char>
00201 ::iterator& i, int pos)
00202 : s(s), i(i), pos(pos) {
00203 if (pos != -1)
00204 (*i).refs++;
00205 }
00206 buf_stream_iterator::buf_stream_iterator(const buf_stream_iterator& other)
00207 : s(other.s), i(other.i), pos(other.pos) {
00208 if (!(s->is_end(i)))
00209 (*i).refs++;
00210 }
00211
00212 buf_stream_iterator::buf_stream_iterator(buf_stream_iterator&& other)
00213 : s(other.s), i(s->buf_end()), pos(other.pos) {
00214 std::swap(i, other.i);
00215 other.pos = -1;
00216 }
00217
00218 buf_stream_iterator::~buf_stream_iterator()
00219 {
00220 if (!s->is_end(i)) {
00221 if (--((*i).refs) == 0)
00222 s->cleanup();
00223 }
00224 }
00225
00226 buf_stream_iterator& buf_stream_iterator::operator++() {
00227 std::forward_list<rc_char>::iterator prev(i);
00228 s->next(i);
00229 pos++;
00230 if (!s->is_end(i)) {
00231 (*i).refs++;
00232 }
00233 if (--((*prev).refs) == 0)
00234 s->cleanup();
00235 return *this;
00236 }
00237
00238 bool buf_stream_iterator::eof() const {
00239 return (s->is_end(i));
00240 }
00241
00242 buf_stream_iterator& buf_stream_iterator::operator=
00243 (buf_stream_iterator&& other) {
00244 std::swap(s, other.s);
00245 std::swap(pos, other.pos);
00246 std::swap(i, other.i);
00247 return *this;
00248 }
00249
00250 unsigned buf_stream_iterator::hash() const {
00252 unsigned hash = (unsigned)pos;
00253 hash = (hash << 11) | (hash >> 21);
00254 hash ^= s->hash();
00255 return hash;
00256 }
00257
00258 bool buf_stream_iterator::operator==(const buf_stream_iterator& other) const {
00259 if (pos == -1) {
00260 return s->is_end(other.i);
00261 }
00262 if (other.pos == -1) {
00263 return s->is_end(i);
00264 }
00265 return (s == other.s) && (pos == other.pos);
00266 }
00267
00268 typedef buf_stream_iterator stream;
00269
00270 std::string stream_range_to_string(stream begin, const stream& end) {
00271 std::stringstream ret;
00272 while (begin != end) {
00273 ret << *begin;
00274 ++begin;
00275 }
00276 return ret.str();
00277 }
00278
00279 template <typename Stream>
00280 Stream& operator<<(Stream& s, const stream& i) {
00281 s << "(stream:" << i.get_pos() << ")";
00282 return s;
00283 }
00284 }
00285
00286 #endif