ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Packet.cpp
Go to the documentation of this file.
1 /*
2  * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net)
3  * Modified work Copyright 2018 - 2020 Andy Maloney <asmaloney@gmail.com>
4  *
5  * Permission is hereby granted, free of charge, to any person or organization
6  * obtaining a copy of the software and accompanying documentation covered by
7  * this license (the "Software") to use, reproduce, display, distribute,
8  * execute, and transmit the Software, and to prepare derivative works of the
9  * Software, and to permit third-parties to whom the Software is furnished to
10  * do so, all subject to the following:
11  *
12  * The copyright notices in the Software and this entire statement, including
13  * the above license grant, this restriction and the following disclaimer,
14  * must be included in all copies of the Software, in whole or in part, and
15  * all derivative works of the Software, unless such copies or derivative
16  * works are solely in the form of machine-executable object code generated by
17  * a source language processor.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  */
27 
28 #include <cstring>
29 
30 #include "CheckedFile.h"
31 #include "Packet.h"
32 
33 using namespace e57;
34 
36 {
37  static constexpr unsigned MAX_ENTRIES = 2048;
38 
39  const uint8_t packetType = INDEX_PACKET;
40 
41  uint8_t packetFlags = 0; // flag bitfields
42  uint16_t packetLogicalLengthMinus1 = 0;
43  uint16_t entryCount = 0;
44  uint8_t indexLevel = 0;
45  uint8_t reserved1[9] = {}; // must be zero
46 
48  {
49  uint64_t chunkRecordNumber = 0;
50  uint64_t chunkPhysicalOffset = 0;
51  } entries[MAX_ENTRIES];
52 
53  void verify( unsigned bufferLength = 0, uint64_t totalRecordCount = 0, uint64_t fileSize = 0 ) const;
54 
55 #ifdef E57_DEBUG
56  void dump( int indent = 0, std::ostream &os = std::cout ) const;
57 #endif
58 };
59 
61 {
62  const uint8_t packetType = EMPTY_PACKET;
63 
64  uint8_t reserved1 = 0; // must be zero
65  uint16_t packetLogicalLengthMinus1 = 0;
66 
67  void verify( unsigned bufferLength = 0 ) const; //???use
68 
69 #ifdef E57_DEBUG
70  void dump( int indent = 0, std::ostream &os = std::cout ) const;
71 #endif
72 };
73 
74 //=============================================================================
75 // PacketReadCache
76 
77 PacketReadCache::PacketReadCache( CheckedFile *cFile, unsigned packetCount ) : cFile_( cFile ), entries_( packetCount )
78 {
79  if ( packetCount == 0 )
80  {
81  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetCount=" + toString( packetCount ) );
82  }
83 }
84 
85 std::unique_ptr<PacketLock> PacketReadCache::lock( uint64_t packetLogicalOffset, char *&pkt )
86 {
87 #ifdef E57_MAX_VERBOSE
88  std::cout << "PacketReadCache::lock() called, packetLogicalOffset=" << packetLogicalOffset << std::endl;
89 #endif
90 
92  if ( lockCount_ > 0 )
93  {
94  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "lockCount=" + toString( lockCount_ ) );
95  }
96 
98  if ( packetLogicalOffset == 0 )
99  {
100  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetLogicalOffset=" + toString( packetLogicalOffset ) );
101  }
102 
104  for ( unsigned i = 0; i < entries_.size(); ++i )
105  {
106  auto &entry = entries_[i];
107 
108  if ( packetLogicalOffset == entry.logicalOffset_ )
109  {
111 #ifdef E57_MAX_VERBOSE
112  std::cout << " Found matching cache entry, index=" << i << std::endl;
113 #endif
115  entry.lastUsed_ = ++useCount_;
116 
118  pkt = entry.buffer_;
119 
122  std::unique_ptr<PacketLock> plock( new PacketLock( this, i ) );
123 
125  ++lockCount_;
126 
127  return plock;
128  }
129  }
131 
133  unsigned oldestEntry = 0;
134  unsigned oldestUsed = entries_.at( 0 ).lastUsed_;
135 
136  for ( unsigned i = 0; i < entries_.size(); ++i )
137  {
138  const auto &entry = entries_[i];
139 
140  if ( entry.lastUsed_ < oldestUsed )
141  {
142  oldestEntry = i;
143  oldestUsed = entry.lastUsed_;
144  }
145  }
146 #ifdef E57_MAX_VERBOSE
147  std::cout << " Oldest entry=" << oldestEntry << " lastUsed=" << oldestUsed << std::endl;
148 #endif
149 
150  readPacket( oldestEntry, packetLogicalOffset );
151 
153  pkt = entries_[oldestEntry].buffer_;
154 
156  std::unique_ptr<PacketLock> plock( new PacketLock( this, oldestEntry ) );
157 
159  ++lockCount_;
160 
161  return plock;
162 }
163 
164 void PacketReadCache::unlock( unsigned cacheIndex )
165 {
166  //??? why lockedEntry not used?
167 #ifdef E57_MAX_VERBOSE
168  std::cout << "PacketReadCache::unlock() called, cacheIndex=" << cacheIndex << std::endl;
169 #endif
170 
171  if ( lockCount_ != 1 )
172  {
173  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "lockCount=" + toString( lockCount_ ) );
174  }
175 
176  --lockCount_;
177 }
178 
179 void PacketReadCache::readPacket( unsigned oldestEntry, uint64_t packetLogicalOffset )
180 {
181 #ifdef E57_MAX_VERBOSE
182  std::cout << "PacketReadCache::readPacket() called, oldestEntry=" << oldestEntry
183  << " packetLogicalOffset=" << packetLogicalOffset << std::endl;
184 #endif
185 
188  EmptyPacketHeader header;
189 
190  cFile_->seek( packetLogicalOffset, CheckedFile::Logical );
191  cFile_->read( reinterpret_cast<char *>( &header ), sizeof( header ) );
192 
195  unsigned packetLength = header.packetLogicalLengthMinus1 + 1;
196 
198  if ( packetLength > DATA_PACKET_MAX )
199  {
200  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) );
201  }
202 
203  auto &entry = entries_.at( oldestEntry );
204 
206  cFile_->seek( packetLogicalOffset, CheckedFile::Logical );
207  cFile_->read( entry.buffer_, packetLength );
208 
210  switch ( header.packetType )
211  {
212  case DATA_PACKET:
213  {
214  auto dpkt = reinterpret_cast<DataPacket *>( entry.buffer_ );
215 
216  dpkt->verify( packetLength );
217 #ifdef E57_MAX_VERBOSE
218  std::cout << " data packet:" << std::endl;
219  dpkt->dump( 4 ); //???
220 #endif
221  }
222  break;
223  case INDEX_PACKET:
224  {
225  auto ipkt = reinterpret_cast<IndexPacket *>( entry.buffer_ );
226 
227  ipkt->verify( packetLength );
228 #ifdef E57_MAX_VERBOSE
229  std::cout << " index packet:" << std::endl;
230  ipkt->dump( 4 ); //???
231 #endif
232  }
233  break;
234  case EMPTY_PACKET:
235  {
236  auto hp = reinterpret_cast<EmptyPacketHeader *>( entry.buffer_ );
237 
238  hp->verify( packetLength );
239 #ifdef E57_MAX_VERBOSE
240  std::cout << " empty packet:" << std::endl;
241  hp->dump( 4 ); //???
242 #endif
243  }
244  break;
245  default:
246  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetType=" + toString( header.packetType ) );
247  }
248 
249  entry.logicalOffset_ = packetLogicalOffset;
250 
253  entry.lastUsed_ = ++useCount_;
254 }
255 
256 #ifdef E57_DEBUG
257 void PacketReadCache::dump( int indent, std::ostream &os )
258 {
259  os << space( indent ) << "lockCount: " << lockCount_ << std::endl;
260  os << space( indent ) << "useCount: " << useCount_ << std::endl;
261  os << space( indent ) << "entries:" << std::endl;
262  for ( unsigned i = 0; i < entries_.size(); i++ )
263  {
264  os << space( indent ) << "entry[" << i << "]:" << std::endl;
265  os << space( indent + 4 ) << "logicalOffset: " << entries_[i].logicalOffset_ << std::endl;
266  os << space( indent + 4 ) << "lastUsed: " << entries_[i].lastUsed_ << std::endl;
267  if ( entries_[i].logicalOffset_ != 0 )
268  {
269  os << space( indent + 4 ) << "packet:" << std::endl;
270  switch ( reinterpret_cast<EmptyPacketHeader *>( entries_.at( i ).buffer_ )->packetType )
271  {
272  case DATA_PACKET:
273  {
274  auto dpkt = reinterpret_cast<DataPacket *>( entries_.at( i ).buffer_ );
275  dpkt->dump( indent + 6, os );
276  }
277  break;
278  case INDEX_PACKET:
279  {
280  auto ipkt = reinterpret_cast<IndexPacket *>( entries_.at( i ).buffer_ );
281  ipkt->dump( indent + 6, os );
282  }
283  break;
284  case EMPTY_PACKET:
285  {
286  auto hp = reinterpret_cast<EmptyPacketHeader *>( entries_.at( i ).buffer_ );
287  hp->dump( indent + 6, os );
288  }
289  break;
290  default:
291  throw E57_EXCEPTION2(
293  "packetType=" +
294  toString( reinterpret_cast<EmptyPacketHeader *>( entries_.at( i ).buffer_ )->packetType ) );
295  }
296  }
297  }
298 }
299 #endif
300 
301 //=============================================================================
302 // PacketLock
303 
304 PacketLock::PacketLock( PacketReadCache *cache, unsigned cacheIndex ) : cache_( cache ), cacheIndex_( cacheIndex )
305 {
306 #ifdef E57_MAX_VERBOSE
307  std::cout << "PacketLock() called" << std::endl;
308 #endif
309 }
310 
312 {
313 #ifdef E57_MAX_VERBOSE
314  std::cout << "~PacketLock() called" << std::endl;
315 #endif
316  try
317  {
320  }
321  catch ( ... )
322  {
323  //??? report?
324  }
325 }
326 
327 //=============================================================================
328 // DataPacketHeader
329 
331 {
334  static_assert( sizeof( DataPacketHeader ) == 6, "Unexpected size of DataPacketHeader" );
335 }
336 
338 {
339  packetFlags = 0;
341  bytestreamCount = 0;
342 }
343 
344 void DataPacketHeader::verify( unsigned bufferLength ) const
345 {
347  if ( packetType != DATA_PACKET )
348  {
349  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( packetType ) );
350  }
351 
353 
355  unsigned packetLength = packetLogicalLengthMinus1 + 1;
356  if ( packetLength < sizeof( *this ) )
357  {
358  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) );
359  }
360 
362  if ( packetLength % 4 )
363  {
364  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) );
365  }
366 
368  if ( bufferLength > 0 && packetLength > bufferLength )
369  {
371  "packetLength=" + toString( packetLength ) + " bufferLength=" + toString( bufferLength ) );
372  }
373 
376  if ( bytestreamCount == 0 )
377  {
378  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "bytestreamCount=" + toString( bytestreamCount ) );
379  }
380 
382  if ( sizeof( DataPacketHeader ) + 2 * bytestreamCount > packetLength )
383  {
384  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) +
385  " bytestreamCount=" + toString( bytestreamCount ) );
386  }
387 }
388 
389 #ifdef E57_DEBUG
390 void DataPacketHeader::dump( int indent, std::ostream &os ) const
391 {
392  os << space( indent ) << "packetType: " << static_cast<unsigned>( packetType ) << std::endl;
393  os << space( indent ) << "packetFlags: " << static_cast<unsigned>( packetFlags ) << std::endl;
394  os << space( indent ) << "packetLogicalLengthMinus1: " << packetLogicalLengthMinus1 << std::endl;
395  os << space( indent ) << "bytestreamCount: " << bytestreamCount << std::endl;
396 }
397 #endif
398 
399 //=============================================================================
400 // DataPacket
401 
403 {
406  static_assert( sizeof( DataPacket ) == 64 * 1024, "Unexpected size of DataPacket" );
407 }
408 
409 void DataPacket::verify( unsigned bufferLength ) const
410 {
411  //??? do all packets need versions? how extend without breaking older
412  // checking? need to check
413  // file version#?
414 
416  auto hp = reinterpret_cast<const DataPacketHeader *>( this );
417 
418  hp->verify( bufferLength );
419 
421  auto bsbLength = reinterpret_cast<const uint16_t *>( &payload[0] );
422  unsigned totalStreamByteCount = 0;
423 
424  for ( unsigned i = 0; i < header.bytestreamCount; i++ )
425  {
426  totalStreamByteCount += bsbLength[i];
427  }
428 
430  const unsigned packetLength = header.packetLogicalLengthMinus1 + 1;
431  const unsigned needed = sizeof( DataPacketHeader ) + 2 * header.bytestreamCount + totalStreamByteCount;
432 #ifdef E57_MAX_VERBOSE
433  std::cout << "needed=" << needed << " actual=" << packetLength << std::endl; //???
434 #endif
435 
437  if ( needed > packetLength || needed + 3 < packetLength )
438  {
440  "needed=" + toString( needed ) + "packetLength=" + toString( packetLength ) );
441  }
442 
444  for ( unsigned i = needed; i < packetLength; i++ )
445  {
446  if ( reinterpret_cast<const char *>( this )[i] != 0 )
447  {
448  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) );
449  }
450  }
451 }
452 
453 char *DataPacket::getBytestream( unsigned bytestreamNumber, unsigned &byteCount )
454 {
455 #ifdef E57_MAX_VERBOSE
456  std::cout << "getBytestream called, bytestreamNumber=" << bytestreamNumber << std::endl;
457 #endif
458 
460  if ( header.packetType != DATA_PACKET )
461  {
462  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( header.packetType ) );
463  }
464 
466  if ( bytestreamNumber >= header.bytestreamCount )
467  {
468  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bytestreamNumber=" + toString( bytestreamNumber ) +
469  "bytestreamCount=" + toString( header.bytestreamCount ) );
470  }
471 
473  auto bsbLength = reinterpret_cast<uint16_t *>( &payload[0] );
474  auto streamBase = reinterpret_cast<char *>( &bsbLength[header.bytestreamCount] );
475 
477  unsigned totalPreceeding = 0;
478  for ( unsigned i = 0; i < bytestreamNumber; i++ )
479  {
480  totalPreceeding += bsbLength[i];
481  }
482 
483  byteCount = bsbLength[bytestreamNumber];
484 
486  if ( sizeof( DataPacketHeader ) + 2 * header.bytestreamCount + totalPreceeding + byteCount >
488  {
490  "bytestreamCount=" + toString( header.bytestreamCount ) + " totalPreceeding=" +
491  toString( totalPreceeding ) + " byteCount=" + toString( byteCount ) +
492  " packetLogicalLengthMinus1=" + toString( header.packetLogicalLengthMinus1 ) );
493  }
494 
496  return ( &streamBase[totalPreceeding] );
497 }
498 
499 unsigned DataPacket::getBytestreamBufferLength( unsigned bytestreamNumber )
500 {
501  //??? for now:
502  unsigned byteCount;
503  (void)getBytestream( bytestreamNumber, byteCount );
504  return ( byteCount );
505 }
506 
507 #ifdef E57_DEBUG
508 void DataPacket::dump( int indent, std::ostream &os ) const
509 {
510  if ( header.packetType != DATA_PACKET )
511  {
512  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "packetType=" + toString( header.packetType ) );
513  }
514 
515  reinterpret_cast<const DataPacketHeader *>( this )->dump( indent, os );
516 
517  auto bsbLength = reinterpret_cast<const uint16_t *>( &payload[0] );
518  auto p = reinterpret_cast<const uint8_t *>( &bsbLength[header.bytestreamCount] );
519 
520  for ( unsigned i = 0; i < header.bytestreamCount; i++ )
521  {
522  os << space( indent ) << "bytestream[" << i << "]:" << std::endl;
523  os << space( indent + 4 ) << "length: " << bsbLength[i] << std::endl;
524  /*====
525  unsigned j;
526  for (j=0; j < bsbLength[i] && j < 10; j++)
527  os << space(indent+4) << "byte[" << j << "]=" << (unsigned)p[j]
528  << std::endl; if (j < bsbLength[i]) os << space(indent+4) << bsbLength[i]-j << "
529  more unprinted..." << std::endl;
530  ====*/
531  p += bsbLength[i];
532  if ( p - reinterpret_cast<const uint8_t *>( this ) > DATA_PACKET_MAX )
533  {
535  "size=" + toString( p - reinterpret_cast<const uint8_t *>( this ) ) );
536  }
537  }
538 }
539 #endif
540 
541 //=============================================================================
542 // IndexPacket
543 
544 void IndexPacket::verify( unsigned bufferLength, uint64_t totalRecordCount, uint64_t fileSize ) const
545 {
546  //??? do all packets need versions? how extend without breaking older
547  // checking? need to check
548  // file version#?
549 
551  if ( packetType != INDEX_PACKET )
552  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( packetType ) );
553 
555  unsigned packetLength = packetLogicalLengthMinus1 + 1;
556  if ( packetLength < sizeof( *this ) )
557  {
558  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) );
559  }
560 
562  if ( packetLength % 4 )
563  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) );
564 
567  if ( entryCount == 0 )
568  {
569  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "entryCount=" + toString( entryCount ) );
570  }
571 
573  if ( entryCount > MAX_ENTRIES )
574  {
575  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "entryCount=" + toString( entryCount ) );
576  }
577 
580  if ( indexLevel > 5 )
581  {
582  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "indexLevel=" + toString( indexLevel ) );
583  }
584 
588  if ( indexLevel > 0 && entryCount < 2 )
589  {
591  "indexLevel=" + toString( indexLevel ) + " entryCount=" + toString( entryCount ) );
592  }
593 
596  for ( unsigned i = 0; i < sizeof( reserved1 ); i++ )
597  {
598  if ( reserved1[i] != 0 )
599  {
600  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) );
601  }
602  }
603 
605  if ( bufferLength > 0 && packetLength > bufferLength )
606  {
608  "packetLength=" + toString( packetLength ) + " bufferLength=" + toString( bufferLength ) );
609  }
610 
612  unsigned neededLength = 16 + 8 * entryCount;
613  if ( packetLength < neededLength )
614  {
616  "packetLength=" + toString( packetLength ) + " neededLength=" + toString( neededLength ) );
617  }
618 
619 #ifdef E57_MAX_DEBUG
621  const char *p = reinterpret_cast<const char *>( this );
622  for ( unsigned i = neededLength; i < packetLength; i++ )
623  {
624  if ( p[i] != 0 )
625  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) );
626  }
627 
629  for ( unsigned i = 0; i < entryCount; i++ )
630  {
632  if ( totalRecordCount > 0 && entries[i].chunkRecordNumber >= totalRecordCount )
633  {
635  "i=" + toString( i ) + " chunkRecordNumber=" + toString( entries[i].chunkRecordNumber ) +
636  " totalRecordCount=" + toString( totalRecordCount ) );
637  }
638 
640  if ( i > 0 && entries[i - 1].chunkRecordNumber >= entries[i].chunkRecordNumber )
641  {
643  "i=" + toString( i ) +
644  " prevChunkRecordNumber=" + toString( entries[i - 1].chunkRecordNumber ) +
645  " currentChunkRecordNumber=" + toString( entries[i].chunkRecordNumber ) );
646  }
647 
649  if ( fileSize > 0 && entries[i].chunkPhysicalOffset >= fileSize )
650  {
651  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "i=" + toString( i ) + " chunkPhysicalOffset=" +
652  toString( entries[i].chunkPhysicalOffset ) +
653  " fileSize=" + toString( fileSize ) );
654  }
655 
657  if ( i > 0 && entries[i - 1].chunkPhysicalOffset >= entries[i].chunkPhysicalOffset )
658  {
660  "i=" + toString( i ) +
661  " prevChunkPhysicalOffset=" + toString( entries[i - 1].chunkPhysicalOffset ) +
662  " currentChunkPhysicalOffset=" + toString( entries[i].chunkPhysicalOffset ) );
663  }
664  }
665 #endif
666 }
667 
668 #ifdef E57_DEBUG
669 void IndexPacket::dump( int indent, std::ostream &os ) const
670 {
671  os << space( indent ) << "packetType: " << static_cast<unsigned>( packetType ) << std::endl;
672  os << space( indent ) << "packetFlags: " << static_cast<unsigned>( packetFlags ) << std::endl;
673  os << space( indent ) << "packetLogicalLengthMinus1: " << packetLogicalLengthMinus1 << std::endl;
674  os << space( indent ) << "entryCount: " << entryCount << std::endl;
675  os << space( indent ) << "indexLevel: " << indexLevel << std::endl;
676  unsigned i;
677  for ( i = 0; i < entryCount && i < 10; i++ )
678  {
679  os << space( indent ) << "entry[" << i << "]:" << std::endl;
680  os << space( indent + 4 ) << "chunkRecordNumber: " << entries[i].chunkRecordNumber << std::endl;
681  os << space( indent + 4 ) << "chunkPhysicalOffset: " << entries[i].chunkPhysicalOffset << std::endl;
682  }
683  if ( i < entryCount )
684  {
685  os << space( indent ) << entryCount - i << "more entries unprinted..." << std::endl;
686  }
687 }
688 #endif
689 
690 //=============================================================================
691 // EmptyPacketHeader
692 
693 void EmptyPacketHeader::verify( unsigned bufferLength ) const
694 {
696  if ( packetType != EMPTY_PACKET )
697  {
698  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetType=" + toString( packetType ) );
699  }
700 
702  unsigned packetLength = packetLogicalLengthMinus1 + 1;
703  if ( packetLength < sizeof( *this ) )
704  {
705  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) );
706  }
707 
709  if ( packetLength % 4 )
710  throw E57_EXCEPTION2( E57_ERROR_BAD_CV_PACKET, "packetLength=" + toString( packetLength ) );
711 
713  if ( bufferLength > 0 && packetLength > bufferLength )
714  {
716  "packetLength=" + toString( packetLength ) + " bufferLength=" + toString( bufferLength ) );
717  }
718 }
719 
720 #ifdef E57_DEBUG
721 void EmptyPacketHeader::dump( int indent, std::ostream &os ) const
722 {
723  os << space( indent ) << "packetType: " << static_cast<unsigned>( packetType ) << std::endl;
724  os << space( indent ) << "packetLogicalLengthMinus1: " << packetLogicalLengthMinus1 << std::endl;
725 }
726 #endif
#define E57_EXCEPTION2(ecode, context)
Definition: Common.h:68
void read(char *buf, size_t nRead, size_t bufSize=0)
void seek(uint64_t offset, OffsetMode omode=Logical)
void verify(unsigned bufferLength=0) const
Definition: Packet.cpp:344
void dump(int indent=0, std::ostream &os=std::cout) const
Definition: Packet.cpp:390
uint16_t bytestreamCount
Definition: Packet.h:119
const uint8_t packetType
Definition: Packet.h:115
uint16_t packetLogicalLengthMinus1
Definition: Packet.h:118
uint8_t packetFlags
Definition: Packet.h:117
DataPacketHeader header
Definition: Packet.h:137
void verify(unsigned bufferLength=0) const
Definition: Packet.cpp:409
void dump(int indent=0, std::ostream &os=std::cout) const
Definition: Packet.cpp:508
char * getBytestream(unsigned bytestreamNumber, unsigned &byteCount)
Definition: Packet.cpp:453
uint8_t payload[PayloadSize]
Definition: Packet.h:139
unsigned getBytestreamBufferLength(unsigned bytestreamNumber)
Definition: Packet.cpp:499
unsigned int cacheIndex_
Definition: Packet.h:100
PacketReadCache * cache_
Definition: Packet.h:99
std::vector< CacheEntry > entries_
Definition: Packet.h:81
unsigned lockCount_
Definition: Packet.h:77
PacketReadCache(CheckedFile *cFile, unsigned packetCount)
Definition: Packet.cpp:77
CheckedFile * cFile_
Definition: Packet.h:79
friend class PacketLock
Only PacketLock can unlock the cache.
Definition: Packet.h:65
void unlock(unsigned cacheIndex)
Definition: Packet.cpp:164
void readPacket(unsigned oldestEntry, uint64_t packetLogicalOffset)
Definition: Packet.cpp:179
unsigned useCount_
Definition: Packet.h:78
void dump(int indent=0, std::ostream &os=std::cout)
Definition: Packet.cpp:257
std::unique_ptr< PacketLock > lock(uint64_t packetLogicalOffset, char *&pkt)
Definition: Packet.cpp:85
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
Definition: E57Exception.h:56
@ E57_ERROR_BAD_CV_PACKET
a CompressedVector binary packet was bad
Definition: E57Exception.h:45
@ DATA_PACKET
Definition: Packet.h:44
@ EMPTY_PACKET
Definition: Packet.h:45
@ INDEX_PACKET
Definition: Packet.h:43
std::string toString(T x)
Definition: Common.h:80
constexpr int DATA_PACKET_MAX
maximum size of CompressedVector binary data packet
Definition: Packet.h:49
std::string space(size_t n)
Definition: Common.h:73
void dump(int indent=0, std::ostream &os=std::cout) const
Definition: Packet.cpp:721
uint16_t packetLogicalLengthMinus1
Definition: Packet.cpp:65
const uint8_t packetType
Definition: Packet.cpp:62
void verify(unsigned bufferLength=0) const
Definition: Packet.cpp:693
void verify(unsigned bufferLength=0, uint64_t totalRecordCount=0, uint64_t fileSize=0) const
Definition: Packet.cpp:544
void dump(int indent=0, std::ostream &os=std::cout) const
Definition: Packet.cpp:669