NCBI C++ Toolkit Cross Reference

C++/src/util/bytesrc.cpp


  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 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.