39 std::vector<SourceDestBuffer> &dbufs ) :
43 #ifdef E57_MAX_VERBOSE
44 std::cout <<
"CompressedVectorReaderImpl() called" <<
std::endl;
46 checkImageFileOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
58 "imageFileName=" + cVector_->imageFileName() +
" cvPathName=" + cVector_->pathName() );
63 proto_ = cVector_->getPrototype();
70 for (
unsigned i = 0; i < dbufs_.size(); i++ )
72 std::vector<SourceDestBuffer> theDbuf;
73 theDbuf.push_back( dbufs.at( i ) );
80 uint64_t bytestreamNumber = 0;
81 if ( !proto_->findTerminalPosition( readNode, bytestreamNumber ) )
86 channels_.emplace_back( dbufs.at( i ), decoder,
static_cast<unsigned>( bytestreamNumber ),
87 cVector_->childCount() );
93 maxRecordCount_ = cvi->childCount();
102 uint64_t sectionLogicalStart = cVector_->getBinarySectionLogicalStart();
103 if ( sectionLogicalStart == 0 )
109 "imageFileName=" + cVector_->imageFileName() +
" cvPathName=" + cVector_->pathName() );
112 imf->file_->read(
reinterpret_cast<char *
>( §ionHeader ),
sizeof( sectionHeader ) );
122 uint64_t dataLogicalOffset = imf->file_->physicalToLogical( sectionHeader.
dataPhysicalOffset );
127 char *anyPacket =
nullptr;
128 std::unique_ptr<PacketLock> packetLock = cache_->
lock( dataLogicalOffset, anyPacket );
130 auto dpkt =
reinterpret_cast<DataPacket *
>( anyPacket );
139 for (
auto &channel : channels_ )
141 channel.currentPacketLogicalOffset = dataLogicalOffset;
142 channel.currentBytestreamBufferIndex = 0;
143 channel.currentBytestreamBufferLength = dpkt->getBytestreamBufferLength( channel.bytestreamNumber );
149 imf->incrReaderCount();
157 #ifdef E57_MAX_VERBOSE
158 std::cout <<
"~CompressedVectorReaderImpl() called" <<
std::endl;
175 void CompressedVectorReaderImpl::setBuffers( std::vector<SourceDestBuffer> &dbufs )
181 proto_->checkBuffers( dbufs,
true );
185 if ( !dbufs_.empty() )
187 if ( dbufs_.size() != dbufs.size() )
190 "oldSize=" +
toString( dbufs_.size() ) +
" newSize=" +
toString( dbufs.size() ) );
192 for (
size_t i = 0; i < dbufs_.size(); i++ )
194 std::shared_ptr<SourceDestBufferImpl> oldBuf = dbufs_[i].impl();
195 std::shared_ptr<SourceDestBufferImpl> newBuf = dbufs[i].impl();
198 oldBuf->checkCompatible( newBuf );
210 checkReaderOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
220 #ifdef E57_MAX_VERBOSE
221 std::cout <<
"CompressedVectorReaderImpl::read() called" <<
std::endl;
223 checkImageFileOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
224 checkReaderOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
227 for (
auto &dbuf : dbufs_ )
229 dbuf.impl()->rewind();
235 for (
auto &channel : channels_ )
237 channel.decoder->inputProcess(
nullptr, 0 );
247 uint64_t earliestPacketLogicalOffset = earliestPacketNeededForInput();
250 if ( earliestPacketLogicalOffset == E57_UINT64_MAX )
256 feedPacketToDecoders( earliestPacketLogicalOffset );
260 unsigned outputCount = 0;
261 for (
unsigned i = 0; i < channels_.size(); i++ )
266 outputCount = chan->
dbuf.impl()->nextIndex();
270 if ( outputCount != chan->
dbuf.impl()->nextIndex() )
282 uint64_t CompressedVectorReaderImpl::earliestPacketNeededForInput()
const
284 uint64_t earliestPacketLogicalOffset = E57_UINT64_MAX;
285 #ifdef E57_MAX_VERBOSE
286 unsigned earliestChannel = 0;
289 for (
unsigned i = 0; i < channels_.size(); i++ )
301 #ifdef E57_MAX_VERBOSE
307 #ifdef E57_MAX_VERBOSE
308 if ( earliestPacketLogicalOffset == E57_UINT64_MAX )
310 std::cout <<
"earliestPacketNeededForInput returning none found" <<
std::endl;
314 std::cout <<
"earliestPacketNeededForInput returning " << earliestPacketLogicalOffset <<
" for channel["
318 return earliestPacketLogicalOffset;
321 DataPacket *CompressedVectorReaderImpl::dataPacket( uint64_t inLogicalOffset )
const
323 char *packet =
nullptr;
325 std::unique_ptr<PacketLock> packetLock = cache_->
lock( inLogicalOffset, packet );
327 return reinterpret_cast<DataPacket *
>( packet );
335 void CompressedVectorReaderImpl::feedPacketToDecoders( uint64_t currentPacketLogicalOffset )
338 auto dpkt = dataPacket( currentPacketLogicalOffset );
350 bool anyChannelHasExhaustedPacket =
false;
351 uint64_t nextPacketLogicalOffset = E57_UINT64_MAX;
355 for ( DecodeChannel &channel : channels_ )
364 unsigned int bsbLength = 0;
365 const char *bsbStart = dpkt->getBytestream( channel.bytestreamNumber, bsbLength );
368 if ( channel.currentBytestreamBufferIndex > bsbLength )
371 "currentBytestreamBufferIndex =" +
toString( channel.currentBytestreamBufferIndex ) +
372 " bsbLength=" +
toString( bsbLength ) );
376 const char *uneatenStart = &bsbStart[channel.currentBytestreamBufferIndex];
377 const size_t uneatenLength = bsbLength - channel.currentBytestreamBufferIndex;
379 if ( &uneatenStart[uneatenLength] > &bsbStart[bsbLength] )
382 " bsbLength=" +
toString( bsbLength ) );
386 const size_t bytesProcessed = channel.decoder->inputProcess( uneatenStart, uneatenLength );
388 #ifdef E57_MAX_VERBOSE
389 std::cout <<
" stream[" << channel.bytestreamNumber <<
"]: feeding decoder " << uneatenLength <<
" bytes"
392 if ( uneatenLength == 0 )
397 std::cout <<
" stream[" << channel.bytestreamNumber <<
"]: bytesProcessed=" << bytesProcessed <<
std::endl;
401 channel.currentBytestreamBufferIndex += bytesProcessed;
405 if ( channel.isInputBlocked() )
407 #ifdef E57_MAX_VERBOSE
408 std::cout <<
" stream[" << channel.bytestreamNumber <<
"] has exhausted its input in current packet"
411 anyChannelHasExhaustedPacket =
true;
412 nextPacketLogicalOffset = currentPacketLogicalOffset + dpkt->header.packetLogicalLengthMinus1 + 1;
417 nextPacketLogicalOffset = findNextDataPacket( nextPacketLogicalOffset );
420 if ( !anyChannelHasExhaustedPacket )
428 if ( nextPacketLogicalOffset < E57_UINT64_MAX )
431 dpkt = dataPacket( nextPacketLogicalOffset );
434 for ( DecodeChannel &channel : channels_ )
442 channel.currentPacketLogicalOffset = nextPacketLogicalOffset;
443 channel.currentBytestreamBufferIndex = 0;
447 channel.currentBytestreamBufferLength = dpkt->getBytestreamBufferLength( channel.bytestreamNumber );
449 #ifdef E57_MAX_VERBOSE
450 std::cout <<
" set new stream buffer for channel[" << channel.bytestreamNumber
451 <<
"], length=" << channel.currentBytestreamBufferLength <<
std::endl;
460 #ifdef E57_MAX_VERBOSE
461 std::cout <<
" at end of data packets" <<
std::endl;
463 if ( nextPacketLogicalOffset >= sectionEndLogicalOffset_ )
465 for ( DecodeChannel &channel : channels_ )
473 #ifdef E57_MAX_VERBOSE
474 std::cout <<
" Marking channel[" << channel.bytestreamNumber <<
"] as finished" <<
std::endl;
476 channel.inputFinished =
true;
482 uint64_t CompressedVectorReaderImpl::findNextDataPacket( uint64_t nextPacketLogicalOffset )
484 #ifdef E57_MAX_VERBOSE
485 std::cout <<
" searching for next data packet, nextPacketLogicalOffset=" << nextPacketLogicalOffset
486 <<
" sectionEndLogicalOffset=" << sectionEndLogicalOffset_ <<
std::endl;
491 while ( nextPacketLogicalOffset < sectionEndLogicalOffset_ )
493 char *anyPacket =
nullptr;
495 std::unique_ptr<PacketLock> packetLock = cache_->
lock( nextPacketLogicalOffset, anyPacket );
498 auto dpkt =
reinterpret_cast<const DataPacket *
>( anyPacket );
502 #ifdef E57_MAX_VERBOSE
503 std::cout <<
" Found next data packet at nextPacketLogicalOffset=" << nextPacketLogicalOffset <<
std::endl;
505 return nextPacketLogicalOffset;
510 nextPacketLogicalOffset += dpkt->header.packetLogicalLengthMinus1 + 1;
514 return E57_UINT64_MAX;
519 checkImageFileOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
541 imf->decrReaderCount();
543 checkImageFileOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
560 void CompressedVectorReaderImpl::checkImageFileOpen(
const char *srcFileName,
int srcLineNumber,
561 const char *srcFunctionName )
const
566 void CompressedVectorReaderImpl::checkReaderOpen(
const char *srcFileName,
int srcLineNumber,
567 const char *srcFunctionName )
const
572 "imageFileName=" + cVector_->imageFileName() +
" cvPathName=" + cVector_->pathName(),
573 srcFileName, srcLineNumber, srcFunctionName );
581 for (
unsigned i = 0; i < dbufs_.size(); i++ )
584 dbufs_[i].dump( indent + 4, os );
588 cVector_->dump( indent + 4, os );
591 proto_->dump( indent + 4, os );
593 for (
unsigned i = 0; i < channels_.size(); i++ )
596 channels_[i].dump( indent + 4, os );
599 os <<
space( indent ) <<
"recordCount: " << recordCount_ <<
std::endl;
600 os <<
space( indent ) <<
"maxRecordCount: " << maxRecordCount_ <<
std::endl;
601 os <<
space( indent ) <<
"sectionEndLogicalOffset: " << sectionEndLogicalOffset_ <<
std::endl;
CompressedVectorReaderImpl(std::shared_ptr< CompressedVectorNodeImpl > ni, std::vector< SourceDestBuffer > &dbufs)
void seek(uint64_t recordNumber)
void dump(int indent=0, std::ostream &os=std::cout)
~CompressedVectorReaderImpl()
std::shared_ptr< CompressedVectorNodeImpl > compressedVectorNode() const
static std::shared_ptr< Decoder > DecoderFactory(unsigned bytestreamNumber, const CompressedVectorNodeImpl *cVector, std::vector< SourceDestBuffer > &dbufs, const ustring &codecPath)
std::unique_ptr< PacketLock > lock(uint64_t packetLogicalOffset, char *&pkt)
QTextStream & endl(QTextStream &stream)
bool _alreadyReadPacket(const DecodeChannel &channel, uint64_t currentPacketLogicalOffset)
std::shared_ptr< class NodeImpl > NodeImplSharedPtr
std::shared_ptr< class ImageFileImpl > ImageFileImplSharedPtr
@ E57_ERROR_BUFFERS_NOT_COMPATIBLE
SourceDestBuffers not compatible with previously given ones.
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
@ E57_ERROR_BAD_API_ARGUMENT
bad API function argument provided by user
@ E57_ERROR_BAD_CV_PACKET
a CompressedVector binary packet was bad
@ E57_ERROR_NOT_IMPLEMENTED
functionality not implemented
@ E57_ERROR_READER_NOT_OPEN
CompressedVectorReader is no longer open.
std::string ustring
UTF-8 encodeded Unicode string.
std::string toString(T x)
std::string space(size_t n)
bool isOutputBlocked() const
uint64_t currentPacketLogicalOffset