#include <CompressedVectorWriterImpl.h>
Public Member Functions | |
void | close () |
std::shared_ptr< CompressedVectorNodeImpl > | compressedVectorNode () const |
CompressedVectorWriterImpl (std::shared_ptr< CompressedVectorNodeImpl > ni, std::vector< SourceDestBuffer > &sbufs) | |
bool | isOpen () const |
void | write (const size_t requestedRecordCount) |
void | write (std::vector< SourceDestBuffer > &sbufs, const size_t requestedRecordCount) |
~CompressedVectorWriterImpl () | |
e57::CompressedVectorWriterImpl::CompressedVectorWriterImpl | ( | std::shared_ptr< CompressedVectorNodeImpl > | ni, |
std::vector< SourceDestBuffer > & | sbufs | ||
) |
Empty sbufs is an error
Get CompressedArray's prototype node (all array elements must match this type)
Check sbufs well formed (matches proto exactly)
For each individual sbuf, create an appropriate Encoder based on the cVector_ attributes
Create vector of single sbuf ??? for now, may have groups later
Calc which stream the given path belongs to. This depends on position of the node in the proto tree.
EncoderFactory picks the appropriate encoder to match type declared in prototype
The bytestreams_ vector must be ordered by bytestreamNumber, not by order called specified sbufs, so sort it.
Reserve space for CompressedVector binary section header, record location so can save to when writer closes. Request that file be extended with zeros since we will write to it at a later time (when writer closes).
Just before return (and can't throw) increment writer count ??? safer way to assure don't miss close?
If get here, the writer is open
References e57::E57_ERROR_BAD_API_ARGUMENT, e57::E57_ERROR_INTERNAL, e57::Encoder::EncoderFactory(), and e57::toString().
e57::CompressedVectorWriterImpl::~CompressedVectorWriterImpl | ( | ) |
References close().
void e57::CompressedVectorWriterImpl::close | ( | ) |
Before anything that can throw, decrement writer count
don't call checkWriterOpen();
Set closed before do anything, so if get fault and start unwinding, don't try to close again.
If have any data, write packet Write all remaining ioBuffers and internal encoder register cache into file. Know we are done when totalOutputAvailable() returns 0 after a flush().
Compute length of whole section we just wrote (from section start to current start of free space).
Prepare CompressedVectorSectionHeader
??? can be zero, if no data written ???not set yet
??? can be zero, if no data written ???not set yet
Write header at beginning of section, previously allocated
Set address and size of associated CompressedVector
Free channels
References e57::CompressedVectorSectionHeader::dataPhysicalOffset, e57::CompressedVectorSectionHeader::indexPhysicalOffset, e57::CheckedFile::Physical, e57::CompressedVectorSectionHeader::sectionLogicalLength, and e57::CompressedVectorSectionHeader::verify().
Referenced by femexamples.examplesgui.FemExamples::reject(), and ~CompressedVectorWriterImpl().
std::shared_ptr< CompressedVectorNodeImpl > e57::CompressedVectorWriterImpl::compressedVectorNode | ( | ) | const |
bool e57::CompressedVectorWriterImpl::isOpen | ( | ) | const |
don't checkImageFileOpen(FILE, LINE, FUNCTION), or checkWriterOpen()
void e57::CompressedVectorWriterImpl::write | ( | const size_t | requestedRecordCount | ) |
Check that requestedRecordCount is not larger than the sbufs
Rewind all sbufs so start reading from beginning
Loop until all channels have completed requestedRecordCount transfers
Calc remaining record counts for all channels
We are done if have no more work, break out of loop
Estimate how many records can write before have enough data to fill data packet to efficient length Efficient packet length is >= 75% of maximum packet length. It is OK if get too much data (more than one packet) in an iteration. Reader will be able to handle packets whose streams are not exactly synchronized to the record boundaries. But try to do a good job of keeping the stream synchronization "close enough" (so a reader that can cache only two packets is efficient).
If have more than target fraction of packet, send it now
restart loop so recalc statistics (packet size may not be zero after write, if have too much data)
??? useful? Get approximation of number of bytes per record of CompressedVector and total of bytes used
Don't allow straggler to get too far behind. ??? Don't allow a single channel to get too far ahead ??? Process channels that are furthest behind first. ???
!!!! For now just process one record per loop until packet is full enough, or completed request
!! For now, process up to 50 records at a time
When we leave this function, will likely still have data in channel ioBuffers as well as partial words in Encoder registers.
References e57::DATA_PACKET_MAX, e57::E57_ERROR_BAD_API_ARGUMENT, and e57::toString().
Referenced by gzip_utf8.GzipFile::seek(), and write().
void e57::CompressedVectorWriterImpl::write | ( | std::vector< SourceDestBuffer > & | sbufs, |
const size_t | requestedRecordCount | ||
) |
don't checkImageFileOpen, write(unsigned) will do it don't checkWriterOpen(), write(unsigned) will do it
References write().
Referenced by gzip_utf8.GzipFile::seek().