OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimJpipMessageDecoder.cpp
Go to the documentation of this file.
2 
4 :m_lastClass(0),
5 m_lastCSn(0),
6 m_headerLength(0),
7 m_inputStream(&m_streamBuffer)
8 {
9 }
10 
11 // ossimJpipMessage* ossimJpipMessageDecoder::readMessage() throw(ossimException)
13 {
14  ossim_int32 BinIDIndicator = 0;
15  ossim_int64 inClassIdentifier = 0;
16  bool completeDataBin = false;
17  ossim_int64 tempByte = 0;
18 
19  // Initialization
20  m_headerLength = 0;
22 
23  // Bin-ID
24  tempByte = m_inputStream.get();
26 
27  if (tempByte == 0x00)
28  { // EOR is reached
29  jpipMessage = readEORMessage();
30  jpipMessage->setHeaderLength(m_headerLength);
31  return jpipMessage.release();
32  }
33 
34  // b bits
35  BinIDIndicator = (tempByte >> 5) & 0x03;
36  if ( (BinIDIndicator < 1) || (BinIDIndicator > 3) )
37  {
38  throw new ossimException("Wrong server response: impossible to decode it correctly");
39  }
40 
41  // c bit
42  completeDataBin = (tempByte & 0x10)==0 ? false : true;
43 
44  // d bits (In-Class ID)
45  inClassIdentifier = tempByte & 0x0F;
46  if ((tempByte >> 7) > 0 ) {
47  int numBytesVBAS = 1;
48  do {
49  tempByte = m_inputStream.get();
51  if (tempByte == -1) {
52  throw new ossimException("There is not data available to read the VBAS");
53  }
54  inClassIdentifier = (inClassIdentifier << 7) | (ossim_int64)(tempByte & 0x7F);
55  numBytesVBAS++;
56 
57  if (numBytesVBAS > 9) { // maximum long value is 2^63 - 1 => 9 bytes VBAS
58  throw new ossimException("VBAS length is larger than 63 bits (which is the maximum of long)");
59  }
60  } while ( (tempByte & 0x80) != 0 );
61  }
62 
63  jpipMessage->header()->m_isLastByte = completeDataBin;
64  jpipMessage->header()->m_inClassIdentifier = inClassIdentifier;
65 
66  // Class
67  if ( (BinIDIndicator == 2) || (BinIDIndicator == 3) )
68  {
69  jpipMessage->header()->m_classIdentifier = (int)readVBAS();
70  m_lastClass = jpipMessage->header()->m_classIdentifier;
71 
72  }
73  else
74  {
75  jpipMessage->header()->m_classIdentifier = m_lastClass;
76  }
77  if ((jpipMessage->header()->m_classIdentifier < 0) || (jpipMessage->header()->m_classIdentifier > 8) )
78  throw new ossimException("Wrong server response: invalid value for Class identifier)");
79 
80  // CSn
81  if ( BinIDIndicator == 3)
82  {
83  jpipMessage->header()->m_CSn = (int)readVBAS();
84  m_lastCSn = jpipMessage->header()->m_CSn;
85 
86  }
87  else
88  {
89  jpipMessage->header()->m_CSn = m_lastCSn;
90  }
91 
92  // Msg-Offset
93  jpipMessage->header()->m_msgOffset = (int)readVBAS();
94 
95  // Msg-Length
96  jpipMessage->header()->m_msgLength = (int)readVBAS();
97 
98  // Aux
99  if ( (jpipMessage->header()->m_classIdentifier % 2) == 1 )
100  {
101  jpipMessage->header()->m_aux = (int)readVBAS();
102  }
103 
104  // Read jpip message body
105  if (jpipMessage->header()->m_msgLength > 0)
106  {
107  jpipMessage->messageBody().resize(jpipMessage->header()->m_msgLength);
108  m_inputStream.read((char*)&jpipMessage->messageBody().front(), (int)jpipMessage->header()->m_msgLength);
109  }
110 
111  jpipMessage->setHeaderLength(m_headerLength);
112 
113  return jpipMessage.release();
114 }
115 
116 // ossim_int64 ossimJpipMessageDecoder::readVBAS() throw(ossimException)
118 {
119  ossim_int64 value = 0;
120  ossim_int64 tempByte;
121  ossim_int32 numBytesVBAS = 0;
122  m_headerLength = 0;
123 
124  do
125  {
126  tempByte = m_inputStream.get();
127  m_headerLength++;
128 
129  if(tempByte == -1)
130  {
131  throw ossimException("There is not data available to read the VBAS");
132  }
133 
134  value = (value << 7) | (long) (tempByte & 0x7F);
135  numBytesVBAS++;
136 
137  if (numBytesVBAS > 9)
138  { // maximum long value is 2^63 - 1 => 9 bytes VBAS
139  throw ossimException("VBAS length is larger than 63 bits (which is the maximum of long)");
140  }
141 
142  } while ( (tempByte & 0x80) != 0 );
143 
144  return value;
145 }
146 
147 // ossimJpipMessage* ossimJpipMessageDecoder::readEORMessage() throw(ossimException)
149 {
150  ossimRefPtr<ossimJpipMessage> jpipMessage;
151 
152  jpipMessage = new ossimJpipMessage();
153  jpipMessage->header()->m_isEOR = true;
154 
155  // Read EOR code
156  jpipMessage->header()->m_EORCode = m_inputStream.get();
157  m_headerLength++;
158 
159  // Read EOR body length
160  int EORBodyLength = (int)readVBAS();
161  jpipMessage->header()->m_msgLength = EORBodyLength;
162 
163  // Read EOR body
164  if (EORBodyLength > 0 )
165  {
166  jpipMessage->messageBody().resize(EORBodyLength);
167  m_inputStream.read((char*)&jpipMessage->messageBody().front(), EORBodyLength);
168  }
169 
170  return jpipMessage.release();
171 }
ossim_int64 m_msgOffset
Identifies the offset of the data in the message from the start of the data-bin.
ossim_int64 readVBAS()
Reads a Variable-length Byte-Aligned Segment.
ossimJpipMessageHeader * header()
ossim_int64 m_headerLength
Indicates the length of the JPIP message header.
MessageBodyType & messageBody()
virtual ossimJpipMessage * readMessage()
ossim_int32 m_CSn
If present, identifies the index (stating from 0) of the codestream to which the data-bin belongs...
int m_EORCode
Definition in CADI.Common.Network.JPIP.EORCodes.
T * release()
Definition: ossimRefPtr.h:93
bool m_isEOR
Indicates if this JPIP Message is an End of Response Message.
ossim_int32 m_lastCSn
Contains the last CSn value.
void setHeaderLength(ossim_uint64 length)
bool m_isLastByte
Bin-ID = [BinIdIndicator, completeDataBin, InClassIdentifier].
ossim_int64 m_msgLength
Identifies the total number of bytes in the body of the message.
ossim_int64 m_aux
If present, it represents a non-negative integer value, formed by concatenating the least significant...
long long ossim_int64
ossim_int32 m_classIdentifier
If present, provides a message class identifier.
ossimJpipMessage * readEORMessage()
int ossim_int32