Tawara  0.1.0
file_cluster.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, 2012, Geoffrey Biggs, geoffrey.biggs@aist.go.jp
5  * RT-Synthesis Research Group
6  * Intelligent Systems Research Institute,
7  * National Institute of Advanced Industrial Science and Technology (AIST),
8  * Japan
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * * Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above
18  * copyright notice, this list of conditions and the following
19  * disclaimer in the documentation and/or other materials provided
20  * with the distribution.
21  * * Neither the name of Geoffrey Biggs nor AIST, nor the names of its
22  * contributors may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #if !defined(TAWARA_FILE_CLUSTER_H_)
40 #define TAWARA_FILE_CLUSTER_H_
41 
42 #include <boost/iterator/iterator_facade.hpp>
43 #include <tawara/block_element.h>
44 #include <tawara/block_group.h>
45 #include <tawara/cluster.h>
46 #include <tawara/simple_block.h>
47 #include <tawara/win_dll.h>
48 
51 
52 namespace tawara
53 {
64  {
65  public:
67  typedef boost::shared_ptr<FileCluster> Ptr;
68 
74  FileCluster(uint64_t timecode=0);
75 
77  // Iterator types
79 
80  template <typename BlockType>
82  : public boost::iterator_facade<
83  IteratorBase<BlockType>, BlockType,
84  boost::forward_traversal_tag>
85  {
86  private:
87  struct enabler {};
88 
89  public:
95  : cluster_(0)
96  {
97  }
98 
106  IteratorBase(FileCluster const* cluster,
107  std::istream& stream, std::streampos pos)
108  : cluster_(cluster), stream_(&stream)
109  {
110  // Open the block at the provided position
111  load_block(pos);
112  }
113 
119  template <typename OtherType>
121  : cluster_(other.cluster_), stream_(other.stream_),
122  block_(other.block_)
123  {
124  }
125 
126  protected:
127  // Necessary for Boost::iterator implementation.
128  friend class boost::iterator_core_access;
129 
130  // Integrate with owning container.
131  friend class FileCluster;
132 
134  std::istream* stream_;
135  boost::shared_ptr<BlockType> block_;
136 
137  void load_block(std::streampos pos)
138  {
139  if (pos == cluster_->blocks_end_pos_)
140  {
141  // End of the blocks
142  block_.reset();
143  }
144  else
145  {
146  // Save the current read position
147  std::streampos cur_read(stream_->tellg());
148  // Jump to the expected block location
149  stream_->seekg(pos);
150  // Read the block
151  ids::ReadResult id_res = ids::read(*stream_);
152  if (id_res.first == ids::SimpleBlock)
153  {
154  BlockElement::Ptr new_block(new SimpleBlock(0, 0));
155  new_block->read(*stream_);
156  // TODO Ick. Needs fixing.
157  boost::shared_ptr<BlockType> new_const_block(new_block);
158  block_.swap(new_const_block);
159  }
160  else if (id_res.first == ids::BlockGroup)
161  {
162  BlockElement::Ptr new_block(new BlockGroup(0, 0));
163  new_block->read(*stream_);
164  // TODO Ick. Needs fixing.
165  boost::shared_ptr<BlockType> new_const_block(new_block);
166  block_.swap(new_const_block);
167  }
168  else
169  {
170  throw InvalidChildID() << err_id(id_res.first) <<
171  err_par_id(cluster_->id_) <<
172  // The cast here makes Apple's LLVM compiler happy
173  err_pos(static_cast<std::streamsize>(stream_->tellg()) -
174  id_res.second);
175  }
176  // Return to the original read position
177  stream_->seekg(cur_read);
178  }
179  }
180 
182  void increment()
183  {
184  // Don't increment if at the end
185  if (block_)
186  {
187  // Load the block after this one
188  load_block(block_->offset() + block_->size());
189  }
190  }
191 
196  template <typename OtherType>
197  bool equal(IteratorBase<OtherType> const& other) const
198  {
199  if (block_)
200  {
201  // This iterator is not at the end
202  if (other.block_)
203  {
204  // Neither is the other
205  return block_->offset() ==
206  other.block_->offset();
207  }
208  return false;
209  }
210  else
211  {
212  // This iterator is at the end
213  if (!other.block_)
214  {
215  // So is the other
216  return true;
217  }
218  return false;
219  }
220  }
221 
225  BlockType& dereference() const
226  {
227  return *block_;
228  }
229  }; // class IteratorBase
230 
236 
238  // Iterator access
240 
245  Iterator begin();
250  Iterator end();
251 
252 
254  // Cluster interface
256 
258  virtual bool empty() const;
260  virtual size_type count() const;
266  virtual void clear();
267 
275  virtual void erase(Iterator position);
284  virtual void erase(Iterator first, Iterator last);
285 
291  virtual void push_back(value_type const& value);
292 
294  std::streamsize write(std::ostream& output);
295 
297  std::streamsize finalise(std::ostream& output);
298 
299  protected:
300  std::ostream* ostream_;
301  std::istream* istream_;
302  std::streampos blocks_start_pos_;
303  std::streampos blocks_end_pos_;
304 
306  std::streamsize blocks_size() const;
307 
309  std::streamsize read_blocks(std::istream& input,
310  std::streamsize size);
311  }; // class FileCluster
312 }; // namespace tawara
313 
315 // group elements
316 
317 #endif // TAWARA_FILE_CLUSTER_H_
318 
std::streampos blocks_end_pos_
Definition: file_cluster.h:303
std::streampos blocks_start_pos_
Definition: file_cluster.h:302
void load_block(std::streampos pos)
Definition: file_cluster.h:137
BlockType & dereference() const
Dereference the iterator to get a pointer to the block.
Definition: file_cluster.h:225
std::streamsize write(ID id, std::ostream &output)
Write an ID to an output stream.
boost::shared_ptr< BlockElement > Ptr
Definition: block_element.h:57
std::streamsize size(ID id)
Get the number of bytes required by an ID.
The in-file Cluster implementation.
Definition: file_cluster.h:63
#define TAWARA_EXPORT
Definition: win_dll.h:51
BlockElement::Ptr value_type
The value type of this container.
Definition: cluster.h:156
bool equal(IteratorBase< OtherType > const &other) const
Test for equality with another iterator.
Definition: file_cluster.h:197
std::ostream * ostream_
Definition: file_cluster.h:300
A child element was found where it doesn't belong.
Definition: exceptions.h:249
void increment()
Increment the iterator to the next block.
Definition: file_cluster.h:182
boost::shared_ptr< BlockType > block_
Definition: file_cluster.h:135
ReadResult read(std::istream &input)
Read an ID from an input stream.
const ID BlockGroup(0xA0)
IteratorBase(FileCluster const *cluster, std::istream &stream, std::streampos pos)
Base constructor.
Definition: file_cluster.h:106
boost::shared_ptr< FileCluster > Ptr
Pointer to a file-based cluster.
Definition: file_cluster.h:67
const ID SimpleBlock(0xA3)
IteratorBase()
Base constructor.
Definition: file_cluster.h:94
boost::error_info< struct tag_par_id, uint32_t > err_par_id
A parent element ID.
Definition: exceptions.h:533
The base Cluster, defining the common interface for Cluster element implementations.
Definition: cluster.h:150
IteratorBase< BlockElement > Iterator
File-based cluster iterator interface.
Definition: file_cluster.h:235
IteratorBase(IteratorBase< OtherType > const &other)
Templated base constructor.
Definition: file_cluster.h:120
boost::error_info< struct tag_id, ids::ID > err_id
An Element ID.
Definition: exceptions.h:530
boost::error_info< struct tag_pos, std::streamsize > err_pos
Position in a Tawara file.
Definition: exceptions.h:514
std::istream * istream_
Definition: file_cluster.h:301
size_t size_type
The size type of this container.
Definition: cluster.h:158
tawara::ids::ID id_
Definition: element.h:166
std::pair< ID, std::streamsize > ReadResult
The result of a read operation is a pair of the ID read and the number of bytes read.
Definition: el_ids.h:256