]>
git.saurik.com Git - wxWidgets.git/blob - src/common/stream.cpp
d546ab473f105de674d389e5d20b18e70a39afe6
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxStream base classes 
   4 // Author:      Guilhem Lavaux 
   8 // Copyright:   (c) Guilhem Lavaux 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "stream.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  19 #include <wx/stream.h> 
  20 #include <wx/datstrm.h> 
  21 #include <wx/objstrm.h> 
  27 // ---------------------------------------------------------------------------- 
  29 // ---------------------------------------------------------------------------- 
  31 wxStreamBuffer::wxStreamBuffer(wxInputStream
& i_stream
) 
  32   : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
), 
  33     m_buffer_size(0), m_istream(&i_stream
), m_ostream(NULL
) 
  37 wxStreamBuffer::wxStreamBuffer(wxOutputStream
& o_stream
) 
  38   : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
), 
  39     m_buffer_size(0), m_istream(NULL
), m_ostream(&o_stream
) 
  43 wxStreamBuffer::~wxStreamBuffer() 
  45   wxDELETEA(m_buffer_start
); 
  48 void wxStreamBuffer::WriteBack(char c
) 
  53   // Assume that if we write "back" we have read a few bytes: so we have some 
  55   if (m_buffer_pos 
== m_buffer_start
) 
  62 void wxStreamBuffer::SetBufferIO(char *buffer_start
, char *buffer_end
) 
  66   m_buffer_start 
= buffer_start
; 
  67   m_buffer_end   
= buffer_end
; 
  69   m_buffer_size 
= m_buffer_end
-m_buffer_start
; 
  72     ret 
= m_istream
->DoRead(m_buffer_start
, m_buffer_size
); 
  73     m_buffer_end 
= m_buffer_start 
+ ret
; 
  75   m_buffer_pos 
= m_buffer_start
; 
  78 void wxStreamBuffer::SetBufferIO(size_t bufsize
) 
  82   wxDELETE(m_buffer_start
); 
  85     m_buffer_start 
= NULL
; 
  92   b_start 
= new char[bufsize
]; 
  94   SetBufferIO(b_start
, b_start 
+ bufsize
); 
  97 void wxStreamBuffer::ResetBuffer() 
 100     m_buffer_pos 
= m_buffer_end
; 
 102     m_buffer_pos 
= m_buffer_start
; 
 105 void wxStreamBuffer::Read(void *buffer
, size_t size
) 
 107   wxASSERT(m_istream 
!= NULL
); 
 109   // ------------------ 
 110   // Buffering disabled 
 111   // ------------------ 
 113   if (!m_buffer_size
) { 
 114     m_istream
->m_lastread 
= m_istream
->DoRead(buffer
, size
); 
 121   size_t buf_left
, orig_size 
= size
; 
 125     buf_left 
= m_buffer_end 
- m_buffer_pos
;  
 127     // First case: the requested buffer is larger than the stream buffer, 
 129     if (size 
> buf_left
) { 
 130       memcpy(buffer
, m_buffer_pos
, buf_left
); 
 132       buffer 
= (char *)buffer 
+ buf_left
; // ANSI C++ violation. 
 134       read_ret 
= m_istream
->DoRead(m_buffer_start
, m_buffer_size
); 
 138         m_istream
->m_lastread 
= orig_size
-size
; 
 139         m_istream
->m_eof 
= TRUE
; 
 140         m_buffer_pos 
= m_buffer_end 
= m_buffer_start
; 
 143         m_buffer_end 
= m_buffer_start
+read_ret
; 
 144         m_buffer_pos 
= m_buffer_start
; 
 148       // Second case: we just copy from the stream buffer. 
 149       memcpy(buffer
, m_buffer_pos
, size
); 
 150       m_buffer_pos 
+= size
; 
 154   m_istream
->m_lastread 
= orig_size
; 
 157 void wxStreamBuffer::Write(const void *buffer
, size_t size
) 
 159   wxASSERT(m_ostream 
!= NULL
); 
 161   // ------------------ 
 162   // Buffering disabled 
 163   // ------------------ 
 165   if (!m_buffer_size
) { 
 166     m_ostream
->m_lastwrite 
= m_ostream
->DoWrite(buffer
, size
); 
 170   // ------------------ 
 172   // ------------------ 
 174   size_t buf_left
, orig_size 
= size
; 
 178     buf_left 
= m_buffer_end 
- m_buffer_pos
; 
 180     // First case: the buffer to write is larger than the stream buffer, 
 182     if (size 
> buf_left
) { 
 183       memcpy(m_buffer_pos
, buffer
, buf_left
); 
 185       buffer 
= (char *)buffer 
+ buf_left
; // ANSI C++ violation. 
 187       write_ret 
= m_ostream
->DoWrite(m_buffer_start
, m_buffer_size
); 
 188       if (write_ret 
!= m_buffer_size
) { 
 189         m_ostream
->m_bad 
= TRUE
; 
 190         m_ostream
->m_lastwrite 
= orig_size
-size
; 
 191         m_buffer_pos 
= m_buffer_end 
= m_buffer_start
; 
 194       m_buffer_pos 
= m_buffer_start
; 
 198       // Second case: just copy it in the stream buffer. 
 200       memcpy(m_buffer_pos
, buffer
, size
); 
 201       m_buffer_pos 
+= size
; 
 205   m_ostream
->m_lastwrite 
= orig_size
; 
 208 // ---------------------------------------------------------------------------- 
 210 // ---------------------------------------------------------------------------- 
 212 wxInputStream::wxInputStream() 
 214   m_i_destroybuf 
= TRUE
; 
 215   m_i_streambuf 
= new wxStreamBuffer(*this); 
 220 wxInputStream::wxInputStream(wxStreamBuffer 
*buffer
) 
 222   m_i_destroybuf 
= FALSE
; 
 223   m_i_streambuf 
= buffer
; 
 228 wxInputStream::~wxInputStream() 
 231     delete m_i_streambuf
; 
 234 char wxInputStream::GetC() 
 237   m_i_streambuf
->Read(&c
, 1); 
 241 wxInputStream
& wxInputStream::Read(void *buffer
, size_t size
) 
 243   m_i_streambuf
->Read(buffer
, size
); 
 244   // wxStreamBuffer sets all variables for us 
 248 #define BUF_TEMP_SIZE 10000 
 250 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
) 
 252   char buf
[BUF_TEMP_SIZE
];  
 253   size_t bytes_read 
= BUF_TEMP_SIZE
; 
 255   while (bytes_read 
== BUF_TEMP_SIZE 
&& !stream_out
.Bad()) { 
 256     bytes_read 
= Read(buf
, bytes_read
).LastRead(); 
 258     stream_out
.Write(buf
, bytes_read
); 
 263 wxInputStream
& wxInputStream::operator>>(wxString
& line
) 
 265   wxDataInputStream 
s(*this); 
 271 wxInputStream
& wxInputStream::operator>>(char& c
) 
 277 wxInputStream
& wxInputStream::operator>>(short& i
) 
 286 wxInputStream
& wxInputStream::operator>>(int& i
) 
 295 wxInputStream
& wxInputStream::operator>>(long& i
) 
 297   /* I only implemented a simple integer parser */ 
 300   while (isspace( c 
= GetC() ) ) 
 304   if (! (c 
== '-' || isdigit(c
)) ) { 
 305     InputStreamBuffer()->WriteBack(c
); 
 325 wxInputStream
& wxInputStream::operator>>(float& f
) 
 327   /* I only implemented a simple float parser */ 
 330   while (isspace( c 
= GetC() ) ) 
 334   if (! (c 
== '-' || isdigit(c
)) ) { 
 335     InputStreamBuffer()->WriteBack(c
); 
 351     float f_multiplicator 
= 0.1; 
 355       f 
+= c
*f_multiplicator
; 
 356       f_multiplicator 
/= 10; 
 366 wxInputStream
& wxInputStream::operator>>(wxObject 
*& obj
) 
 368   wxObjectInputStream 
obj_s(*this); 
 369   obj 
= obj_s
.LoadObject(); 
 373 off_t 
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
) 
 375   off_t ret_off
, diff
, last_access
; 
 377   last_access 
= m_i_streambuf
->GetLastAccess(); 
 381     diff 
= DoTellInput() - pos
; 
 382     if ( diff 
< 0 || diff 
> last_access  
) { 
 383       ret_off 
= DoSeekInput(pos
, wxFromStart
); 
 384       m_i_streambuf
->ResetBuffer(); 
 387       m_i_streambuf
->SetIntPosition(last_access 
- diff
); 
 391     diff 
= pos 
+ m_i_streambuf
->GetIntPosition(); 
 393     if ( (diff 
> last_access
) || (diff 
< 0) ) { 
 394       ret_off 
= DoSeekInput(pos
, wxFromCurrent
); 
 395       m_i_streambuf
->ResetBuffer(); 
 398       m_i_streambuf
->SetIntPosition(diff
); 
 402     // Hard to compute: always seek to the requested position. 
 403     ret_off 
= DoSeekInput(pos
, wxFromEnd
); 
 404     m_i_streambuf
->ResetBuffer(); 
 407   return wxInvalidOffset
; 
 410 off_t 
wxInputStream::TellI() const 
 412   return DoTellInput() - m_i_streambuf
->GetLastAccess() + 
 413                          m_i_streambuf
->GetIntPosition(); 
 416 // ---------------------------------------------------------------------------- 
 418 // ---------------------------------------------------------------------------- 
 419 wxOutputStream::wxOutputStream() 
 421   m_o_destroybuf 
= TRUE
; 
 422   m_o_streambuf 
= new wxStreamBuffer(*this); 
 427 wxOutputStream::wxOutputStream(wxStreamBuffer 
*buffer
) 
 429   m_o_destroybuf 
= FALSE
; 
 430   m_o_streambuf 
= buffer
; 
 435 wxOutputStream::~wxOutputStream() 
 438     delete m_o_streambuf
; 
 441 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
) 
 443   m_o_streambuf
->Write(buffer
, size
); 
 447 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
) 
 449   stream_in
.Read(*this); 
 453 off_t 
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
) 
 459     if ( (unsigned)abs (DoTellOutput()-pos
) > m_o_streambuf
->GetLastAccess()  ) { 
 460       ret_off 
= DoSeekOutput(pos
, wxFromStart
); 
 461       m_o_streambuf
->ResetBuffer(); 
 464       m_o_streambuf
->SetIntPosition( DoTellOutput() - pos
); 
 468     if ( ((unsigned)pos 
> m_o_streambuf
->GetLastAccess()) || (pos 
< 0) ) { 
 469       ret_off 
= DoSeekOutput(pos
, wxFromCurrent
); 
 470       m_o_streambuf
->ResetBuffer(); 
 473       m_o_streambuf
->SetIntPosition(pos
); 
 477     // Hard to compute: always seek to the requested position. 
 478     ret_off 
= DoSeekOutput(pos
, wxFromEnd
); 
 479     m_o_streambuf
->ResetBuffer(); 
 482   return wxInvalidOffset
; 
 485 off_t 
wxOutputStream::TellO() const 
 487   return DoTellOutput() - m_o_streambuf
->GetLastAccess() 
 488                         + m_o_streambuf
->GetIntPosition(); 
 491 void wxOutputStream::Sync() 
 493   DoWrite(m_o_streambuf
->GetBufferStart(), m_o_streambuf
->GetIntPosition()); 
 495   m_o_streambuf
->ResetBuffer(); 
 498 wxOutputStream
& wxOutputStream::operator<<(const char *string
) 
 500   return Write(string
, strlen(string
)); 
 503 wxOutputStream
& wxOutputStream::operator<<(wxString
& string
) 
 505   return Write(string
, string
.Len()); 
 508 wxOutputStream
& wxOutputStream::operator<<(char c
) 
 513 wxOutputStream
& wxOutputStream::operator<<(short i
) 
 517   strint
.Printf("%i", i
); 
 518   return Write(strint
, strint
.Len()); 
 521 wxOutputStream
& wxOutputStream::operator<<(int i
) 
 525   strint
.Printf("%i", i
); 
 526   return Write(strint
, strint
.Len()); 
 529 wxOutputStream
& wxOutputStream::operator<<(long i
) 
 533   strlong
.Printf("%i", i
); 
 534   return Write((const char *)strlong
, strlong
.Len()); 
 537 wxOutputStream
& wxOutputStream::operator<<(double f
) 
 541   strfloat
.Printf("%f", f
); 
 542   return Write(strfloat
, strfloat
.Len()); 
 545 wxOutputStream
& wxOutputStream::operator<<(wxObject
& obj
) 
 547   wxObjectOutputStream 
obj_s(*this); 
 548   obj_s
.SaveObject(obj
); 
 552 // ---------------------------------------------------------------------------- 
 554 // ---------------------------------------------------------------------------- 
 557   : wxInputStream(), wxOutputStream() 
 561 // ---------------------------------------------------------------------------- 
 562 // wxFilterInputStream 
 563 // ---------------------------------------------------------------------------- 
 564 wxFilterInputStream::wxFilterInputStream() 
 565   : wxInputStream(NULL
) 
 569 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
) 
 570   : wxInputStream(NULL
) 
 572   m_parent_i_stream 
= &stream
; 
 573   m_i_streambuf 
= stream
.InputStreamBuffer(); 
 576 wxFilterInputStream::~wxFilterInputStream() 
 580 size_t wxFilterInputStream::DoRead(void *buffer
, size_t size
) 
 582   return m_parent_i_stream
->Read(buffer
, size
).LastRead(); 
 585 off_t 
wxFilterInputStream::DoSeekInput(off_t pos
, wxSeekMode mode
) 
 587   return m_parent_i_stream
->SeekI(pos
, mode
); 
 590 off_t 
wxFilterInputStream::DoTellInput() const 
 592   return m_parent_i_stream
->TellI(); 
 595 // ---------------------------------------------------------------------------- 
 596 // wxFilterOutputStream 
 597 // ---------------------------------------------------------------------------- 
 598 wxFilterOutputStream::wxFilterOutputStream() 
 599   : wxOutputStream(NULL
) 
 603 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
) 
 604   : wxOutputStream(NULL
) 
 606   m_parent_o_stream 
= &stream
; 
 607   m_o_streambuf 
= stream
.OutputStreamBuffer(); 
 610 wxFilterOutputStream::~wxFilterOutputStream() 
 614 size_t wxFilterOutputStream::DoWrite(const void *buffer
, size_t size
) 
 616   return m_parent_o_stream
->Write(buffer
, size
).LastWrite(); 
 619 off_t 
wxFilterOutputStream::DoSeekOutput(off_t pos
, wxSeekMode mode
) 
 621   return m_parent_o_stream
->SeekO(pos
, mode
); 
 624 off_t 
wxFilterOutputStream::DoTellOutput() const 
 626   return m_parent_o_stream
->TellO(); 
 629 // ---------------------------------------------------------------------------- 
 631 // ---------------------------------------------------------------------------- 
 633 wxFilterStream::wxFilterStream() 
 637 wxFilterStream::wxFilterStream(wxStream
& stream
) 
 638   : wxFilterInputStream(stream
), wxFilterOutputStream(stream
) 
 642 // ---------------------------------------------------------------------------- 
 643 // Some IOManip function 
 644 // ---------------------------------------------------------------------------- 
 646 wxOutputStream
& wxEndL(wxOutputStream
& stream
) 
 649   return stream
.Write("\r\n", 2); 
 651   return stream
.Write("\n", 1);