1 #ifndef PACKET_H
2 #define PACKET_H
3 /*
4  * Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net)
5  *
6  * Permission is hereby granted, free of charge, to any person or organization
7  * obtaining a copy of the software and accompanying documentation covered by
8  * this license (the "Software") to use, reproduce, display, distribute,
9  * execute, and transmit the Software, and to prepare derivative works of the
10  * Software, and to permit third-parties to whom the Software is furnished to
11  * do so, all subject to the following:
12  *
13  * The copyright notices in the Software and this entire statement, including
14  * the above license grant, this restriction and the following disclaimer,
15  * must be included in all copies of the Software, in whole or in part, and
16  * all derivative works of the Software, unless such copies or derivative
17  * works are solely in the form of machine-executable object code generated by
18  * a source language processor.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  */
28 
29 #include <cstdint>
30 #include <vector>
31 
32 #include "Common.h"
33 
34 
35 namespace e57
36 {
37    class CheckedFile;
38    class PacketLock;
39 
40    /// Packet types (in a compressed vector section)
41    enum
42    {
43       INDEX_PACKET = 0,
44       DATA_PACKET,
45       EMPTY_PACKET,
46    };
47 
48    /// maximum size of CompressedVector binary data packet
49    constexpr int   DATA_PACKET_MAX = (64*1024);
50 
51    class PacketReadCache
52    {
53       public:
54          PacketReadCache(CheckedFile* cFile, unsigned packetCount);
55 
56          std::unique_ptr<PacketLock> lock(uint64_t packetLogicalOffset, char* &pkt);  //??? pkt could be const
57 
58 #ifdef E57_DEBUG
59          void                dump(int indent = 0, std::ostream& os = std::cout);
60 #endif
61 
62       protected:
63          /// Only PacketLock can unlock the cache
64          friend class PacketLock;
65          void                unlock(unsigned cacheIndex);
66 
67          void                readPacket(unsigned oldestEntry, uint64_t packetLogicalOffset);
68 
69          struct CacheEntry
70          {
71                uint64_t    logicalOffset_ = 0;
72                char        buffer_[DATA_PACKET_MAX];  //! No need to init since it's a data buffer
73                unsigned    lastUsed_ = 0;
74          };
75 
76          unsigned    lockCount_ = 0;
77          unsigned    useCount_ = 0;
78          CheckedFile *cFile_ = nullptr;
79 
80          std::vector<CacheEntry>  entries_;
81    };
82 
83    class PacketLock
84    {
85       public:
86          ~PacketLock();
87 
88       private:
89          /// Can't be copied or assigned
90          PacketLock(const PacketLock& plock);
91          PacketLock&     operator=(const PacketLock& plock);
92 
93       protected:
94          friend class PacketReadCache;
95          /// Only PacketReadCache can construct
96          PacketLock(PacketReadCache* cache, unsigned cacheIndex);
97 
98          PacketReadCache* cache_ = nullptr;
99          unsigned int     cacheIndex_ = 0;
100    };
101 
102    class DataPacketHeader
103    {
104       public:
105          DataPacketHeader();
106 
107          void  reset();
108 
109          void  verify(unsigned bufferLength = 0) const; //???use
110 
111 #ifdef E57_DEBUG
112          void  dump(int indent = 0, std::ostream& os = std::cout) const;
113 #endif
114          const uint8_t     packetType = DATA_PACKET;
115 
116          uint8_t     packetFlags = 0;
117          uint16_t    packetLogicalLengthMinus1 = 0;
118          uint16_t    bytestreamCount = 0;
119    };
120 
121    class DataPacket
122    {
123       public:
124          DataPacket();
125 
126          void        verify(unsigned bufferLength = 0) const;
127          char*       getBytestream(unsigned bytestreamNumber, unsigned& bufferLength);
128          unsigned    getBytestreamBufferLength(unsigned bytestreamNumber);
129 
130 #ifdef E57_DEBUG
131          void        dump(int indent = 0, std::ostream& os = std::cout) const;
132 #endif
133 
134          static constexpr int  PayloadSize = DATA_PACKET_MAX - sizeof(DataPacketHeader);
135 
136          DataPacketHeader  header;
137 
138          uint8_t     payload[PayloadSize];  //! No need to init since it's a data buffer
139    };
140 }
141 #endif
142