|
NCBI Home IEB Home C++ Toolkit docs C Toolkit source browser C Toolkit source browser (2) |
NCBI C++ Toolkit Cross ReferenceC++/src/util/bytesrc.cpp |
source navigation diff markup identifier search freetext search file search |
1 /* $Id: bytesrc.cpp 118922 2008-02-04 15:13:19Z lavr $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 * Implementation of CByteSource and CByteSourceReader
30 * and their specializations'.
31 *
32 */
33
34 #include <ncbi_pch.hpp>
35 #include <corelib/ncbistd.hpp>
36 #include <corelib/stream_utils.hpp>
37 #include <util/bytesrc.hpp>
38 #include <util/util_exception.hpp>
39 #include <util/error_codes.hpp>
40 #include <algorithm>
41
42
43 #define NCBI_USE_ERRCODE_X Util_ByteSrc
44
45
46 BEGIN_NCBI_SCOPE
47
48
49 typedef CFileSourceCollector::TFilePos TFilePos;
50 typedef CFileSourceCollector::TFileOff TFileOff;
51
52 /////////////////////////////////////////////////////////////////////////////
53 // CByteSource
54 /////////////////////////////////////////////////////////////////////////////
55
56 CByteSource::CByteSource(void)
57 {
58 }
59
60
61 CByteSource::~CByteSource(void)
62 {
63 }
64
65
66 /////////////////////////////////////////////////////////////////////////////
67 // CByteSourceReader
68 /////////////////////////////////////////////////////////////////////////////
69
70 CByteSourceReader::CByteSourceReader(void)
71 {
72 }
73
74
75 CByteSourceReader::~CByteSourceReader(void)
76 {
77 }
78
79
80 bool CByteSourceReader::EndOfData(void) const
81 {
82 return true;
83 }
84
85
86 bool CByteSourceReader::Pushback(const char* /*data*/, size_t size)
87 {
88 if ( size ) {
89 ERR_POST_X(1, "CByteSourceReader::Pushback: "
90 "unable to push back " << size << " byte(s)");
91 return false;
92 }
93 return true;
94 }
95
96 void CByteSourceReader::Seekg(CNcbiStreampos /* pos */)
97 {
98 NCBI_THROW(CUtilException,eWrongCommand,"CByteSourceReader::Seekg: unable to seek");
99 }
100
101 CRef<CSubSourceCollector>
102 CByteSourceReader::SubSource(size_t /*prevent*/,
103 CRef<CSubSourceCollector> parent)
104 {
105 return CRef<CSubSourceCollector>(new CMemorySourceCollector(parent));
106 }
107
108
109 /////////////////////////////////////////////////////////////////////////////
110 // CSubSourceCollector
111 /////////////////////////////////////////////////////////////////////////////
112
113
114 CSubSourceCollector::CSubSourceCollector(CRef<CSubSourceCollector> parent)
115 : m_ParentCollector(parent)
116 {
117 }
118
119
120 CSubSourceCollector::~CSubSourceCollector(void)
121 {
122 }
123
124
125 void CSubSourceCollector::AddChunk(const char* buffer, size_t bufferLength)
126 {
127 if ( m_ParentCollector ) {
128 m_ParentCollector->AddChunk(buffer, bufferLength);
129 }
130 }
131
132
133 /////////////////////////////////////////////////////////////////////////////
134 // CStreamByteSource
135 /////////////////////////////////////////////////////////////////////////////
136
137 /* Mac compiler doesn't like getting these flags as unsigned int (thiessen)
138 static inline
139 unsigned IFStreamFlags(bool binary)
140 {
141 return binary ? (IOS_BASE::in | IOS_BASE::binary) : IOS_BASE::in;
142 }
143 */
144 #define IFStreamFlags(isBinary) \
145 (isBinary? (IOS_BASE::in | IOS_BASE::binary): IOS_BASE::in)
146
147
148 CStreamByteSource::CStreamByteSource(CNcbiIstream& in)
149 : m_Stream(&in)
150 {
151 }
152
153
154 CStreamByteSource::~CStreamByteSource(void)
155 {
156 }
157
158
159 CRef<CByteSourceReader> CStreamByteSource::Open(void)
160 {
161 return CRef<CByteSourceReader>
162 (new CStreamByteSourceReader(this, m_Stream));
163 }
164
165
166 /////////////////////////////////////////////////////////////////////////////
167 // CStreamByteSourceReader
168 /////////////////////////////////////////////////////////////////////////////
169
170 CStreamByteSourceReader::CStreamByteSourceReader(const CByteSource* source,
171 CNcbiIstream* stream)
172 : m_Source(source), m_Stream(stream)
173 {
174 }
175
176
177 CStreamByteSourceReader::~CStreamByteSourceReader(void)
178 {
179 }
180
181
182 size_t CStreamByteSourceReader::Read(char* buffer, size_t bufferLength)
183 {
184 return CStreamUtils::Readsome(*m_Stream, buffer, bufferLength);
185 }
186
187
188 bool CStreamByteSourceReader::EndOfData(void) const
189 {
190 return m_Stream->eof();
191 }
192
193
194 bool CStreamByteSourceReader::Pushback(const char* data, size_t size)
195 {
196 CStreamUtils::Stepback(*m_Stream, (CT_CHAR_TYPE*) data, (streamsize) size);
197 m_Stream->clear();
198 return true;
199 }
200
201
202 void CStreamByteSourceReader::Seekg(CNcbiStreampos pos)
203 {
204 m_Stream->seekg(pos);
205 }
206
207
208 /////////////////////////////////////////////////////////////////////////////
209 // CIRByteSourceReader
210 /////////////////////////////////////////////////////////////////////////////
211
212 CIRByteSourceReader::CIRByteSourceReader(IReader* reader)
213 : m_Reader(reader), m_EOF(false)
214 {
215 }
216
217
218 CIRByteSourceReader::~CIRByteSourceReader(void)
219 {
220 }
221
222
223 size_t CIRByteSourceReader::Read(char* buffer, size_t bufferLength)
224 {
225 size_t bytes_read;
226 ERW_Result result = m_Reader->Read(buffer, bufferLength, &bytes_read);
227 if ( result == eRW_Eof ) {
228 m_EOF = true;
229 }
230 return bytes_read;
231 }
232
233
234 bool CIRByteSourceReader::EndOfData(void) const
235 {
236 return m_EOF;
237 }
238
239
240 /////////////////////////////////////////////////////////////////////////////
241 // CFStreamByteSource
242 /////////////////////////////////////////////////////////////////////////////
243
244 CFStreamByteSource::CFStreamByteSource(CNcbiIstream& in)
245 : CStreamByteSource(in)
246 {
247 }
248
249
250 CFStreamByteSource::CFStreamByteSource(const string& fileName, bool binary)
251 : CStreamByteSource(*new CNcbiIfstream(fileName.c_str(),
252 IFStreamFlags(binary)))
253 {
254 if ( !*m_Stream ) {
255 NCBI_THROW(CUtilException,eNoInput,"file not found: " + fileName);
256 }
257 }
258
259
260 CFStreamByteSource::~CFStreamByteSource(void)
261 {
262 delete m_Stream;
263 }
264
265
266 /////////////////////////////////////////////////////////////////////////////
267 // CFileByteSource
268 /////////////////////////////////////////////////////////////////////////////
269
270 CFileByteSource::CFileByteSource(const string& fileName, bool binary)
271 : m_FileName(fileName), m_Binary(binary)
272 {
273 return;
274 }
275
276
277 CFileByteSource::CFileByteSource(const CFileByteSource& file)
278 : m_FileName(file.m_FileName), m_Binary(file.m_Binary)
279 {
280 return;
281 }
282
283
284 CFileByteSource::~CFileByteSource(void)
285 {
286 }
287
288
289 CRef<CByteSourceReader> CFileByteSource::Open(void)
290 {
291 return CRef<CByteSourceReader>(new CFileByteSourceReader(this));
292 }
293
294
295 /////////////////////////////////////////////////////////////////////////////
296 // CSubFileByteSource
297 /////////////////////////////////////////////////////////////////////////////
298
299 CSubFileByteSource::CSubFileByteSource(const CFileByteSource& file,
300 TFilePos start, TFileOff length)
301 : CParent(file), m_Start(start), m_Length(length)
302 {
303 return;
304 }
305
306
307 CSubFileByteSource::~CSubFileByteSource(void)
308 {
309 }
310
311
312 CRef<CByteSourceReader> CSubFileByteSource::Open(void)
313 {
314 return CRef<CByteSourceReader>
315 (new CSubFileByteSourceReader(this, m_Start, m_Length));
316 }
317
318 /////////////////////////////////////////////////////////////////////////////
319 // CFileByteSourceReader
320 /////////////////////////////////////////////////////////////////////////////
321
322 CFileByteSourceReader::CFileByteSourceReader(const CFileByteSource* source)
323 : CStreamByteSourceReader(source, 0),
324 m_FileSource(source),
325 m_FStream(source->GetFileName().c_str(),
326 IFStreamFlags(source->IsBinary()))
327 {
328 if ( !m_FStream ) {
329 // THROW1_TRACE(runtime_error, "file not found: " +
330 // source->GetFileName());
331 NCBI_THROW(CUtilException,eNoInput,
332 "file not found: " +source->GetFileName());
333 }
334 m_Stream = &m_FStream;
335 }
336
337
338 CFileByteSourceReader::~CFileByteSourceReader(void)
339 {
340 }
341
342
343 CRef<CSubSourceCollector>
344 CFileByteSourceReader::SubSource(size_t prepend,
345 CRef<CSubSourceCollector> parent)
346 {
347 return CRef<CSubSourceCollector>(new CFileSourceCollector(m_FileSource,
348 m_Stream->tellg() - TFileOff(prepend),
349 parent));
350 }
351
352 /////////////////////////////////////////////////////////////////////////////
353 // CSubFileByteSourceReader
354 /////////////////////////////////////////////////////////////////////////////
355
356 CSubFileByteSourceReader::CSubFileByteSourceReader(const CFileByteSource* s,
357 TFilePos start,
358 TFileOff length)
359 : CParent(s), m_Length(length)
360 {
361 m_Stream->seekg(start);
362 }
363
364
365 CSubFileByteSourceReader::~CSubFileByteSourceReader(void)
366 {
367 }
368
369
370 size_t CSubFileByteSourceReader::Read(char* buffer, size_t bufferLength)
371 {
372 if ( TFileOff(bufferLength) > m_Length ) {
373 bufferLength = size_t(m_Length);
374 }
375 size_t count = CParent::Read(buffer, bufferLength);
376 m_Length -= TFileOff(count);
377 return count;
378 }
379
380
381 bool CSubFileByteSourceReader::EndOfData(void) const
382 {
383 return m_Length == 0;
384 }
385
386
387 /////////////////////////////////////////////////////////////////////////////
388 // CFileSourceCollector
389 /////////////////////////////////////////////////////////////////////////////
390
391
392 CFileSourceCollector::CFileSourceCollector(CConstRef<CFileByteSource> s,
393 TFilePos start,
394 CRef<CSubSourceCollector> parent)
395 : CSubSourceCollector(parent),
396 m_FileSource(s),
397 m_Start(start),
398 m_Length(0)
399 {
400 }
401
402
403 CFileSourceCollector::~CFileSourceCollector(void)
404 {
405 }
406
407
408 void CFileSourceCollector::AddChunk(const char* buffer,
409 size_t bufferLength)
410 {
411 CSubSourceCollector::AddChunk(buffer, bufferLength);
412 m_Length += TFileOff(bufferLength);
413 }
414
415
416 CRef<CByteSource> CFileSourceCollector::GetSource(void)
417 {
418 return CRef<CByteSource>(new CSubFileByteSource(*m_FileSource,
419 m_Start, m_Length));
420 }
421
422
423 /////////////////////////////////////////////////////////////////////////////
424 // CMemoryChunk
425 /////////////////////////////////////////////////////////////////////////////
426
427 CMemoryChunk::CMemoryChunk(const char* data, size_t dataSize,
428 CRef<CMemoryChunk> prevChunk)
429 : m_Data(new char[dataSize]),
430 m_DataSize(dataSize)
431 {
432 memcpy(m_Data, data, dataSize);
433 if ( prevChunk ) {
434 prevChunk->m_NextChunk = this;
435 }
436 }
437
438
439 CMemoryChunk::~CMemoryChunk(void)
440 {
441 delete[] m_Data;
442 CRef<CMemoryChunk> next = m_NextChunk;
443 m_NextChunk.Reset();
444 while ( next && next->ReferencedOnlyOnce() ) {
445 CRef<CMemoryChunk> cur = next;
446 next = cur->m_NextChunk;
447 cur->m_NextChunk.Reset();
448 }
449 }
450
451
452 /////////////////////////////////////////////////////////////////////////////
453 // CMemoryByteSource
454 /////////////////////////////////////////////////////////////////////////////
455
456 CMemoryByteSource::CMemoryByteSource(CConstRef<CMemoryChunk> bytes)
457 : m_Bytes(bytes)
458 {
459 }
460
461
462 CMemoryByteSource::~CMemoryByteSource(void)
463 {
464 }
465
466
467 CRef<CByteSourceReader> CMemoryByteSource::Open(void)
468 {
469 return CRef<CByteSourceReader>(new CMemoryByteSourceReader(m_Bytes));
470 }
471
472
473 /////////////////////////////////////////////////////////////////////////////
474 // CMemoryByteSourceReader
475 /////////////////////////////////////////////////////////////////////////////
476
477
478 CMemoryByteSourceReader::CMemoryByteSourceReader(CConstRef<CMemoryChunk> bytes)
479 : m_CurrentChunk(bytes), m_CurrentChunkOffset(0)
480 {
481 }
482
483
484 CMemoryByteSourceReader::~CMemoryByteSourceReader(void)
485 {
486 }
487
488
489 size_t CMemoryByteSourceReader::Read(char* buffer, size_t bufferLength)
490 {
491 while ( m_CurrentChunk ) {
492 size_t avail = GetCurrentChunkAvailable();
493 if ( avail == 0 ) {
494 // End of current chunk
495 CConstRef<CMemoryChunk> rest = m_CurrentChunk->GetNextChunk();
496 m_CurrentChunk = rest;
497 m_CurrentChunkOffset = 0;
498 }
499 else {
500 size_t c = min(bufferLength, avail);
501 memcpy(buffer, m_CurrentChunk->GetData(m_CurrentChunkOffset), c);
502 m_CurrentChunkOffset += c;
503 return c;
504 }
505 }
506 return 0;
507 }
508
509
510 bool CMemoryByteSourceReader::EndOfData(void) const
511 {
512 return !m_CurrentChunk;
513 }
514
515
516 /////////////////////////////////////////////////////////////////////////////
517 // CMemorySourceCollector
518 /////////////////////////////////////////////////////////////////////////////
519
520 CMemorySourceCollector::CMemorySourceCollector(CRef<CSubSourceCollector>
521 parent)
522 : CSubSourceCollector(parent)
523 {
524 }
525
526
527 CMemorySourceCollector::~CMemorySourceCollector(void)
528 {
529 }
530
531
532 void CMemorySourceCollector::AddChunk(const char* buffer,
533 size_t bufferLength)
534 {
535 CSubSourceCollector::AddChunk(buffer, bufferLength);
536 m_LastChunk = new CMemoryChunk(buffer, bufferLength, m_LastChunk);
537 if ( !m_FirstChunk ) {
538 m_FirstChunk = m_LastChunk;
539 }
540 }
541
542
543 CRef<CByteSource> CMemorySourceCollector::GetSource(void)
544 {
545 return CRef<CByteSource>(new CMemoryByteSource(m_FirstChunk));
546 }
547
548
549 /////////////////////////////////////////////////////////////////////////////
550 // CWriterSourceCollector
551 /////////////////////////////////////////////////////////////////////////////
552
553 CWriterSourceCollector::CWriterSourceCollector(IWriter* writer,
554 EOwnership own,
555 CRef<CSubSourceCollector> parent)
556 : CSubSourceCollector(parent),
557 m_Writer(writer),
558 m_Own(own)
559 {
560 return;
561 }
562
563
564 CWriterSourceCollector::~CWriterSourceCollector()
565 {
566 if ( m_Own ) {
567 delete m_Writer;
568 }
569 }
570
571
572 void CWriterSourceCollector::SetWriter(IWriter* writer,
573 EOwnership own)
574 {
575 if ( m_Own ) {
576 delete m_Writer;
577 }
578 m_Writer = writer;
579 m_Own = own;
580 }
581
582
583 void CWriterSourceCollector::AddChunk(const char* buffer, size_t bufferLength)
584 {
585 CSubSourceCollector::AddChunk(buffer, bufferLength);
586 while ( bufferLength ) {
587 size_t written;
588 m_Writer->Write(buffer, bufferLength, &written);
589 buffer += written;
590 bufferLength -= written;
591 }
592 }
593
594
595 CRef<CByteSource> CWriterSourceCollector::GetSource(void)
596 {
597 // Return NULL byte source, this happens because we cannot derive
598 // any readers from IWriter (one way interface)
599 return CRef<CByteSource>();
600 }
601
602
603 /////////////////////////////////////////////////////////////////////////////
604 // CWriterByteSourceReader
605 /////////////////////////////////////////////////////////////////////////////
606
607 CWriterByteSourceReader::CWriterByteSourceReader(CNcbiIstream* stream,
608 IWriter* writer)
609 : CStreamByteSourceReader(0 /* CByteSource* */, stream),
610 m_Writer(writer)
611 {
612 _ASSERT(writer);
613 }
614
615
616 CWriterByteSourceReader::~CWriterByteSourceReader(void)
617 {
618 }
619
620
621 CRef<CSubSourceCollector>
622 CWriterByteSourceReader::SubSource(size_t /*prepend*/,
623 CRef<CSubSourceCollector> parent)
624 {
625 return
626 CRef<CSubSourceCollector>(
627 new CWriterSourceCollector(m_Writer, eNoOwnership, parent));
628 }
629
630
631 /////////////////////////////////////////////////////////////////////////////
632 // CWriterCopyByteSourceReader
633 /////////////////////////////////////////////////////////////////////////////
634
635 CWriterCopyByteSourceReader::CWriterCopyByteSourceReader(CByteSourceReader* reader, IWriter* writer)
636 : m_Reader(reader),
637 m_Writer(writer)
638 {
639 _ASSERT(reader);
640 _ASSERT(writer);
641 }
642
643
644 CWriterCopyByteSourceReader::~CWriterCopyByteSourceReader(void)
645 {
646 }
647
648
649 size_t CWriterCopyByteSourceReader::Read(char* buffer, size_t bufferLength)
650 {
651 return m_Reader->Read(buffer, bufferLength);
652 }
653
654
655 bool CWriterCopyByteSourceReader::EndOfData(void) const
656 {
657 return m_Reader->EndOfData();
658 }
659
660
661 CRef<CSubSourceCollector>
662 CWriterCopyByteSourceReader::SubSource(size_t /*prepend*/,
663 CRef<CSubSourceCollector> parent)
664 {
665 return
666 CRef<CSubSourceCollector>(
667 new CWriterSourceCollector(m_Writer, eNoOwnership, parent));
668 }
669
670
671 END_NCBI_SCOPE
672 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |