OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
BlockStreamBuffer.cpp
Go to the documentation of this file.
3 #include <cstring> /* for memcpy */
4 
5 static ossimTrace traceDebug("BlockStreamBuffer:debug");
6 
8  : m_blockBuffer(),
9  m_currentPosValue(0),
10  m_blockInfo(),
11  m_adaptStream(adaptStream)
12 {
13  m_blockInfo.m_blockSize = blockSize;
15  {
18  }
19  setg(0, 0, 0);
20 }
21 
22 std::streambuf* ossim::BlockStreamBuffer::setbuf (char* s,
23  std::streamsize n)
24 {
25  if(n>0)
26  {
27  m_blockBuffer.clear();
28  m_blockInfo.setBuffer(s,n);
29  setg(0, 0, 0);
30  }
31  return this;
32 }
33 
35 {
36  if(m_blockInfo.isLoaded())
37  {
38  setg(m_blockInfo.getBuffer(),
39  m_blockInfo.getBuffer() + (m_currentPosValue - m_blockInfo.m_startByte),
40  m_blockInfo.getBuffer() + m_blockInfo.m_validSize);
41  }
42  else
43  {
44  setg(0,0,0);
45  }
46 
47 }
48 
50 {
51  m_blockInfo.m_blockLoaded = false;
52  m_blockInfo.m_validSize = 0;
53  if(m_adaptStream)
54  {
55  if(m_currentPosValue < 0) m_currentPosValue = 0;
56  ossim_int64 blockIndex = m_blockInfo.getBlockIndex(m_currentPosValue);
57  m_blockInfo.m_startByte = blockIndex*m_blockInfo.m_blockSize;
58  if(!m_adaptStream->good()) m_adaptStream->clear();
59  if(m_blockInfo.m_startByte != m_adaptStream->tellg())
60  {
61  m_adaptStream->seekg(m_blockInfo.m_startByte);
62  }
63  m_adaptStream->read(m_blockInfo.m_blockBufferPtr,
64  m_blockInfo.m_blockSize);
65  ossim_int64 bytesRead = m_adaptStream->gcount();
66  if(!m_adaptStream->bad()&&(bytesRead>0))
67  {
68  m_blockInfo.m_blockLoaded = true;
69  m_blockInfo.m_validSize = bytesRead;
70  if((m_blockInfo.m_validSize<=0)||(!m_blockInfo.isWithinValidWindow(m_currentPosValue)))
71  {
72  m_blockInfo.m_blockLoaded = false;
73  }
74  }
75  }
76  setgPtrs();
77 }
78 
79 std::streambuf::pos_type ossim::BlockStreamBuffer::seekoff(
80  off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode /* mode */)
81 {
82  // make sure we are in synch with current pos
83  // gptr can be updated by other means
84  syncCurrentPosition();
85  pos_type result = pos_type(off_type(-1));
86  if(m_adaptStream)
87  {
88  ossim_int64 pos = m_currentPosValue;
89  switch(dir)
90  {
91  case std::ios_base::beg:
92  {
93  pos = offset;
94  result = seekpos(pos, std::ios_base::in);
95  break;
96  }
97  case std::ios_base::cur:
98  {
99  pos += offset;
100  result = seekpos(pos, std::ios_base::in);
101  break;
102  }
103  case std::ios_base::end:
104  {
105  // at this point in time of implementation
106  // we do not know the offset to the end of the stream
107  // we are adapting
108  //
109  // we have no choice but to call the adapted stream
110  // implementation
111  result = m_adaptStream->rdbuf()->pubseekoff(pos, dir);
112  m_currentPosValue = result;
113  setgPtrs();
114 
115  break;
116  }
117  default:
118  {
119  break;
120  }
121  }
122  }
123  return result;
124 }
125 
126 std::streambuf::pos_type ossim::BlockStreamBuffer::seekpos(pos_type pos,
127  std::ios_base::openmode mode)
128 {
129  if(traceDebug())
130  {
132  << "BlockStreamBuffer::seekpos DEBUG: entered with absolute position: " << pos << "\n";
133  }
134  pos_type result = pos_type(off_type(-1));
135 
136  if(m_adaptStream)
137  {
138  if(pos == m_currentPosValue)
139  {
140  result = pos;
141  }
142  else if(m_blockInfo.isLoaded()&&m_blockInfo.isWithinValidWindow(pos))
143  {
144  result = pos;
145  m_currentPosValue = result;
146  }
147  else
148  {
149  result = m_adaptStream->rdbuf()->pubseekpos(pos, mode);
150  m_currentPosValue = result;
151  }
152  setgPtrs();
153  }
154 
155  if(traceDebug())
156  {
158  << "BlockStreamBuffer::seekpos DEBUG: leaving\n";
159 
160  }
161  return result;
162 
163 }
164 
165 std::streamsize ossim::BlockStreamBuffer::xsgetn(char_type* s,
166  std::streamsize n)
167 {
168  if(traceDebug())
169  {
171  << "BlockStreamBuffer::xsgetn DEBUG: entered ......"<<n<<"\n";
172 
173  }
174  std::streamsize result = EOF;
175 
176  if(m_adaptStream)
177  {
178  ossim_int64 bytesNeedToRead = n;
179  ossim_int64 bytesRead = 0;
180  syncCurrentPosition();
181 
182  while(bytesNeedToRead>0)
183  {
184  if(!m_blockInfo.isWithinValidWindow(m_currentPosValue))
185  {
186  loadBlock();
187  }
188 
189  if(m_blockInfo.isLoaded())
190  {
191  ossim_int64 delta = (m_blockInfo.getEndByte()-
192  m_currentPosValue);
193  if(delta <= bytesNeedToRead)
194  {
195  std::memcpy(s+bytesRead,
196  m_blockInfo.getBufferStart(m_currentPosValue),
197  delta);
198  bytesRead+=delta;
199  bytesNeedToRead-=delta;
200  m_currentPosValue+=delta;
201  }
202  else
203  {
204  std::memcpy(s+bytesRead,
205  m_blockInfo.getBufferStart(m_currentPosValue),
206  bytesNeedToRead);
207  m_currentPosValue+=bytesNeedToRead;
208  bytesRead+=bytesNeedToRead;
209  bytesNeedToRead=0;
210  }
211  }
212  else
213  {
214  bytesNeedToRead=0;
215  }
216  }
217  // specify the current absolute position after read
218  // so we are in sync.
219  setgPtrs();
220  result = bytesRead;
221  }
222  if(traceDebug())
223  {
225  << "BlockStreamBuffer::xsgetn DEBUG: leaving ......\n";
226 
227  }
228  return result;
229 }
230 
232 {
233  if(traceDebug())
234  {
236  << "BlockStreamBuffer::underflow DEBUG: entered ......\n";
237 
238  }
239  if(!m_adaptStream) return EOF;
240  else{
241  syncCurrentPosition();
242  if(!m_blockInfo.isWithinValidWindow(m_currentPosValue))
243  {
244  loadBlock();
245  }
246 
247  if(!m_blockInfo.isLoaded())
248  {
249  return EOF;
250  }
251  }
252  if(traceDebug())
253  {
255  << "BlockStreamBuffer::underflow DEBUG: leaving ......\n";
256 
257  }
258  return (int)static_cast<ossim_uint8>(*gptr());
259 }
260 
262 {
263  if(m_blockInfo.isLoaded()&&gptr())
264  {
265  m_currentPosValue = (m_blockInfo.m_startByte+(gptr()-eback()));
266  }
267 }
std::vector< char > m_blockBuffer
The block buffer that we set the buf pointers to.
virtual std::streambuf * setbuf(char *s, std::streamsize n)
This is a virtual method that can be overriden.
ossim_int64 m_blockSize
Is the size of the buffer.
char * m_blockBufferPtr
Starting address of the block.
virtual int underflow()
underflow is overriden from the base streambuf.
void loadBlock()
loadBlock will load data into the current block and call the setgPtrs to adjust the internal pointers...
void syncCurrentPosition()
syncCurrentPosition is a utility method that we call internally in the overriden protected methods th...
os2<< "> n<< " > nendobj n
unsigned long long ossim_uint64
virtual std::streamsize xsgetn(char_type *s, std::streamsize n)
xsgetn is a protected virtual method that we override from the base streambuf.
std::basic_istream< char > istream
Base class for char input streams.
Definition: ossimIosFwd.h:20
virtual pos_type seekoff(off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
this is a protected method overriden from streambuf base.
BlockStreamBuffer(ossim::istream *adaptStream=0, ossim_uint64 blockSize=0)
long long ossim_int64
void setgPtrs()
setgPtrs calls setg and sets the eback egptr and gptr.
BlockBufInfo m_blockInfo
Holds the information about the block.
virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
seekpos is overriden from the base streambuf class.
unsigned char ossim_uint8
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)