]> git.saurik.com Git - wxWidgets.git/commitdiff
* Ooops, I didn't copy the files in the right directory of my repository.
authorGuilhem Lavaux <lavaux@easynet.fr>
Fri, 24 Jul 1998 17:21:06 +0000 (17:21 +0000)
committerGuilhem Lavaux <lavaux@easynet.fr>
Fri, 24 Jul 1998 17:21:06 +0000 (17:21 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@362 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/datstrm.cpp
src/common/fstream.cpp
src/common/mstream.cpp
src/common/objstrm.cpp [new file with mode: 0644]
src/common/stream.cpp
src/common/zstream.cpp

index fa1eaa7d8907985caa467839fa6631a94c2ccbfd..a4cecc093b27b4651bf368023cfd8ef405f9cc00 100644 (file)
 #endif
 
 #include "wx/datstrm.h"
 #endif
 
 #include "wx/datstrm.h"
-
-/*
-#if !USE_SHARED_LIBRARY
-IMPLEMENT_CLASS(wxDataInputStream, wxFilterInputStream)
-IMPLEMENT_CLASS(wxDataOutputStream, wxFilterOutputStream)
-#endif
-*/
+#include "wx/bufstrm.h"
 
 wxDataInputStream::wxDataInputStream(wxInputStream& s)
   : wxFilterInputStream(s)
 
 wxDataInputStream::wxDataInputStream(wxInputStream& s)
   : wxFilterInputStream(s)
@@ -89,10 +83,30 @@ double wxDataInputStream::ReadDouble()
 
 wxString wxDataInputStream::ReadLine()
 {
 
 wxString wxDataInputStream::ReadLine()
 {
-  char i_strg[255];
-
-  // TODO: Implement ReadLine
-  return i_strg;
+  char c, last_endl = 0;
+  bool end_line = FALSE;
+  wxString line;
+
+  while (!end_line) {
+    c = GetC();
+    switch (c) {
+    case '\n':
+      end_line = TRUE;
+      break;
+    case '\r':
+      last_endl = '\r';
+      break;
+    default:
+      if (last_endl == '\r') {
+        end_line = TRUE;
+        InputStreamBuffer()->WriteBack(c);
+        break;
+      }
+      line += c;
+      break;
+    } 
+  }
+  return line;
 }
 
 wxString wxDataInputStream::ReadString()
 }
 
 wxString wxDataInputStream::ReadString()
index d1bfb0637bc0d4020de5e7ba0b73189491e59ca3..4014d31031a1c5267af7ac0f01c2b861fdfba59a 100644 (file)
 wxFileInputStream::wxFileInputStream(const wxString& fileName)
   : wxFile(fileName, read)
 {
 wxFileInputStream::wxFileInputStream(const wxString& fileName)
   : wxFile(fileName, read)
 {
-  m_lastread = 0;
+  m_i_streambuf->SetBufferIO(1024);
 }
 
 wxFileInputStream::~wxFileInputStream()
 {
 }
 
 }
 
 wxFileInputStream::~wxFileInputStream()
 {
 }
 
-wxInputStream& wxFileInputStream::Read(void *buffer, size_t size)
+char wxFileInputStream::Peek()
 {
 {
-  m_lastread = wxFile::Read(buffer, size);
-  return *this;
+  return 0;
 }
 
 }
 
-off_t wxFileInputStream::SeekI(off_t pos, wxSeekMode mode)
+size_t wxFileInputStream::DoRead(void *buffer, size_t size)
+{
+  return wxFile::Read(buffer, size);
+}
+
+off_t wxFileInputStream::DoSeekInput(off_t pos, wxSeekMode mode)
 {
   return wxFile::Seek(pos, mode);
 }
 
 {
   return wxFile::Seek(pos, mode);
 }
 
-off_t wxFileInputStream::TellI() const
+off_t wxFileInputStream::DoTellInput() const
 {
   return wxFile::Tell();
 }
 {
   return wxFile::Tell();
 }
@@ -62,32 +66,34 @@ off_t wxFileInputStream::TellI() const
 wxFileOutputStream::wxFileOutputStream(const wxString& fileName)
  : wxFile(fileName, write)
 {
 wxFileOutputStream::wxFileOutputStream(const wxString& fileName)
  : wxFile(fileName, write)
 {
-  m_lastwrite = 0;
+  m_o_streambuf->SetBufferIO(1024);
 }
 
 wxFileOutputStream::~wxFileOutputStream()
 {
 }
 
 wxFileOutputStream::~wxFileOutputStream()
 {
+  Sync();
 }
 
 }
 
-wxOutputStream& wxFileOutputStream::Write(const void *buffer, size_t size)
+size_t wxFileOutputStream::DoWrite(const void *buffer, size_t size)
 {
 {
-  m_lastwrite = wxFile::Write(buffer, size);
+  size_t ret = wxFile::Write(buffer, size);
   m_bad = wxFile::Error();
   m_bad = wxFile::Error();
-  return *this;
+  return ret;
 }
 
 }
 
-off_t wxFileOutputStream::TellO() const
+off_t wxFileOutputStream::DoTellOutput() const
 {
   return wxFile::Tell();
 }
 
 {
   return wxFile::Tell();
 }
 
-off_t wxFileOutputStream::SeekO(off_t pos, wxSeekMode mode)
+off_t wxFileOutputStream::DoSeekOutput(off_t pos, wxSeekMode mode)
 {
   return wxFile::Seek(pos, mode);
 }
 
 void wxFileOutputStream::Sync()
 {
 {
   return wxFile::Seek(pos, mode);
 }
 
 void wxFileOutputStream::Sync()
 {
+  wxOutputStream::Sync();
   wxFile::Flush();
 }
 
   wxFile::Flush();
 }
 
index d75c423885488611d96b110427b79f05df7436ae..9e1ee174f29feaba8078f4d9ea41108d5e787d6f 100644 (file)
@@ -67,29 +67,30 @@ wxMemoryInputStream::wxMemoryInputStream(const char *data, size_t len)
   m_lastread = 0;
   m_eof = FALSE;
   m_iolimit = 1;
   m_lastread = 0;
   m_eof = FALSE;
   m_iolimit = 1;
+
+  m_i_streambuf->SetBufferIO(0);
 }
 
 wxMemoryInputStream::~wxMemoryInputStream()
 {
 }
 
 }
 
 wxMemoryInputStream::~wxMemoryInputStream()
 {
 }
 
-wxInputStream& wxMemoryInputStream::Read(void *buffer, size_t size)
+size_t wxMemoryInputStream::DoRead(void *buffer, size_t size)
 {
   if (m_iolimit == 2) {
     m_eof = TRUE;
 {
   if (m_iolimit == 2) {
     m_eof = TRUE;
-    return *this;
+    return 0; 
   }
   if (m_position_i+size > m_length)
     size = m_length-m_position_i;
 
   memcpy((void *)((unsigned long)buffer+m_position_i), m_buffer, size);
   m_position_i += size;
   }
   if (m_position_i+size > m_length)
     size = m_length-m_position_i;
 
   memcpy((void *)((unsigned long)buffer+m_position_i), m_buffer, size);
   m_position_i += size;
-  m_lastread = size;
 
 
-  return *this;
+  return size;
 }
 
 }
 
-off_t wxMemoryInputStream::SeekI(off_t pos, wxSeekMode mode)
+off_t wxMemoryInputStream::DoSeekInput(off_t pos, wxSeekMode mode)
 {
   if (m_iolimit == 2)
     return 0;
 {
   if (m_iolimit == 2)
     return 0;
@@ -129,33 +130,35 @@ wxMemoryOutputStream::wxMemoryOutputStream(char *data, size_t len)
   m_lastwrite = 0;
   m_bad = FALSE;
   m_iolimit = 2;
   m_lastwrite = 0;
   m_bad = FALSE;
   m_iolimit = 2;
+
+  m_o_streambuf->SetBufferIO(0);
 }
 
 wxMemoryOutputStream::~wxMemoryOutputStream()
 {
 }
 
 wxMemoryOutputStream::~wxMemoryOutputStream()
 {
+  Sync();
 }
 
 }
 
-wxOutputStream& wxMemoryOutputStream::Write(const void *buffer, size_t size)
+size_t wxMemoryOutputStream::DoWrite(const void *buffer, size_t size)
 {
   if (m_iolimit == 1) {
     m_bad = TRUE;
 {
   if (m_iolimit == 1) {
     m_bad = TRUE;
-    return *this;
+    return 0;
   }
   
   if (m_position_o+size > m_length)
     if (!ChangeBufferSize(m_position_o+size)) {
       m_bad = TRUE;
   }
   
   if (m_position_o+size > m_length)
     if (!ChangeBufferSize(m_position_o+size)) {
       m_bad = TRUE;
-      return *this;
+      return 0;
     }
 
   memcpy(m_buffer+m_position_o, buffer, size);
   m_position_o += size;
     }
 
   memcpy(m_buffer+m_position_o, buffer, size);
   m_position_o += size;
-  m_lastwrite = size;
 
 
-  return *this;
+  return size;
 }
 
 }
 
-off_t wxMemoryOutputStream::SeekO(off_t pos, wxSeekMode mode)
+off_t wxMemoryOutputStream::DoSeekOutput(off_t pos, wxSeekMode mode)
 {
   if (m_iolimit == 1)
     return 0;
 {
   if (m_iolimit == 1)
     return 0;
diff --git a/src/common/objstrm.cpp b/src/common/objstrm.cpp
new file mode 100644 (file)
index 0000000..1d2b01d
--- /dev/null
@@ -0,0 +1,224 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        objstrm.cpp
+// Purpose:     wxObjectStream classes
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     16/07/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "objstrm.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/objstrm.h"
+#include "wx/datstrm.h"
+
+#define WXOBJ_BEGIN "OBEGIN"
+#define WXOBJ_BEG_LEN 6
+
+// ----------------------------------------------------------------------------
+// wxObjectOutputStream
+// ----------------------------------------------------------------------------
+
+wxObjectOutputStream::wxObjectOutputStream(wxOutputStream& s)
+  : wxFilterOutputStream(s)
+{
+  m_saving = FALSE;
+}
+
+wxString wxObjectOutputStream::GetObjectName(wxObject *obj)
+{
+  wxString name;
+
+  name.Printf("%x", (unsigned long)obj);
+  return name;
+}
+
+void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo& info)
+{
+  wxDataOutputStream data_s(*this); 
+
+  Write(WXOBJ_BEGIN, WXOBJ_BEG_LEN);
+  data_s.WriteString(info.object->GetClassInfo()->GetClassName());
+  data_s.WriteString(GetObjectName(info.object));
+  // I assume an object will not have millions of children
+  data_s.Write8(info.children.Number());
+}
+
+void wxObjectOutputStream::AddChildren(wxObject *obj)
+{
+  wxObjectStreamInfo *info;
+
+  if (!FirstStage())
+    return;
+
+  info = new wxObjectStreamInfo;
+  info->n_children = 0;
+  info->object = obj;
+  info->parent = m_current_info->object; // Not useful here.
+  m_current_info->n_children++;
+  m_current_info->children.Append(info);
+}
+
+void wxObjectOutputStream::ProcessObjectDef(wxObjectStreamInfo *info)
+{
+  wxNode *node;
+
+  m_current_info = info;
+  // First stage: get children of obj
+  info->object->StoreObject(*this);
+
+  // Prepare and write the sub-entry about the child obj.
+  WriteObjectDef(*info);
+
+  node = info->children.First();
+  
+  while (node) {
+    ProcessObjectDef((wxObjectStreamInfo *)node->Data());
+    node = node->Next();
+  }
+}
+
+void wxObjectOutputStream::ProcessObjectData(wxObjectStreamInfo *info)
+{
+  wxNode *node = info->children.First();
+
+  m_current_info = info;
+
+  info->object->StoreObject(*this);
+
+  while (node) {
+    ProcessObjectData((wxObjectStreamInfo *)node->Data());
+    node = node->Next();
+  }
+}
+
+bool wxObjectOutputStream::SaveObject(wxObject& obj)
+{
+  wxObjectStreamInfo info;
+
+  if (m_saving)
+    return FALSE;
+
+  m_saving = TRUE;
+
+  // First stage
+  m_stage = 0;
+  info.object = &obj;
+  info.n_children = 0;
+  ProcessObjectDef(&info);
+
+  m_stage = 1;
+  ProcessObjectData(&info);
+
+  info.children.Clear();
+
+  m_saving = FALSE;
+
+  return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// wxObjectInputStream
+// ----------------------------------------------------------------------------
+
+wxObjectInputStream::wxObjectInputStream(wxInputStream& s)
+  : wxFilterInputStream(s)
+{
+}
+
+wxObject *wxObjectInputStream::SolveName(const wxString& name) const
+{
+  wxNode *node = m_solver.First();
+  wxObjectStreamInfo *info;
+
+  while (node) {
+    info = (wxObjectStreamInfo *)node->Data();
+    if (info->object_name == name)
+      return info->object;
+
+    node = node->Next();
+  }
+  return NULL;
+}
+
+wxObject *wxObjectInputStream::GetChild(int no) const
+{
+  return m_current_info->children.Nth(no);
+}
+
+bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo *info)
+{
+  wxDataInputStream data_s(*this);
+  char sig[WXOBJ_BEG_LEN+1];
+
+  Read(sig, WXOBJ_BEG_LEN);
+  sig[WXOBJ_BEG_LEN] = 0;
+  if (wxString(sig) != WXOBJ_BEGIN)
+    return FALSE;
+  info->object = wxCreateDynamicObject((char *)data_s.ReadString());
+  info->object_name = data_s.ReadString();
+  info->n_children = data_s.Read8();
+  info->children = wxList();
+
+  return TRUE;
+}
+
+wxObjectStreamInfo *wxObjectInputStream::ProcessObjectDef(wxObjectStreamInfo *parent)
+{
+  wxObjectStreamInfo *info, *c_info;
+  int c;
+
+  info = new wxObjectStreamInfo;
+  info->parent = parent;
+  info->children.DeleteContents(TRUE);
+
+  m_solver.Append(info);
+
+  if (!ReadObjectDef(info))
+    return NULL;
+
+  for (c=0;c<info->n_children;c++) {
+    c_info = ProcessObjectDef(info);
+    if (!c_info)
+      return NULL;
+    info->children.Append(c_info);
+  }
+
+  return info;
+}
+
+void wxObjectInputStream::ProcessObjectData(wxObjectStreamInfo *info)
+{
+  wxNode *node = info->children.First();
+  wxObjectStreamInfo *c_info;
+
+  m_current_info = info;
+
+  info->object->LoadObject(*this);
+  while (node) {
+    c_info = (wxObjectStreamInfo *)node->Data();
+    c_info->object->LoadObject(*this);
+    node = node->Next();
+  }
+}
+
+wxObject *wxObjectInputStream::LoadObject()
+{
+  wxObjectStreamInfo *info;
+  wxObject *object;
+
+  info = ProcessObjectDef(NULL);
+  if (!info)
+    return NULL;
+  ProcessObjectData(info);
+
+  object = info->object;
+
+  delete info; // It's magic ! The whole tree is destroyed.
+
+  return object;
+}
index b3a43423a7fc73045127b45aad6a4fee434c07f0..0186a9548cedb860e9608e1112d2cf7b1aaa26e6 100644 (file)
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
+#include <ctype.h>
 #include <wx/stream.h>
 #include <wx/stream.h>
+#include <wx/datstrm.h>
 
 #ifdef __BORLANDC__
 #pragma hdrstop
 #endif
 
 
 #ifdef __BORLANDC__
 #pragma hdrstop
 #endif
 
+// ----------------------------------------------------------------------------
+// wxStreamBuffer
+// ----------------------------------------------------------------------------
+
+wxStreamBuffer::wxStreamBuffer(wxInputStream& i_stream)
+  : m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
+    m_buffer_size(0), m_istream(&i_stream), m_ostream(NULL)
+{
+}
+
+wxStreamBuffer::wxStreamBuffer(wxOutputStream& o_stream)
+  : m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
+    m_buffer_size(0), m_istream(NULL), m_ostream(&o_stream)
+{
+}
+
+wxStreamBuffer::~wxStreamBuffer()
+{
+}
+
+void wxStreamBuffer::WriteBack(char c)
+{
+  if (m_ostream)
+    return;
+
+  // Assume that if we write "back" we have read a few bytes: so we have some
+  // space.
+
+  m_buffer_pos--;
+  *m_buffer_pos = c;
+}
+
+void wxStreamBuffer::SetBufferIO(char *buffer_start, char *buffer_end)
+{
+  m_buffer_pos  = m_buffer_start = buffer_start;
+  m_buffer_end  = buffer_end;
+
+  m_buffer_size = m_buffer_end-m_buffer_start;
+}
+
+void wxStreamBuffer::SetBufferIO(size_t bufsize)
+{
+  if (m_buffer_start)
+    delete[] m_buffer_start;
+
+  if (!bufsize) {
+    m_buffer_start = NULL;
+    m_buffer_end = NULL;
+    m_buffer_pos = NULL;
+    m_buffer_size = 0;
+  }
+
+  m_buffer_start = new char[bufsize];
+  m_buffer_end   = m_buffer_start + bufsize;
+  if (m_istream)
+    m_buffer_pos = m_buffer_end;
+  else
+    m_buffer_pos = m_buffer_start;
+  m_buffer_size  = bufsize;
+}
+
+void wxStreamBuffer::ResetBuffer()
+{
+  if (m_istream)
+    m_buffer_pos = m_buffer_end;
+  else
+    m_buffer_pos = m_buffer_start;
+}
+
+void wxStreamBuffer::Read(void *buffer, size_t size)
+{
+  wxASSERT(m_istream != NULL);
+
+  // ------------------
+  // Buffering disabled
+  // ------------------
+
+  if (!m_buffer_size) {
+    m_istream->m_lastread = m_istream->DoRead(buffer, size);
+    return;
+  }
+
+  // -----------------
+  // Buffering enabled
+  // -----------------
+  size_t buf_left, orig_size = size;
+  size_t read_ret;
+
+  while (size > 0) {
+    buf_left = m_buffer_end - m_buffer_pos; 
+
+    // First case: the requested buffer is larger than the stream buffer,
+    //             we split
+    if (size > buf_left) {
+      memcpy(buffer, m_buffer_pos, buf_left);
+      size -= buf_left;
+      buffer = (char *)buffer + buf_left; // ANSI C++ violation.
+
+      read_ret = m_istream->DoRead(m_buffer_start, m_buffer_size);
+
+      // Read failed
+      if (read_ret == 0) {
+        m_istream->m_lastread = orig_size-size;
+        m_buffer_pos = m_buffer_end = m_buffer_start;
+        return;
+      } else {
+        m_buffer_end = m_buffer_start+read_ret;
+        m_buffer_pos = m_buffer_start;
+      }
+    } else {
+
+      // Second case: we just copy from the stream buffer.
+      memcpy(buffer, m_buffer_pos, size);
+      m_buffer_pos += size;
+      break;
+    }
+  }
+  m_istream->m_lastread = orig_size;
+}
+
+void wxStreamBuffer::Write(const void *buffer, size_t size)
+{
+  wxASSERT(m_ostream != NULL);
+
+  // ------------------
+  // Buffering disabled
+  // ------------------
+
+  if (!m_buffer_size) {
+    m_ostream->m_lastwrite = m_ostream->DoWrite(buffer, size);
+    return;
+  }
+
+  // ------------------
+  // Buffering enabled
+  // ------------------
+
+  size_t buf_left, orig_size = size;
+  size_t write_ret;
+
+  while (size > 0) {
+    buf_left = m_buffer_end - m_buffer_pos;
+
+    // First case: the buffer to write is larger than the stream buffer,
+    //             we split it
+    if (size > buf_left) {
+      memcpy(m_buffer_pos, buffer, buf_left);
+      size -= buf_left;
+      buffer = (char *)buffer + buf_left; // ANSI C++ violation.
+
+      write_ret = m_ostream->DoWrite(m_buffer_start, m_buffer_size);
+      if (write_ret != m_buffer_size) {
+        m_ostream->m_bad = TRUE;
+        m_ostream->m_lastwrite = orig_size-size;
+        m_buffer_pos = m_buffer_end = m_buffer_start;
+        return;
+      }
+      m_buffer_pos = m_buffer_start;
+
+    } else {
+
+      // Second case: just copy it in the stream buffer.
+
+      memcpy(m_buffer_pos, buffer, size);
+      m_buffer_pos += size;
+      break;
+    }
+  }
+  m_ostream->m_lastwrite = orig_size;
+}
+
 // ----------------------------------------------------------------------------
 // wxInputStream
 // ----------------------------------------------------------------------------
 
 wxInputStream::wxInputStream()
 {
 // ----------------------------------------------------------------------------
 // wxInputStream
 // ----------------------------------------------------------------------------
 
 wxInputStream::wxInputStream()
 {
+  m_i_destroybuf = TRUE;
+  m_i_streambuf = new wxStreamBuffer(*this);
+}
+
+wxInputStream::wxInputStream(wxStreamBuffer *buffer)
+{
+  m_i_destroybuf = FALSE;
+  m_i_streambuf = buffer;
 }
 
 wxInputStream::~wxInputStream()
 {
 }
 
 wxInputStream::~wxInputStream()
 {
+  if (m_i_destroybuf)
+    delete m_i_streambuf;
+}
+
+char wxInputStream::GetC()
+{
+  char c;
+  m_i_streambuf->Read(&c, 1);
+  return c;
+}
+
+wxInputStream& wxInputStream::Read(void *buffer, size_t size)
+{
+  m_i_streambuf->Read(buffer, size);
+  // wxStreamBuffer sets all variables for us
+  return *this;
 }
 
 #define BUF_TEMP_SIZE 10000
 }
 
 #define BUF_TEMP_SIZE 10000
@@ -48,14 +245,6 @@ wxInputStream& wxInputStream::Read(wxOutputStream& stream_out)
   return *this;
 }
 
   return *this;
 }
 
-int wxInputStream::Scanf(const wxString& format, ...)
-{
-  va_list params;
-
-  va_start(params, format);
-  va_end(params);
-}
-
 wxInputStream& wxInputStream::operator>>(wxString& line)
 {
   wxDataInputStream s(*this);
 wxInputStream& wxInputStream::operator>>(wxString& line)
 {
   wxDataInputStream s(*this);
@@ -67,65 +256,320 @@ wxInputStream& wxInputStream::operator>>(wxString& line)
 wxInputStream& wxInputStream::operator>>(char& c)
 {
   c = GetC();
 wxInputStream& wxInputStream::operator>>(char& c)
 {
   c = GetC();
+  return *this;
 }
 
 wxInputStream& wxInputStream::operator>>(short& i)
 {
 }
 
 wxInputStream& wxInputStream::operator>>(short& i)
 {
-  Scanf("%i", &i);
+  long l;
+
+  *this >> l;
+  i = (short)l;
   return *this;
 }
 
 wxInputStream& wxInputStream::operator>>(long& i)
 {
   return *this;
 }
 
 wxInputStream& wxInputStream::operator>>(long& i)
 {
-  Scanf("%l", &i);
+  /* I only implemented a simple integer parser */
+  int c, sign;
+
+  while (isspace( c = GetC() ) )
+     /* Do nothing */ ;
+
+  i = 0;
+  if (! (c == '-' || isdigit(c)) ) {
+    InputStreamBuffer()->WriteBack(c);
+    return *this;
+  }
+
+  if (c == '-') {
+    sign = -1;
+    c = GetC();
+  } else
+    sign = 1;
+
+  while (isdigit(c)) {
+    i = i*10 + c;
+    c = GetC();
+  }
+
+  i *= sign;
+
   return *this;
 }
 
 wxInputStream& wxInputStream::operator>>(float& f)
 {
   return *this;
 }
 
 wxInputStream& wxInputStream::operator>>(float& f)
 {
-  Scanf("%f", &f);
+  /* I only implemented a simple float parser */
+  int c, sign;
+
+  while (isspace( c = GetC() ) )
+     /* Do nothing */ ;
+
+  f = 0.0;
+  if (! (c == '-' || isdigit(c)) ) {
+    InputStreamBuffer()->WriteBack(c);
+    return *this;
+  }
+
+  if (c == '-') {
+    sign = -1;
+    c = GetC();
+  } else
+    sign = 1;
+
+  while (isdigit(c)) {
+    f = f*10 + c;
+    c = GetC();
+  }
+
+  if (c == '.') {
+    float f_multiplicator = 0.1;
+    c = GetC();
+
+    while (isdigit(c)) {
+      f += c*f_multiplicator;
+      f_multiplicator /= 10;
+      c = GetC();
+    }
+  }
+
+  f *= sign;
+
   return *this;
 }
 
   return *this;
 }
 
+off_t wxInputStream::SeekI(off_t pos, wxSeekMode mode)
+{
+  off_t ret_off;
+
+  switch (mode) {
+  case wxFromStart:
+    if ( (unsigned)abs (DoTellInput()-pos) > m_i_streambuf->GetLastAccess()  ) {
+      ret_off = DoSeekInput(pos, wxFromStart);
+      m_i_streambuf->ResetBuffer();
+      return ret_off;
+    } else {
+      m_i_streambuf->SetIntPosition(DoTellInput() - pos);
+      return pos;
+    }
+  case wxFromCurrent:
+    if ( ((unsigned)pos > m_i_streambuf->GetLastAccess()) || (pos < 0) ) {
+      ret_off = DoSeekInput(pos, wxFromCurrent);
+      m_i_streambuf->ResetBuffer();
+      return ret_off;
+    } else {
+      m_i_streambuf->SetIntPosition(pos);
+      return pos;
+    }
+  case wxFromEnd:
+    // Hard to compute: always seek to the requested position.
+    ret_off = DoSeekInput(pos, wxFromEnd);
+    m_i_streambuf->ResetBuffer();
+    return ret_off;
+  }
+  return wxInvalidOffset;
+}
+
+off_t wxInputStream::TellI() const
+{
+  return DoTellInput() - m_i_streambuf->GetLastAccess() +
+                         m_i_streambuf->GetIntPosition();
+}
+
 // ----------------------------------------------------------------------------
 // wxOutputStream
 // ----------------------------------------------------------------------------
 wxOutputStream::wxOutputStream()
 {
 // ----------------------------------------------------------------------------
 // wxOutputStream
 // ----------------------------------------------------------------------------
 wxOutputStream::wxOutputStream()
 {
+  m_o_destroybuf = TRUE;
+  m_o_streambuf = new wxStreamBuffer(*this);
+}
+
+wxOutputStream::wxOutputStream(wxStreamBuffer *buffer)
+{
+  m_o_destroybuf = FALSE;
+  m_o_streambuf = buffer;
 }
 
 wxOutputStream::~wxOutputStream()
 {
 }
 
 wxOutputStream::~wxOutputStream()
 {
+  if (m_o_destroybuf)
+    delete m_o_streambuf;
+}
+
+wxOutputStream& wxOutputStream::Write(const void *buffer, size_t size)
+{
+  m_o_streambuf->Write(buffer, size);
+  return *this;
 }
 
 wxOutputStream& wxOutputStream::Write(wxInputStream& stream_in)
 {
 }
 
 wxOutputStream& wxOutputStream::Write(wxInputStream& stream_in)
 {
-   stream_in.Read(*this);
-   return *this;
+  stream_in.Read(*this);
+  return *this;
+}
+
+off_t wxOutputStream::SeekO(off_t pos, wxSeekMode mode)
+{
+  off_t ret_off;
+
+  switch (mode) {
+  case wxFromStart:
+    if ( (unsigned)abs (DoTellOutput()-pos) > m_o_streambuf->GetLastAccess()  ) {
+      ret_off = DoSeekOutput(pos, wxFromStart);
+      m_o_streambuf->ResetBuffer();
+      return ret_off;
+    } else {
+      m_o_streambuf->SetIntPosition( DoTellOutput() - pos);
+      return pos;
+    }
+  case wxFromCurrent:
+    if ( ((unsigned)pos > m_o_streambuf->GetLastAccess()) || (pos < 0) ) {
+      ret_off = DoSeekOutput(pos, wxFromCurrent);
+      m_o_streambuf->ResetBuffer();
+      return ret_off;
+    } else {
+      m_o_streambuf->SetIntPosition(pos);
+      return pos;
+    }
+  case wxFromEnd:
+    // Hard to compute: always seek to the requested position.
+    ret_off = DoSeekOutput(pos, wxFromEnd);
+    m_o_streambuf->ResetBuffer();
+    return ret_off;
+  }
+  return wxInvalidOffset;
+}
+
+off_t wxOutputStream::TellO() const
+{
+  return DoTellOutput() - m_o_streambuf->GetLastAccess()
+                        + m_o_streambuf->GetIntPosition();
+}
+
+void wxOutputStream::Sync()
+{
+  DoWrite(m_o_streambuf->GetBufferStart(), m_o_streambuf->GetIntPosition());
+
+  m_o_streambuf->ResetBuffer();
+}
+
+wxOutputStream& wxOutputStream::operator<<(const char *string)
+{
+  return Write(string, strlen(string));
+}
+
+wxOutputStream& wxOutputStream::operator<<(wxString& string)
+{
+  return Write(string, string.Len());
+}
+
+wxOutputStream& wxOutputStream::operator<<(char c)
+{
+  return Write(&c, 1);
+}
+
+wxOutputStream& wxOutputStream::operator<<(short i)
+{
+  wxString strint;
+
+  strint.Printf("%i", i);
+  return Write(strint, strint.Len());
+}
+
+wxOutputStream& wxOutputStream::operator<<(int i)
+{
+  wxString strint;
+
+  strint.Printf("%i", i);
+  return Write(strint, strint.Len());
+}
+
+wxOutputStream& wxOutputStream::operator<<(long i)
+{
+  wxString strlong;
+
+  strlong.Printf("%i", i);
+  return Write((const char *)strlong, strlong.Len());
+}
+
+wxOutputStream& wxOutputStream::operator<<(double f)
+{
+  wxString strfloat;
+
+  strfloat.Printf("%f", f);
+  return Write(strfloat, strfloat.Len());
 }
 
 // ----------------------------------------------------------------------------
 // wxFilterInputStream
 // ----------------------------------------------------------------------------
 wxFilterInputStream::wxFilterInputStream(wxInputStream& stream)
 }
 
 // ----------------------------------------------------------------------------
 // wxFilterInputStream
 // ----------------------------------------------------------------------------
 wxFilterInputStream::wxFilterInputStream(wxInputStream& stream)
-  : wxInputStream()
+  : wxInputStream(NULL)
 {
   m_parent_i_stream = &stream;
 {
   m_parent_i_stream = &stream;
+  m_i_streambuf = stream.InputStreamBuffer();
 }
 
 wxFilterInputStream::~wxFilterInputStream()
 {
 }
 
 }
 
 wxFilterInputStream::~wxFilterInputStream()
 {
 }
 
+size_t wxFilterInputStream::DoRead(void *buffer, size_t size)
+{
+  return m_parent_i_stream->Read(buffer, size).LastRead();
+}
+
+off_t wxFilterInputStream::DoSeekInput(off_t pos, wxSeekMode mode)
+{
+  return m_parent_i_stream->SeekI(pos, mode);
+}
+
+off_t wxFilterInputStream::DoTellInput() const
+{
+  return m_parent_i_stream->TellI();
+}
+
+
 // ----------------------------------------------------------------------------
 // wxFilterOutputStream
 // ----------------------------------------------------------------------------
 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream)
 // ----------------------------------------------------------------------------
 // wxFilterOutputStream
 // ----------------------------------------------------------------------------
 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream)
-  : wxOutputStream()
+  : wxOutputStream(NULL)
 {
   m_parent_o_stream = &stream;
 {
   m_parent_o_stream = &stream;
+  m_o_streambuf = stream.OutputStreamBuffer();
 }
 
 wxFilterOutputStream::~wxFilterOutputStream()
 {
 }
 }
 
 wxFilterOutputStream::~wxFilterOutputStream()
 {
 }
+
+size_t wxFilterOutputStream::DoWrite(const void *buffer, size_t size)
+{
+  return m_parent_o_stream->Write(buffer, size).LastWrite();
+}
+
+off_t wxFilterOutputStream::DoSeekOutput(off_t pos, wxSeekMode mode)
+{
+  return m_parent_o_stream->SeekO(pos, mode);
+}
+
+off_t wxFilterOutputStream::DoTellOutput() const
+{
+  return m_parent_o_stream->TellO();
+}
+
+// ----------------------------------------------------------------------------
+// Some IOManip function
+// ----------------------------------------------------------------------------
+
+wxOutputStream& wxEndL(wxOutputStream& stream)
+{
+#ifdef __MSW__
+  return stream.Write("\r\n", 2);
+#else
+  return stream.Write("\n", 1);
+#endif
+}
index 2db13338a34b581cfc433fc57ab5ae38590b6ad8..ea64071eb7e5018c149d1cdc252a79e468b8e31a 100644 (file)
 #include <wx/stream.h>
 #include <wx/zstream.h>
 #include <wx/utils.h>
 #include <wx/stream.h>
 #include <wx/zstream.h>
 #include <wx/utils.h>
+#include "zlib.h"
 
 #ifdef __BORLANDC__
 #pragma hdrstop
 #endif
 
 
 #ifdef __BORLANDC__
 #pragma hdrstop
 #endif
 
+#define ZSTREAM_BUFFER_SIZE 1024
+
 //////////////////////
 // wxZlibInputStream
 //////////////////////
 //////////////////////
 // wxZlibInputStream
 //////////////////////
@@ -31,6 +34,10 @@ wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
 {
   int err;
 
 {
   int err;
 
+  // I need a private stream buffer.
+  m_i_streambuf = new wxStreamBuffer(*this);
+  m_i_destroybuf = TRUE;
+
   m_inflate.zalloc = (alloc_func)0;
   m_inflate.zfree = (free_func)0;
   m_inflate.opaque = (voidpf)0;
   m_inflate.zalloc = (alloc_func)0;
   m_inflate.zfree = (free_func)0;
   m_inflate.opaque = (voidpf)0;
@@ -41,7 +48,11 @@ wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
     return;
   }
 
     return;
   }
 
+  m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
+  m_z_size = ZSTREAM_BUFFER_SIZE;
+
   m_inflate.avail_in = 0;
   m_inflate.avail_in = 0;
+  m_inflate.next_in = NULL;
 }
 
 wxZlibInputStream::~wxZlibInputStream()
 }
 
 wxZlibInputStream::~wxZlibInputStream()
@@ -49,50 +60,35 @@ wxZlibInputStream::~wxZlibInputStream()
   inflateEnd(&m_inflate);
 }
 
   inflateEnd(&m_inflate);
 }
 
-wxInputStream& wxZlibInputStream::Read(void *buffer, size_t size)
+size_t wxZlibInputStream::DoRead(void *buffer, size_t size)
 {
   int err;
 
   m_inflate.next_out = (unsigned char *)buffer;
   m_inflate.avail_out = size;
 {
   int err;
 
   m_inflate.next_out = (unsigned char *)buffer;
   m_inflate.avail_out = size;
-  m_eof = FALSE;
 
   while (m_inflate.avail_out > 0) {
     if (m_inflate.avail_in == 0) {
 
   while (m_inflate.avail_out > 0) {
     if (m_inflate.avail_in == 0) {
-      wxFilterInputStream::Read(m_z_buffer, m_z_size);
+
+      m_parent_i_stream->Read(m_z_buffer, m_z_size);
       m_inflate.next_in = m_z_buffer;
       m_inflate.next_in = m_z_buffer;
-      m_inflate.avail_in = wxFilterInputStream::LastRead();
-      if (wxFilterInputStream::Eof()) {
-        m_lastread = size - m_inflate.avail_out;
-        return *this;
-      }
+      m_inflate.avail_in = m_parent_i_stream->LastRead();
+
+      if (m_parent_i_stream->Eof())
+        return (size - m_inflate.avail_in);
     }
     err = inflate(&m_inflate, Z_FINISH);
     }
     err = inflate(&m_inflate, Z_FINISH);
-    if (err == Z_STREAM_END) {
-      m_lastread = size - m_inflate.avail_out;
-      m_eof = TRUE;
-      return *this;
-    }
+    if (err == Z_STREAM_END)
+      return (size - m_inflate.avail_in);
   }
 
   }
 
-  m_lastread = size;
-  return *this;
-}
-
-off_t wxZlibInputStream::SeekI(off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode))
-{
-  return 0;
-}
-
-off_t wxZlibInputStream::TellI() const
-{
-  return 0;
+  return size-m_inflate.avail_in;
 }
 
 bool wxZlibInputStream::Eof() const
 {
   if (!m_eof)
 }
 
 bool wxZlibInputStream::Eof() const
 {
   if (!m_eof)
-    return wxFilterInputStream::Eof();
+    return m_parent_i_stream->Eof();
   return m_eof;
 }
 
   return m_eof;
 }
 
@@ -105,6 +101,9 @@ wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
 {
   int err;
 
 {
   int err;
 
+  m_o_streambuf = new wxStreamBuffer(*this);
+  m_o_destroybuf = TRUE;
+
   m_deflate.zalloc = (alloc_func)0;
   m_deflate.zfree = (free_func)0;
   m_deflate.opaque = (voidpf)0;
   m_deflate.zalloc = (alloc_func)0;
   m_deflate.zfree = (free_func)0;
   m_deflate.opaque = (voidpf)0;
@@ -114,6 +113,10 @@ wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
     deflateEnd(&m_deflate);
     return;
   }
     deflateEnd(&m_deflate);
     return;
   }
+
+  m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
+  m_z_size = ZSTREAM_BUFFER_SIZE;
+
   m_deflate.avail_in = 0;
   m_deflate.next_out = m_z_buffer;
   m_deflate.avail_out = m_z_size;
   m_deflate.avail_in = 0;
   m_deflate.next_out = m_z_buffer;
   m_deflate.avail_out = m_z_size;
@@ -123,72 +126,67 @@ wxZlibOutputStream::~wxZlibOutputStream()
 {
   int err;
 
 {
   int err;
 
-  while (1) {
-    err = deflate(&m_deflate, Z_FINISH);
-    if (err == Z_STREAM_END)
-      break;
-    if (err < 0) {
-      wxDebugMsg("wxZlibOutputStream: error during final deflate");
-      break;
-    }
-    if (m_deflate.avail_out == 0) {
-      wxFilterOutputStream::Write(m_z_buffer, m_z_size);
-      if (wxFilterOutputStream::Bad()) {
-        wxDebugMsg("wxZlibOutputStream: error during final write");
-        break;
-      }
-      m_deflate.next_out = m_z_buffer;
-      m_deflate.avail_out = m_z_size;
-    }
+  Sync();
+
+  err = deflate(&m_deflate, Z_FINISH);
+  if (err != Z_STREAM_END) {
+    wxDebugMsg("wxZlibOutputStream: an error occured while we was closing "
+               "the stream.\n");
+    return;
   }
   }
-  wxFilterOutputStream::Write(m_z_buffer, m_z_size-m_deflate.avail_out);
 
   deflateEnd(&m_deflate);
 
   deflateEnd(&m_deflate);
+
+  delete[] m_z_buffer;
 }
 
 }
 
-wxOutputStream& wxZlibOutputStream::Write(const void *buffer, size_t size)
+void wxZlibOutputStream::Sync()
+{
+  int err;
+
+  m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate.avail_out);
+  m_deflate.next_out  = m_z_buffer;
+  m_deflate.avail_out = m_z_size;
+
+  err = deflate(&m_deflate, Z_FULL_FLUSH);
+  if (err != Z_OK) {
+    m_bad = TRUE;
+    return;
+  }
+
+  m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate.avail_out);
+  m_deflate.next_out  = m_z_buffer;
+  m_deflate.avail_out = m_z_size;
+}
+
+size_t wxZlibOutputStream::DoWrite(const void *buffer, size_t size)
 {
   int err;
 
   m_deflate.next_in = (unsigned char *)buffer;
   m_deflate.avail_in = size;
 
 {
   int err;
 
   m_deflate.next_in = (unsigned char *)buffer;
   m_deflate.avail_in = size;
 
-  m_bad = FALSE;
   while (m_deflate.avail_in > 0) {
   while (m_deflate.avail_in > 0) {
+
     if (m_deflate.avail_out == 0) {
     if (m_deflate.avail_out == 0) {
-      wxFilterOutputStream::Write(m_z_buffer, m_z_size);
-      if (wxFilterOutputStream::Bad()) {
-        m_lastwrite = size - m_deflate.avail_in;
-        return *this;
-      }
-            
+      m_parent_o_stream->Write(m_z_buffer, m_z_size);
+      if (m_parent_o_stream->Bad())
+        return (size - m_deflate.avail_in);
+
       m_deflate.next_out = m_z_buffer;
       m_deflate.avail_out = m_z_size;
     }
       m_deflate.next_out = m_z_buffer;
       m_deflate.avail_out = m_z_size;
     }
+
     err = deflate(&m_deflate, Z_NO_FLUSH);
     err = deflate(&m_deflate, Z_NO_FLUSH);
-    if (err < 0) {
-      m_bad = TRUE;
-      m_lastwrite = size - m_deflate.avail_in;
-      return *this;
-    }
+    if (err != Z_OK)
+      return (size - m_deflate.avail_in);
   }
   }
-  m_lastwrite = size;
-  return *this;
-}
-
-off_t wxZlibOutputStream::SeekO(off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode))
-{
-  return 0;
-}
-
-off_t wxZlibOutputStream::TellO() const
-{
-  return 0;
+  return size;
 }
 
 bool wxZlibOutputStream::Bad() const
 {
   if (!m_bad)
 }
 
 bool wxZlibOutputStream::Bad() const
 {
   if (!m_bad)
-    return wxFilterOutputStream::Bad();
+    return m_parent_o_stream->Bad();
   return m_bad;
 }
   return m_bad;
 }