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 <tawara/block_element.h>
43 #include <tawara/block_group.h>
44 #include <tawara/cluster.h>
45 #include <tawara/simple_block.h>
46 #include <tawara/win_dll.h>
47 
50 
51 namespace tawara
52 {
63  {
64  public:
66  typedef boost::shared_ptr<FileCluster> Ptr;
67 
73  FileCluster(uint64_t timecode=0);
74 
76  // Iterator types
78 
79  template <typename BlockType>
81  : public boost::iterator_facade<
82  IteratorBase<BlockType>, BlockType,
83  boost::forward_traversal_tag>
84  {
85  private:
86  struct enabler {};
87 
88  public:
94  : cluster_(0)
95  {
96  }
97 
105  IteratorBase(FileCluster const* cluster,
106  std::istream& stream, std::streampos pos)
107  : cluster_(cluster), stream_(&stream)
108  {
109  // Open the block at the provided position
110  load_block(pos);
111  }
112 
118  template <typename OtherType>
120  : cluster_(other.cluster_), stream_(other.stream_),
121  block_(other.block_)
122  {
123  }
124 
125  protected:
126  // Necessary for Boost::iterator implementation.
127  friend class boost::iterator_core_access;
128 
129  // Integrate with owning container.
130  friend class FileCluster;
131 
133  std::istream* stream_;
134  boost::shared_ptr<BlockType> block_;
135 
136  void load_block(std::streampos pos)
137  {
138  if (pos == cluster_->blocks_end_pos_)
139  {
140  // End of the blocks
141  block_.reset();
142  }
143  else
144  {
145  // Save the current read position
146  std::streampos cur_read(stream_->tellg());
147  // Jump to the expected block location
148  stream_->seekg(pos);
149  // Read the block
150  ids::ReadResult id_res = ids::read(*stream_);
151  if (id_res.first == ids::SimpleBlock)
152  {
153  BlockElement::Ptr new_block(new SimpleBlock(0, 0));
154  new_block->read(*stream_);
155  // TODO Ick. Needs fixing.
156  boost::shared_ptr<BlockType> new_const_block(new_block);
157  block_.swap(new_const_block);
158  }
159  else if (id_res.first == ids::BlockGroup)
160  {
161  BlockElement::Ptr new_block(new BlockGroup(0, 0));
162  new_block->read(*stream_);
163  // TODO Ick. Needs fixing.
164  boost::shared_ptr<BlockType> new_const_block(new_block);
165  block_.swap(new_const_block);
166  }
167  else
168  {
169  throw InvalidChildID() << err_id(id_res.first) <<
170  err_par_id(cluster_->id_) <<
171  // The cast here makes Apple's LLVM compiler happy
172  err_pos(static_cast<std::streamsize>(stream_->tellg()) -
173  id_res.second);
174  }
175  // Return to the original read position
176  stream_->seekg(cur_read);
177  }
178  }
179 
181  void increment()
182  {
183  // Don't increment if at the end
184  if (block_)
185  {
186  // Load the block after this one
187  load_block(block_->offset() + block_->size());
188  }
189  }
190 
195  template <typename OtherType>
196  bool equal(IteratorBase<OtherType> const& other) const
197  {
198  if (block_)
199  {
200  // This iterator is not at the end
201  if (other.block_)
202  {
203  // Neither is the other
204  return block_->offset() ==
205  other.block_->offset();
206  }
207  return false;
208  }
209  else
210  {
211  // This iterator is at the end
212  if (!other.block_)
213  {
214  // So is the other
215  return true;
216  }
217  return false;
218  }
219  }
220 
224  BlockType& dereference() const
225  {
226  return *block_;
227  }
228  }; // class IteratorBase
229 
235 
237  // Iterator access
239 
244  Iterator begin();
249  Iterator end();
250 
251 
253  // Cluster interface
255 
257  virtual bool empty() const;
259  virtual size_type count() const;
265  virtual void clear();
266 
274  virtual void erase(Iterator position);
283  virtual void erase(Iterator first, Iterator last);
284 
290  virtual void push_back(value_type const& value);
291 
293  std::streamsize write(std::ostream& output);
294 
296  std::streamsize finalise(std::ostream& output);
297 
298  protected:
299  std::ostream* ostream_;
300  std::istream* istream_;
301  std::streampos blocks_start_pos_;
302  std::streampos blocks_end_pos_;
303 
305  std::streamsize blocks_size() const;
306 
308  std::streamsize read_blocks(std::istream& input,
309  std::streamsize size);
310  }; // class FileCluster
311 }; // namespace tawara
312 
314 // group elements
315 
316 #endif // TAWARA_FILE_CLUSTER_H_
317 
std::streampos blocks_end_pos_
Definition: file_cluster.h:302
std::streampos blocks_start_pos_
Definition: file_cluster.h:301
void load_block(std::streampos pos)
Definition: file_cluster.h:136
BlockType & dereference() const
Dereference the iterator to get a pointer to the block.
Definition: file_cluster.h:224
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:62
#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:196
std::ostream * ostream_
Definition: file_cluster.h:299
A child element was found where it doesn&#39;t belong.
Definition: exceptions.h:249
void increment()
Increment the iterator to the next block.
Definition: file_cluster.h:181
boost::shared_ptr< BlockType > block_
Definition: file_cluster.h:134
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:105
boost::shared_ptr< FileCluster > Ptr
Pointer to a file-based cluster.
Definition: file_cluster.h:66
const ID SimpleBlock(0xA3)
IteratorBase()
Base constructor.
Definition: file_cluster.h:93
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:234
IteratorBase(IteratorBase< OtherType > const &other)
Templated base constructor.
Definition: file_cluster.h:119
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:300
size_t size_type
The size type of this container.
Definition: cluster.h:158
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