Tide 0.1.0
|
The base Cluster, defining the common interface for Cluster element implementations. More...
#include <tide/cluster.h>
Public Types | |
typedef boost::shared_ptr < Cluster > | Ptr |
Pointer to a cluster. | |
typedef BlockElement::Ptr | value_type |
The value type of this container. | |
typedef size_t | size_type |
The size type of this container. | |
typedef value_type & | reference |
The reference type. | |
typedef value_type const & | const_reference |
The constant reference type. | |
Public Member Functions | |
Cluster (uint64_t timecode=0) | |
Construct a new Cluster. | |
virtual | ~Cluster () |
Destructor. | |
virtual bool | empty () const =0 |
Check if there are no blocks. | |
virtual size_type | count () const =0 |
Get the number of blocks. | |
virtual void | clear ()=0 |
Remove all blocks. | |
virtual void | push_back (value_type const &value)=0 |
Erase the block at the specified iterator. | |
uint64_t | timecode () const |
Get the cluster's timecode. | |
void | timecode (uint64_t timecode) |
Set the cluster's timecode. | |
std::vector< SilentTrackNumber > & | silent_tracks () |
Get the list of silent tracks. | |
uint64_t | position () const |
Get the position of this cluster in the segment. | |
uint64_t | previous_size () const |
Get the size of the previous cluster in the segment. | |
void | previous_size (uint64_t size) |
Set the size of the previous cluster in the segment. | |
std::streamsize | size () const |
Get the total size of the element. | |
std::streamsize | read (std::istream &input) |
Element reading. | |
virtual std::streamsize | finalise (std::ostream &output)=0 |
Finalise writing of the cluster. | |
Protected Member Functions | |
std::streamsize | meta_size () const |
Get the size of the meta-data portion of the body of. | |
std::streamsize | body_size () const |
Get the size of the body of this element. | |
std::streamsize | write_size (std::ostream &output) |
Element size writing. | |
std::streamsize | write_body (std::ostream &output) |
Element body writing. | |
std::streamsize | read_body (std::istream &input, std::streamsize size) |
Element body loading. | |
virtual std::streamsize | blocks_size () const =0 |
Get the size of the blocks in this cluster. | |
virtual std::streamsize | read_blocks (std::istream &input, std::streamsize size)=0 |
Read the blocks in this cluster from the output stream. | |
std::streamsize | read_silent_tracks (std::istream &input) |
Read the SilentTracks child element. | |
virtual void | reset () |
Reset the cluster's members to default values. | |
Protected Attributes | |
UIntElement | timecode_ |
std::vector< SilentTrackNumber > | silent_tracks_ |
UIntElement | position_ |
UIntElement | prev_size_ |
std::streamsize | size_ |
The size of the cluster. | |
bool | writing_ |
The base Cluster, defining the common interface for Cluster element implementations.
This class is the base class for all Cluster implementations. Different concrete implementations of this interface implement reading and writing of blocks in different ways. The two most commonly-used implementations are the in-memory cluster and the streamed-writing cluster.
Because of their nature as streamed data, Clusters are the most complex element to write. They are often written in stages, with a dummy size value and the other data written first, before the blocks are streamed in, and finally the correct size value written over the dummy size value at the start of the cluster. Alternative implementations may store all cluster data in memory (or even in another file) before writing the cluster in one hit.
The Cluster interface supports both streaming and all-at-once approaches to writing. The sequence of method calls is the same for both cases, but what is done for each call varies. The sequence of method calls that must be performed is:
* cluster.write(output) * || * \/ * [Capture blocks] * || * \/ * cluster.finalise(output) *
The purpose of the write step is to allow Cluster implementations that use stream-based writing to prepare the file for writing the blocks. The finalise step is used to finalise the cluster in the file, ensuring, for example, that the correct size value is written into the element header.
For a Cluster implementation that stores the block data elsewhere (e.g. in memory) before writing the entire cluster in one go, the method calls could be implemented to do the following:
* cluster.write(output) -> Prepare space outside of the file to store * || the blocks while they are accumulated. For * || example, a block of memory could be * || allocated to store the blocks. * \/ * [Capture blocks] -> Store blocks in the reserved space. * || * \/ * cluster.finalise(output) -> Write the Cluster ID and size (calculated * from the stored blocks), followed by the * other Cluster fields, and then the stored * blocks. *
For a Cluster implementation that streams the blocks directly into the file as they arrive, the method calls could be implemented to do the following:
* cluster.write(output) -> Write the Cluster ID with a base value for * || the size (a good value to use is the size * || of an empty cluster). Following this, * || write the other Cluster fields. * \/ * [Capture blocks] -> Write blocks directly to the file as they * || are received. * \/ * cluster.finalise(output) -> Calculate the actual cluster size (e.g. * subtract the position in the file of the * first block from the position in the file * after the last block), and write it over * the dummy value written earlier. *
The second approach described above has a very important limitation: no other writes to the file can occur while a cluster is open. To support this restriction, the Cluster interface requires that no writes are performed to the file while a cluster is open. This applies to any implementation, including in-memory implementations, in order to support interchangeability.
typedef value_type const& tide::Cluster::const_reference |
typedef boost::shared_ptr<Cluster> tide::Cluster::Ptr |
typedef value_type& tide::Cluster::reference |
typedef size_t tide::Cluster::size_type |
tide::Cluster::Cluster | ( | uint64_t | timecode = 0 | ) |
Construct a new Cluster.
[in] | timecode | The timecode of the cluster, in the units specified by TimecodeScale. |
virtual tide::Cluster::~Cluster | ( | ) | [inline, virtual] |
virtual std::streamsize tide::Cluster::blocks_size | ( | ) | const [protected, pure virtual] |
Get the size of the blocks in this cluster.
Implemented in tide::MemoryCluster.
std::streamsize tide::Cluster::body_size | ( | ) | const [inline, protected, virtual] |
Get the size of the body of this element.
Implements tide::Element.
virtual void tide::Cluster::clear | ( | ) | [pure virtual] |
Remove all blocks.
Implemented in tide::MemoryCluster.
virtual size_type tide::Cluster::count | ( | ) | const [pure virtual] |
Get the number of blocks.
Implemented in tide::MemoryCluster.
virtual bool tide::Cluster::empty | ( | ) | const [pure virtual] |
Check if there are no blocks.
Implemented in tide::MemoryCluster.
virtual std::streamsize tide::Cluster::finalise | ( | std::ostream & | output | ) | [pure virtual] |
Finalise writing of the cluster.
See the Cluster documentation for more details of how this method should be implemented. Once this is called, the cluster should be considered final in the stream, including all the cluster's meta-data and all blocks.
[in] | output | The byte stream to write the cluster to. |
Implemented in tide::MemoryCluster.
std::streamsize tide::Cluster::meta_size | ( | ) | const [protected] |
Get the size of the meta-data portion of the body of.
uint64_t tide::Cluster::position | ( | ) | const |
Get the position of this cluster in the segment.
This property gives the byte-offset of this cluster in its segment. This value is useful for re-synchronising damaged streams.
If it is zero, then the cluster has not been written or was not read from a byte stream.
uint64_t tide::Cluster::previous_size | ( | ) | const [inline] |
Get the size of the previous cluster in the segment.
This property gives the size of the previous cluster in bytes. This can be used to jump straight to the start of the previous cluster, rather than searching for it.
It it is zero, the size of the previous cluster is unknown.
void tide::Cluster::previous_size | ( | uint64_t | size | ) | [inline] |
virtual void tide::Cluster::push_back | ( | value_type const & | value | ) | [pure virtual] |
Erase the block at the specified iterator.
[in] | position | The position to erase at.Erase a range of blocks. |
[in] | first | The start of the range. |
[in] | last | The end of the range.Add a block to this cluster. |
The cluster must be in the writable state. This means that write() has been called and finish_write() has not been called.
ClusterNotReady | if the Cluster is not in the correct state for writing blocks. |
Implemented in tide::MemoryCluster.
std::streamsize tide::Cluster::read | ( | std::istream & | input | ) | [inline, virtual] |
Element reading.
DuplicateTrackNumber | if more than one TrackEntry in the stored element has the same track number. |
DuplicateUID | if more than one TrackEntry in the stored element has the same UID. |
Reimplemented from tide::Element.
virtual std::streamsize tide::Cluster::read_blocks | ( | std::istream & | input, |
std::streamsize | size | ||
) | [protected, pure virtual] |
Read the blocks in this cluster from the output stream.
This function may not necessarily perform the actual reading, but once called, the blocks should be accessible through whatever interface the Cluster implementation provides.
For example, if the blocks are actually read by an iterator, calling this function should prepare for the iterators' use. It might, for example, read the position of each block and store it in an index.
[in] | input | The input byte stream to read blocks from. |
[in] | size | The number of bytes available for reading. Exactly this many bytes should be used, or an error should be reported. |
Implemented in tide::MemoryCluster.
std::streamsize tide::Cluster::read_body | ( | std::istream & | input, |
std::streamsize | size | ||
) | [protected, virtual] |
Element body loading.
Implements tide::Element.
std::streamsize tide::Cluster::read_silent_tracks | ( | std::istream & | input | ) | [protected] |
Read the SilentTracks child element.
virtual void tide::Cluster::reset | ( | ) | [protected, virtual] |
Reset the cluster's members to default values.
std::vector<SilentTrackNumber>& tide::Cluster::silent_tracks | ( | ) | [inline] |
Get the list of silent tracks.
Some tracks in a cluster may be marked as silent. This means that all blocks for those tracks should be ignored within this cluster. This property lists the track numbers of the silent tracks.
A track being made silent in this cluster has no effect on its silence in other clusters.
std::streamsize tide::Cluster::size | ( | ) | const [virtual] |
Get the total size of the element.
Reimplemented from tide::Element.
void tide::Cluster::timecode | ( | uint64_t | timecode | ) | [inline] |
uint64_t tide::Cluster::timecode | ( | ) | const [inline] |
Get the cluster's timecode.
This timecode defines the base timecode for all blocks in the cluster. It is specified in units of the TimecodeScale found in the SegmentInfo element for the same segment as the cluster.
std::streamsize tide::Cluster::write_body | ( | std::ostream & | output | ) | [protected, virtual] |
Element body writing.
Implements tide::Element.
std::streamsize tide::Cluster::write_size | ( | std::ostream & | output | ) | [protected, virtual] |
Element size writing.
Reimplemented from tide::Element.
UIntElement tide::Cluster::position_ [protected] |
UIntElement tide::Cluster::prev_size_ [protected] |
std::vector<SilentTrackNumber> tide::Cluster::silent_tracks_ [protected] |
std::streamsize tide::Cluster::size_ [protected] |
UIntElement tide::Cluster::timecode_ [protected] |
bool tide::Cluster::writing_ [protected] |