00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <spl/types.h>
00018
00019 #ifdef _WINDOWS
00020 #include <spl/configwin32.h>
00021 #include <stdio.h>
00022 #else
00023 #include <spl/autoconf/config.h>
00024 #endif
00025
00026 #include <spl/io/BlockingStream.h>
00027 #include <spl/io/DualChannelStream.h>
00028 #include <spl/Int64.h>
00029 #include <spl/io/NullStream.h>
00030 #include <spl/text/StringBuffer.h>
00031 #include <spl/io/Stream.h>
00032 #include <spl/io/StreamBuffer.h>
00033 #include <spl/io/StreamDelegateDispatch.h>
00034 #include <spl/io/TextStream.h>
00035 #include <spl/io/ThreadSafeStream.h>
00036 #include <stdarg.h>
00037 #ifdef HAVE_ERRNO_H
00038 #include <errno.h>
00039 #endif
00040
00041 extern char *int32toa( int32 i, char *buf, const int buflen );
00042
00043 using namespace spl;
00044
00045 StreamDelegateDispatch::~StreamDelegateDispatch()
00046 {
00047 }
00048
00049 void StreamDelegateDispatch::Add(IStreamReadListener *l)
00050 {
00051 m_onClose += Delegate<IStreamReadListener>::Create(l, &IStreamReadListener::IStreamRead_OnClose);
00052 m_onError += DelegateOneParameter<IStreamReadListener, const String&>::Create(l, &IStreamReadListener::IStreamRead_OnError);
00053 m_onRead += DelegateTwoParameter<IStreamReadListener, const Array<byte>&, int>::Create(l, &IStreamReadListener::IStreamRead_OnRead);
00054 }
00055
00056 #ifdef DEBUG
00057 void StreamDelegateDispatch::ValidateMem() const
00058 {
00059 m_onClose.ValidateMem();
00060 m_onError.ValidateMem();
00061 m_onRead.ValidateMem();
00062 }
00063
00064 void StreamDelegateDispatch::CheckMem() const
00065 {
00066 m_onClose.CheckMem();
00067 m_onError.CheckMem();
00068 m_onRead.CheckMem();
00069 }
00070 #endif
00071
00072 IStreamReadListener::~IStreamReadListener()
00073 {
00074 }
00075
00076 IStream::IStream()
00077 {
00078 }
00079
00080 IStream::~IStream()
00081 {
00082 }
00083
00084 IStreamState::IStreamState( IStream* parent, IStreamState **parentStateVar )
00085 : m_parent(parent), m_holder(parentStateVar)
00086 {
00087 }
00088
00089 IStreamState::~IStreamState()
00090 {
00091 }
00092
00093 void IStreamState::ChangeState(IStreamState *newState)
00094 {
00095 this->OnLeave( newState );
00096 newState->OnEnter( this );
00097 *m_holder = newState;
00098 delete this;
00099 }
00100
00101 NullStream::NullStream()
00102 {
00103 }
00104
00105 NullStream::~NullStream()
00106 {
00107 }
00108
00109 void NullStream::Close()
00110 {
00111 }
00112
00113 void NullStream::Flush()
00114 {
00115 }
00116
00117 int NullStream::Read(Array<byte>& buffer, const int offset, int count)
00118 {
00119 buffer[offset] = 0;
00120 return 0;
00121 }
00122
00123 int NullStream::ReadByte()
00124 {
00125 return 0;
00126 }
00127
00128 long NullStream::Seek(const long offset, const SeekOrigin origin)
00129 {
00130 return 0;
00131 }
00132
00133 void NullStream::Write(const Array<byte>& buffer, const int offset, const int count)
00134 {
00135 }
00136
00137 void NullStream::WriteByte(byte value)
00138 {
00139 }
00140
00141 bool NullStream::CanRead() const
00142 {
00143 return true;
00144 }
00145
00146 bool NullStream::CanSeek() const
00147 {
00148 return true;
00149 }
00150
00151 bool NullStream::CanWrite() const
00152 {
00153 return true;
00154 }
00155
00156 long NullStream::Length() const
00157 {
00158 return 0;
00159 }
00160
00161 long NullStream::Position() const
00162 {
00163 return 0;
00164 }
00165
00166 #ifdef DEBUG
00167 void NullStream::ValidateMem() const
00168 {
00169 }
00170
00171 void NullStream::CheckMem() const
00172 {
00173 }
00174 #endif
00175
00176 DualChannelStream::DualChannelStream(IStreamPtr input, IStreamPtr output, bool canClose)
00177 : m_in(input), m_out(output)
00178 {
00179 }
00180
00181 DualChannelStream::~DualChannelStream()
00182 {
00183 }
00184
00185 void DualChannelStream::Close()
00186 {
00187 m_in->Close();
00188 m_out->Close();
00189 }
00190
00191 void DualChannelStream::Flush()
00192 {
00193 m_in->Flush();
00194 m_out->Flush();
00195 }
00196
00197 int DualChannelStream::Read(Array<byte>& buffer, const int offset, int count)
00198 {
00199 return m_in->Read(buffer, offset, count);
00200 }
00201
00202 int DualChannelStream::ReadByte()
00203 {
00204 return m_in->ReadByte();
00205 }
00206
00207 long DualChannelStream::Seek(const long offset, const SeekOrigin origin)
00208 {
00209 return m_out->Seek(offset, origin);
00210 }
00211
00212 void DualChannelStream::Write(const Array<byte>& buffer, const int offset, const int count)
00213 {
00214 m_out->Write(buffer, offset, count);
00215 }
00216
00217 void DualChannelStream::WriteByte(byte value)
00218 {
00219 m_out->WriteByte(value);
00220 }
00221
00222 bool DualChannelStream::CanRead() const
00223 {
00224 return m_in->CanRead();
00225 }
00226
00227 bool DualChannelStream::CanSeek() const
00228 {
00229 return m_out->CanSeek();
00230 }
00231
00232 bool DualChannelStream::CanWrite() const
00233 {
00234 return m_out->CanWrite();
00235 }
00236
00237 long DualChannelStream::Length() const
00238 {
00239 return m_in->Length();
00240 }
00241
00242 long DualChannelStream::Position() const
00243 {
00244 return m_out->Position();
00245 }
00246
00247 #ifdef DEBUG
00248 void DualChannelStream::ValidateMem() const
00249 {
00250 m_in.ValidateMem();
00251 m_out.ValidateMem();
00252 }
00253
00254 void DualChannelStream::CheckMem() const
00255 {
00256 m_in.CheckMem();
00257 m_out.CheckMem();
00258 }
00259 #endif
00260
00261 BlockingStream::BlockingStream(IStreamPtr strm)
00262 : m_strm(strm), m_dataready(), m_datalock()
00263 {
00264 ASSERT(m_strm->CanRead());
00265 }
00266
00267 BlockingStream::~BlockingStream()
00268 {
00269 m_strm->Close();
00270 }
00271
00272 int BlockingStream::Read(Array<byte>& buffer, const int offset, int count)
00273 {
00274 int readbytes = 0;
00275
00276 while ( 0 == readbytes )
00277 {
00278 m_datalock.Lock();
00279 int pending = m_strm->Length();
00280 m_datalock.Unlock();
00281 if ( 0 == pending )
00282 {
00283 m_dataready.Wait();
00284 }
00285 m_datalock.Lock();
00286 readbytes = m_strm->Read(buffer, offset, count);
00287 m_datalock.Unlock();
00288 }
00289 return readbytes;
00290 }
00291
00292 int BlockingStream::ReadByte()
00293 {
00294 Array<byte> buf(1);
00295 int count = Read(buf, 0, 1);
00296 if ( 0 >= count )
00297 {
00298 return -1;
00299 }
00300 return (int)buf[0];
00301 }
00302
00303 void BlockingStream::Write(const Array<byte>& buffer, const int offset, const int count)
00304 {
00305 m_datalock.Lock();
00306 m_strm->Write(buffer, offset, count);
00307 m_datalock.Unlock();
00308 m_dataready.Notify();
00309 }
00310
00311 void BlockingStream::WriteByte(byte value)
00312 {
00313 Array<byte> buf(1);
00314 buf[0] = value;
00315 Write(buf, 0, 1);
00316 }
00317
00318 void BlockingStream::Close()
00319 {
00320 m_strm->Close();
00321 }
00322
00323 void BlockingStream::Flush()
00324 {
00325 m_strm->Flush();
00326 }
00327
00328 long BlockingStream::Seek(const long offset, const SeekOrigin origin)
00329 {
00330 return m_strm->Seek(offset, origin);
00331 }
00332
00333 bool BlockingStream::CanRead() const
00334 {
00335 return m_strm->CanRead();
00336 }
00337
00338 bool BlockingStream::CanSeek() const
00339 {
00340 return m_strm->CanSeek();
00341 }
00342
00343 bool BlockingStream::CanWrite() const
00344 {
00345 return m_strm->CanWrite();
00346 }
00347
00348 long BlockingStream::Length() const
00349 {
00350 return m_strm->Length();
00351 }
00352
00353 long BlockingStream::Position() const
00354 {
00355 return m_strm->Position();
00356 }
00357
00358 #ifdef DEBUG
00359 void BlockingStream::ValidateMem() const
00360 {
00361 m_strm->ValidateMem();
00362 }
00363
00364 void BlockingStream::CheckMem() const
00365 {
00366 m_strm.CheckMem();
00367 }
00368 #endif
00369
00370 TextWriter::TextWriter(IStreamPtr strm)
00371 : m_strm(strm)
00372 {
00373 if ( ! m_strm->CanWrite() )
00374 {
00375 throw new InvalidArgumentException("Stream is not writable.");
00376 }
00377 }
00378
00379 TextWriter::~TextWriter()
00380 {
00381 }
00382
00383 void TextWriter::Close()
00384 {
00385 m_strm->Close();
00386 }
00387
00388 void TextWriter::Flush()
00389 {
00390 m_strm->Flush();
00391 }
00392
00393 void TextWriter::Write(const String& buf)
00394 {
00395 ASSERT ( sizeof(char) == sizeof(byte) );
00396
00397 m_strm->Write( buf.ToByteArray() );
00398 }
00399
00400 void TextWriter::Write(byte b)
00401 {
00402 Write((unsigned int)b);
00403 }
00404
00405 void TextWriter::Write(int8 i)
00406 {
00407 char buf[128];
00408 int32toa(i, buf, 128);
00409 Write(buf);
00410 }
00411
00412 void TextWriter::Write(int16 i)
00413 {
00414 char buf[128];
00415 int32toa(i, buf, 128);
00416 Write(buf);
00417 }
00418
00419 void TextWriter::Write(int32 i)
00420 {
00421 char buf[128];
00422 int32toa(i, buf, 128);
00423 Write(buf);
00424 }
00425
00426 void TextWriter::Write(int64 i)
00427 {
00428 Write(*Int64::ToString(i));
00429 }
00430
00431 void TextWriter::Write(uint16 i)
00432 {
00433 char buf[128];
00434 int32toa(i, buf, 128);
00435 Write(buf);
00436 }
00437
00438 void TextWriter::Write(uint32 i)
00439 {
00440 char buf[128];
00441 int32toa(i, buf, 128);
00442 Write(buf);
00443 }
00444
00445 void TextWriter::Write(float32 f)
00446 {
00447 char buf[128];
00448 sprintf(buf, "%f", f);
00449 Write(buf);
00450 }
00451
00452 void TextWriter::Write(float64 f)
00453 {
00454 char buf[128];
00455 sprintf(buf, "%lf", f);
00456 Write(buf);
00457 }
00458
00459 void TextWriter::WriteLine(const String& str)
00460 {
00461 Write(str);
00462 #ifdef _WINDOWS
00463 Write("\r\n");
00464 #elif _MACOSX
00465 Write("\r");
00466 #else
00467 Write("\n");
00468 #endif
00469 }
00470
00471
00472 void TextWriter::WriteFormat(const String fmt, ...)
00473 {
00474 va_list marker;
00475 va_start(marker, fmt);
00476
00477 StringPtr str = String::FormatVA(fmt, marker);
00478
00479 Write(str->GetChars());
00480 }
00481
00482 #ifdef DEBUG
00483 void TextWriter::ValidateMem() const
00484 {
00485 m_strm.ValidateMem();
00486 }
00487
00488 void TextWriter::CheckMem() const
00489 {
00490 m_strm.CheckMem();
00491 }
00492 #endif
00493
00494 TextReader::TextReader(IStreamPtr strm)
00495 : m_strm(strm), m_peekch(-1)
00496 {
00497 }
00498
00499 TextReader::~TextReader()
00500 {
00501 }
00502
00503 void TextReader::Close()
00504 {
00505 m_strm->Close();
00506 }
00507
00508 int TextReader::Peek()
00509 {
00510 if ( m_peekch > -1 )
00511 {
00512 return m_peekch;
00513 }
00514 m_peekch = Read();
00515 return m_peekch;
00516 }
00517
00518 int TextReader::Read()
00519 {
00520 return _Read();
00521 }
00522
00523 int TextReader::ReadBlock(Array<byte>& buf, int offset, int count)
00524 {
00525 ASSERT( count > 0 && offset >= 0 );
00526 if ( m_peekch > -1 )
00527 {
00528 buf[offset++] = (char)m_peekch;
00529 count--;
00530 }
00531
00532 ASSERT ( sizeof(char) == sizeof(byte) );
00533 return m_strm->Read(buf, offset, count);
00534 }
00535
00536 bool TextReader::ReadLine(StringBuffer& sb)
00537 {
00538 int ch;
00539
00540 while ( '\n' != (ch = _Read()) )
00541 {
00542 if ( -1 == ch )
00543 {
00544 if ( sb.Length() == 0 )
00545 {
00546 return false;
00547 }
00548 return true;
00549 }
00550 if ( '\r' != ch )
00551 {
00552 sb.Append( (char)ch );
00553 }
00554 }
00555 return true;
00556 }
00557
00558 StringPtr TextReader::ReadLine()
00559 {
00560 StringBuffer buf;
00561 if ( ReadLine(buf) )
00562 {
00563 return buf.ToString();
00564 }
00565 return StringPtr();
00566 }
00567
00568 bool TextReader::ReadLine(Array<byte>& buf, int& lineLen)
00569 {
00570 int buflen = buf.Length();
00571 lineLen = 0;
00572
00573 ASSERT( buflen > 0 );
00574 int ch = _Read();
00575
00576 if ( -1 == ch )
00577 {
00578 return false;
00579 }
00580
00581 while ( lineLen < (buflen-1) && ch != '\n' && ch != -1 )
00582 {
00583 if ( '\r' != ch )
00584 {
00585 buf[lineLen++] = ch;
00586 }
00587 ch = _Read();
00588 }
00589 buf[lineLen++] = '\0';
00590
00591 return true;
00592 }
00593
00594 StringPtr TextReader::ReadToEnd()
00595 {
00596 StringBuffer buf;
00597 int ch;
00598
00599 while ( (ch = _Read()) > -1 )
00600 {
00601 m_strm->ValidateMem();
00602 buf.Append( (char)ch );
00603 }
00604 return buf.ToString();
00605 }
00606
00607 #ifdef DEBUG
00608 void TextReader::ValidateMem() const
00609 {
00610 m_strm.ValidateMem();
00611 }
00612
00613 void TextReader::CheckMem() const
00614 {
00615 m_strm.CheckMem();
00616 }
00617 #endif
00618
00619 ThreadSafeStream::ThreadSafeStream( IStreamPtr strm )
00620 : m_strm(strm), m_lock()
00621 {
00622 }
00623
00624 ThreadSafeStream::~ThreadSafeStream()
00625 {
00626 m_strm->Close();
00627 }
00628
00629 void ThreadSafeStream::Close()
00630 {
00631 m_strm->Close();
00632 }
00633
00634 void ThreadSafeStream::Flush()
00635 {
00636 m_lock.Lock();
00637 m_strm->Flush();
00638 m_lock.Unlock();
00639 }
00640
00641 int ThreadSafeStream::Read(Array<byte>& buffer, const int offset, int count)
00642 {
00643 m_lock.Lock();
00644 int ret = m_strm->Read(buffer, offset, count);
00645 m_lock.Unlock();
00646 return ret;
00647 }
00648
00649 int ThreadSafeStream::ReadByte()
00650 {
00651 m_lock.Lock();
00652 int ch = m_strm->ReadByte();
00653 m_lock.Unlock();
00654 return ch;
00655 }
00656
00657 long ThreadSafeStream::Seek(const long offset, const SeekOrigin origin)
00658 {
00659 m_lock.Lock();
00660 long ret = m_strm->Seek(offset, origin);
00661 m_lock.Unlock();
00662 return ret;
00663 }
00664
00665 void ThreadSafeStream::Write(const Array<byte>& buffer, const int offset, const int count)
00666 {
00667 m_lock.Lock();
00668 m_strm->Write(buffer, offset, count);
00669 m_lock.Unlock();
00670 }
00671
00672 void ThreadSafeStream::WriteByte(byte value)
00673 {
00674 m_lock.Lock();
00675 m_strm->WriteByte(value);
00676 m_lock.Unlock();
00677 }
00678
00679 bool ThreadSafeStream::CanRead() const
00680 {
00681 return m_strm->CanRead();
00682 }
00683
00684 bool ThreadSafeStream::CanSeek() const
00685 {
00686 return m_strm->CanSeek();
00687 }
00688
00689 bool ThreadSafeStream::CanWrite() const
00690 {
00691 return m_strm->CanWrite();
00692 }
00693
00694 long ThreadSafeStream::Length() const
00695 {
00696 long len = m_strm->Length();
00697 return len;
00698 }
00699
00700 long ThreadSafeStream::Position() const
00701 {
00702 long ret = m_strm->Position();
00703 return ret;
00704 }
00705
00706 #ifdef DEBUG
00707 void ThreadSafeStream::ValidateMem() const
00708 {
00709 m_strm.ValidateMem();
00710 }
00711
00712 void ThreadSafeStream::CheckMem() const
00713 {
00714 m_strm.CheckMem();
00715 }
00716 #endif
00717
00718 StreamBuffer::StreamBuffer( IStreamPtr strm, const int buflen )
00719 : m_strm(strm),
00720 m_bufpos(0),
00721 m_buflen(buflen),
00722 m_buf(buflen)
00723 {
00724 }
00725
00726 StreamBuffer::~StreamBuffer()
00727 {
00728 Flush();
00729 m_strm->Close();
00730 }
00731
00732 void StreamBuffer::Close()
00733 {
00734 Flush();
00735 m_strm->Close();
00736 }
00737
00738 void StreamBuffer::Flush()
00739 {
00740 if ( m_bufpos > 0 && m_strm->CanWrite() )
00741 {
00742 m_strm->Write(m_buf, 0, m_bufpos);
00743 }
00744 m_bufpos = 0;
00745 }
00746
00747 int StreamBuffer::Read(Array<byte>& buffer, const int offset, int count)
00748 {
00749 if ( m_bufpos == 0 )
00750 {
00751
00752 m_bufpos = m_strm->Read(m_buf, 0, m_buflen);
00753 if ( m_bufpos < 0 )
00754 {
00755 m_bufpos = 0;
00756 return -1;
00757 }
00758 }
00759 if ( count > m_bufpos )
00760 {
00761 count = m_bufpos;
00762 }
00763 ASSERT( m_bufpos >= count );
00764 memcpy(&buffer[offset], m_buf, count);
00765 memcpy(m_buf, &m_buf[count], m_bufpos - count);
00766 m_bufpos -= count;
00767 return count;
00768 }
00769
00770 int StreamBuffer::ReadByte()
00771 {
00772 Array<byte> buf(1);
00773 if ( 0 >= StreamBuffer::Read(buf, 0, 1) )
00774 {
00775 return -1;
00776 }
00777 return (int)buf[0];
00778 }
00779
00780 long StreamBuffer::Seek(const long offset, const SeekOrigin origin)
00781 {
00782 Flush();
00783 return m_strm->Seek(offset, origin);
00784 }
00785
00786 void StreamBuffer::Write(const Array<byte>& buffer, const int offset, const int count)
00787 {
00788 if ( m_bufpos + count >= m_buflen )
00789 {
00790 Flush();
00791 }
00792 if ( count >= m_buflen )
00793 {
00794 m_strm->Write(buffer, offset, count);
00795 }
00796 else
00797 {
00798 memcpy(&m_buf[m_bufpos], &buffer[offset], count);
00799 m_bufpos += count;
00800 }
00801 ASSERT( m_bufpos < m_buflen );
00802 }
00803
00804 void StreamBuffer::WriteByte(byte value)
00805 {
00806 if ( m_bufpos + 1 >= m_buflen )
00807 {
00808 Flush();
00809 }
00810 m_buf[m_bufpos++] = value;
00811 }
00812
00813 bool StreamBuffer::CanRead() const
00814 {
00815 return m_strm->CanRead();
00816 }
00817
00818 bool StreamBuffer::CanSeek() const
00819 {
00820 return m_strm->CanSeek();
00821 }
00822
00823 bool StreamBuffer::CanWrite() const
00824 {
00825 return m_strm->CanWrite();
00826 }
00827
00828 long StreamBuffer::Length() const
00829 {
00830 return m_strm->Length();
00831 }
00832
00833 long StreamBuffer::Position() const
00834 {
00835 if ( 0 != m_bufpos )
00836 {
00837 throw new IOException("StreamBuffer: Flush before calling Position");
00838 }
00839 return m_strm->Position();
00840 }
00841
00842 #ifdef DEBUG
00843 void StreamBuffer::ValidateMem() const
00844 {
00845 m_buf.ValidateMem();
00846 m_strm.ValidateMem();
00847 }
00848
00849 void StreamBuffer::CheckMem() const
00850 {
00851 m_buf.CheckMem();
00852 m_strm.CheckMem();
00853 }
00854 #endif