Scopira  20080306
cacheflow.h
1 
2 /*
3  * Copyright (c) 2003 National Research Council
4  *
5  * All rights reserved.
6  *
7  * This material is confidential and proprietary information of
8  * National Research Council Canada ("Confidential Information").
9  * This Confidential Information may only be used and reproduced
10  * in accordance with the terms of the license agreement.
11  *
12  */
13 
14 #ifndef __INCLUDED_SCOPIRA_TOOL_CACHEFLOW_H__
15 #define __INCLUDED_SCOPIRA_TOOL_CACHEFLOW_H__
16 
17 #include <scopira/tool/array.h>
18 #include <scopira/tool/flow.h>
19 #include <scopira/tool/export.h>
20 
21 #include <assert.h>
22 
23 namespace scopira
24 {
25  namespace tool
26  {
27  template <class T> class circular_vector;
28 
29  class cacheiflow;
30  class cacheoflow;
31  }
32 }
33 
38 template <class T> class scopira::tool::circular_vector
39 {
40  public:
41  typedef T data_type;
42  typedef typename basic_array<T>::iterator iterator;
43  typedef typename basic_array<T>::const_iterator const_iterator;
44  private:
46  typedef basic_array<T> arr_type;
47  protected:
48  arr_type dm_ary; // its actually 1 longer than we need
49  iterator dm_read, dm_write;
50  public:
52  explicit circular_vector(size_t reserve_size = 0);
55  void reserve(size_t reserve_size);
56 
57  iterator begin1(void) { return dm_read; }
58  iterator end1(void)
59  { return (dm_write<dm_read) ? dm_ary.end() : dm_write; }
60  const_iterator begin1(void) const { return dm_read; }
61  const_iterator end1(void) const
62  { return (dm_write<dm_read) ? dm_ary.end() : dm_write; }
63  iterator begin2(void) { return dm_ary.begin(); }
64  iterator end2(void)
65  { return (dm_write<dm_read) ? dm_write : dm_ary.begin(); }
66  const_iterator begin2(void) const { return dm_ary.begin(); }
67  const_iterator end2(void) const
68  { return (dm_write<dm_read) ? dm_write : dm_ary.begin(); }
69 
71  bool empty(void) const { return dm_read == dm_write; }
73  bool full(void) const
74  { return (dm_write+1 == dm_read) ||
75  (dm_read == dm_ary.begin() && dm_write == dm_ary.end()-1); }
77  size_t size(void) const;
79  size_t capacity(void) const { return dm_ary.size() - 1; }
81  size_t free(void) const { return capacity() - size(); }
83  void clear(void) { dm_read = dm_write = dm_ary.begin(); }
84 
86  const T & front(void) const { return *dm_read; }
88  void push_back(const T &item);
90  void pop_front(void);
92  void pop_all(void) { dm_read = dm_write = dm_ary.begin(); }
94  template <class ITER>
95  void push_back(ITER head, ITER tail);
98  template <class ITER>
99  ITER pop_front(ITER head, ITER tail);
100 
102  void push_seek(size_t sz) { dm_write += sz; assert(dm_write<dm_ary.end()); }
104  void short_rewind(void) { dm_read = dm_ary.begin(); }
105 };
106 
107 //
108 //
109 // circular_vector
110 //
111 //
112 
113 template <class T>
115  : dm_ary(reserve_size+1)
116 {
117  if (reserve_size>0)
118  dm_write = dm_read = dm_ary.begin();
119 }
120 
121 template <class T>
123 {
124  dm_ary.resize(reserve_size+1);
125  if (reserve_size>0)
126  dm_write = dm_read = dm_ary.begin();
127 }
128 
129 template <class T>
131 {
132  if (dm_write >= dm_read)
133  return dm_write - dm_read;
134  else
135  return dm_ary.size() + (dm_write - dm_read);
136 }
137 
138 template <class T>
140 {
141  *dm_write = item;
142  ++dm_write;
143  assert(dm_read != dm_write); // easier to do this check here
144 }
145 
146 template <class T>
148 {
149  assert(!empty());
150 
151  ++dm_read;
152  if (dm_read == dm_ary.end())
153  dm_read = dm_ary.begin();
154 }
155 
156 template <class T> template <class ITER>
158 {
159  assert(free() >= (tail - head));
160 
161  // 2-part write
162  while (head != tail && dm_write != dm_ary.end()) {
163  *dm_write = *head;
164  ++head;
165  ++dm_write;
166  }
167 
168  if (dm_write == dm_ary.end())
169  dm_write = dm_ary.begin();
170  else
171  return; // 1 part was enough, i guess
172 
173  while (head != tail) {
174  *dm_write = *head;
175  ++head;
176  ++dm_write;
177  }
178 }
179 
180 template <class T> template <class ITER>
182 {
183  iterator endend;
184 
185  endend = dm_write < dm_read ? dm_ary.end() : dm_write;
186  // 2-part write
187  while (head != tail && dm_read != endend) {
188  *head = *dm_read;
189  ++head;
190  ++dm_read;
191  }
192 
193  if (head != tail && !empty())
194  dm_read = dm_ary.begin();
195  else
196  return head; // 1 part was enough, i guess
197 
198  while (head != tail && dm_read != dm_write) {
199  *head = *dm_read;
200  ++head;
201  ++dm_read;
202  }
203 
204  return head;
205 }
211 {
212  protected:
213  count2_ptr< iflow_i > dm_in;
214  circular_vector<byte_t> dm_cache;
215  bool dm_failed;
216 
217  public:
226  SCOPIRA_EXPORT cacheiflow(bool doref, iflow_i* innie, size_t buffersize = 32768);
227 
229  SCOPIRA_EXPORT virtual bool failed(void) const { return dm_failed; }
230 
232  SCOPIRA_EXPORT virtual size_t read(byte_t* _buf, size_t _maxsize);
234  SCOPIRA_EXPORT virtual size_t read_byte(byte_t &out);
235 
237  SCOPIRA_EXPORT void open(iflow_i* in);
239  SCOPIRA_EXPORT void close(void);
240 
244  SCOPIRA_EXPORT void short_rewind(void);
245 
247  SCOPIRA_EXPORT void load_cache(void);
248 };
249 
255 {
256  protected:
257  count2_ptr< oflow_i > dm_out;
258  circular_vector<byte_t> dm_cache;
259  bool dm_failed;
260 
261  public:
270  SCOPIRA_EXPORT cacheoflow(bool doref, oflow_i* out, size_t buffersize = 32768);
272  SCOPIRA_EXPORT ~cacheoflow();
273 
275  SCOPIRA_EXPORT virtual bool failed(void) const { return dm_failed; }
276 
278  SCOPIRA_EXPORT virtual size_t write(const byte_t* _buf, size_t _size);
280  SCOPIRA_EXPORT virtual size_t write_byte(byte_t b);
281 
283  SCOPIRA_EXPORT void open(oflow_i* in);
285  SCOPIRA_EXPORT void close(void);
286 
290  SCOPIRA_EXPORT void flush_cache(void);
291 };
292 
293 #endif
void reserve(size_t reserve_size)
Definition: cacheflow.h:122
Definition: flow.h:108
size_t free(void) const
how much room is left
Definition: cacheflow.h:81
Definition: archiveflow.h:20
bool full(void) const
(current) buffer full?
Definition: cacheflow.h:73
circular_vector(size_t reserve_size=0)
ctor
Definition: cacheflow.h:114
iterator begin(void)
Definition: array.h:361
Definition: object.h:43
void clear(void)
pop_all elements
Definition: cacheflow.h:83
const T & front(void) const
gets the front item on the buffer
Definition: cacheflow.h:86
Definition: array.h:30
size_t size(void) const
gets the current (used) size
Definition: cacheflow.h:130
iterator end(void)
Definition: array.h:366
Definition: cacheflow.h:254
void short_rewind(void)
special kind of rewind
Definition: cacheflow.h:104
virtual bool failed(void) const
are we in a failed state?
Definition: cacheflow.h:229
Definition: cacheflow.h:27
Definition: cacheflow.h:210
bool empty(void) const
(current) buffer empty?
Definition: cacheflow.h:71
void push_seek(size_t sz)
special kind of push
Definition: cacheflow.h:102
size_t capacity(void) const
gets the total capacity of the buffer
Definition: cacheflow.h:79
void pop_front(void)
pop one item from the front of the buffer
Definition: cacheflow.h:147
size_t size(void) const
Definition: array.h:400
void resize(size_t newlen)
Definition: array.h:464
void push_back(const T &item)
push one element to the back of the buffer
Definition: cacheflow.h:139
Definition: flow.h:159
void pop_all(void)
pop_all elements (same as clear())
Definition: cacheflow.h:92
virtual bool failed(void) const
are we in a failed state?
Definition: cacheflow.h:275