From 9b386ecadb0f98fb92cfaad786dcc26915a070bd Mon Sep 17 00:00:00 2001
From: Roger Gammans <rgammans@computer-surgery.co.uk>
Date: Fri, 16 Jul 2004 13:09:52 +0000
Subject: [PATCH]  * add documentation for wxMemoryBuffer  * add suport for
 values of type REG_BINARY in the msw registry.

   Such values are converted to wxMemoryBuffer for internal handling


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28258 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/classes.tex |   1 +
 docs/latex/wx/membuf.tex  | 130 ++++++++++++++++++++++++++++++++++++++
 include/wx/buffer.h       |   2 -
 include/wx/msw/registry.h |   4 ++
 src/msw/registry.cpp      |  68 +++++++++++++++++++-
 5 files changed, 201 insertions(+), 4 deletions(-)
 create mode 100644 docs/latex/wx/membuf.tex

diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index b6de238d8f..79d4a3a5da 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -196,6 +196,7 @@
 \input mbcnvut8.tex
 \input mbcnvutf.tex
 \input mdi.tex
+\input membuf.tex
 \input memorydc.tex
 \input fs_mem.tex
 \input strmmem.tex
diff --git a/docs/latex/wx/membuf.tex b/docs/latex/wx/membuf.tex
new file mode 100644
index 0000000000..4de9ed87cb
--- /dev/null
+++ b/docs/latex/wx/membuf.tex
@@ -0,0 +1,130 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Name:        membuf.tex
+%% Purpose:     wxMemoryBuffer class documentation
+%% Author:      Roger Gammans
+%% Modified by:
+%% Created:     08.06.2004
+%% RCS-ID:      $Id$
+%% Copyright:   (c) Roger Gammans
+%% License:     wxWidgets license
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{\class{wxMemoryBuffer}}\label{wxmemorybuffer}
+
+A {\bf wxMemoryBuffer} is a useful data structure for storing arbitrary sized blocks
+of memory. wxMemoryBuffer guarantees deletion of the memory block when the object
+is destroyed. 
+
+\wxheading{Derived from}
+
+None
+
+\wxheading{Include files}
+
+<wx/buffer.h>
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxMemoryBuffer::wxMemoryBuffer}
+
+\func{}{wxMemoryBuffer}{\param{const wxMemoryBuffer\&}{ src}}
+
+Copy constructor, refcounting is used for performance , but wxMemoryBuffer
+is not a copy-on-write structure so changes made to one buffer effect
+all copies made from it.
+
+\func{}{wxMemoryBuffer}{\param{size\_t}{ size}}
+
+Create a new buffer.
+
+\docparam{size}{size of new buffer.}
+
+\membersection{wxMemoryBuffer::GetData}
+
+\func{void* }{GetData}{\void}
+
+Return a pointer to the data in the buffer.
+
+\membersection{wxMemoryBuffer::GetBufSize}
+
+\func{size\_t}{GetBufSize}{\void}
+
+Returns the size of the buffer.
+
+\membersection{wxMemoryBuffer::GetDataLen}
+
+\func{size\_t}{GetDataLen}{\void}
+
+Returns the length of the valid data in the buffer.
+
+\membersection{wxMemoryBuffer::SetBufSize}
+
+\func{void}{SetBufSize}{\param{size\_t}{ size}}
+
+Ensures the buffer has at least {\it size} bytes available.
+
+\membersection{wxMemoryBuffer::SetDataLen}
+
+\func{void}{SetDataLen}{\param{size\_t}{ size}}
+
+Sets the length of the data stored in the buffer.  Mainly useful for truncating existing data.
+
+\docparam{size}{New length of the valid data in the buffer. This is
+distinct from the allocated size}
+
+\membersection{wxMemoryBuffer::GetWriteBuf}
+
+\func{void *}{GetWriteBuf}{\param{size\_t}{ sizeNeeded}}
+
+Ensure the buffer is big enough and return a pointer to the
+buffer which can be used to directly write into the buffer
+up to {\it sizeNeeded} bytes.
+
+\membersection{wxMemoryBuffer::UngetWriteBuf}
+
+\func{void}{UngetWriteBuf}{\param{size\_t}{ sizeUsed}}
+
+Update the buffer after completing a direct write, which
+you must have used GetWriteBuf() to initialise.
+
+\docparam{sizeUsed}{The amount of data written in to buffer
+by the direct write}
+
+\membersection{wxMemoryBuffer::GetAppendBuf}
+
+\func{void *}{GetAppendBuf}{\param{size\_t}{ sizeNeeded}}
+
+Ensure that the buffer is big enough and return a pointer to the start
+of the empty space in the buffer. This pointer can be used to directly 
+write data into the buffer, this new data will be appended to
+the existing data.
+
+\docparam{sizeNeeded}{Amount of extra space required in the buffer for
+the append operation}
+
+\membersection{wxMemoryBuffer::UngetAppendBuf}
+
+\func{void}{UngetAppendBuf}{\param{size\_t}{ sizeUsed}}
+
+Update the length after completing a direct append, which
+you must have used GetAppendBuf() to initialise.
+
+\docparam{sizeUsed}{This is the amount of new data that has been 
+appended.}
+
+\membersection{wxMemoryBuffer::AppendByte}
+
+\func{void}{AppendByte}{\param{char}{ data}}
+
+Append a single byte to the buffer.
+
+\docparam{data}{New byte to append to the buffer.}
+
+\membersection{wxMemoryBuffer::AppendData}
+
+\func{void}{AppendData}{\param{void*}{ data}, \param{size\_t}{ len}}
+
+Single call to append a data block to the buffer.
+
+\docparam{data}{Pointer to block to append to the buffer.}
+\docparam{len}{Length of data to append.}
diff --git a/include/wx/buffer.h b/include/wx/buffer.h
index 85c986a3e9..1396ef5d26 100644
--- a/include/wx/buffer.h
+++ b/include/wx/buffer.h
@@ -9,8 +9,6 @@
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
-// these classes are for private use only for now, they're not documented
-
 #ifndef _WX_BUFFER_H
 #define _WX_BUFFER_H
 
diff --git a/include/wx/msw/registry.h b/include/wx/msw/registry.h
index 4a8c26ac6f..7798473204 100644
--- a/include/wx/msw/registry.h
+++ b/include/wx/msw/registry.h
@@ -197,6 +197,10 @@ public:
   bool  SetValue(const wxChar *szValue, long lValue);
     // return the numeric value
   bool  QueryValue(const wxChar *szValue, long *plValue) const;
+    // set the binary value
+  bool  SetValue(const wxChar *szValue, const wxMemoryBuffer& buf);
+    // return the binary value
+  bool  QueryValue(const wxChar *szValue, wxMemoryBuffer& buf) const;
 #endif  //Win32
 
   // query existence of a key/value
diff --git a/src/msw/registry.cpp b/src/msw/registry.cpp
index d4526909e6..be83d9d14e 100644
--- a/src/msw/registry.cpp
+++ b/src/msw/registry.cpp
@@ -55,6 +55,7 @@
 
 // some registry functions don't like signed chars
 typedef unsigned char *RegString;
+typedef BYTE* RegBinary;
 
 // ----------------------------------------------------------------------------
 // constants
@@ -491,14 +492,19 @@ bool wxRegKey::CopyValue(const wxChar *szValue,
                        keyDst.SetValue(szValueNew, dwVal);
             }
 
+#ifdef  __WIN32__
+        case Type_Binary:
+	    {
+	        wxMemoryBuffer buf;
+		return QueryValue(szValue,buf) &&
+			keyDst.SetValue(szValueNew,buf);
+	    }
         // these types are unsupported because I am not sure about how
         // exactly they should be copied and because they shouldn't
         // occur among the application keys (supposedly created with
         // this class)
-#ifdef  __WIN32__
         case Type_None:
         case Type_Expand_String:
-        case Type_Binary:
         case Type_Dword_big_endian:
         case Type_Link:
         case Type_Multi_String:
@@ -601,6 +607,9 @@ bool wxRegKey::Copy(wxRegKey& keyDst)
 
         if ( ok )
             bCont = GetNextKey(strKey, lIndex);
+	else
+	    wxLogError(_("Failed to copy the registry subkey '%s' to '%s'."), GetFullName(&key), keyName.mb_str());
+	    
     }
 
     // copy all values
@@ -824,6 +833,61 @@ bool wxRegKey::QueryValue(const wxChar *szValue, long *plValue) const
     return FALSE;
 }
 
+bool wxRegKey::SetValue(const wxChar *szValue,const wxMemoryBuffer& buffer)
+{
+#ifdef __TWIN32__
+  wxFAIL_MSG("RegSetValueEx not implemented by TWIN32");
+  return FALSE;
+#else
+  if ( CONST_CAST Open() ) {
+    m_dwLastError = RegSetValueEx((HKEY) m_hKey, szValue, (DWORD) RESERVED, REG_BINARY,
+                                  (RegBinary)buffer.GetData(),buffer.GetDataLen());
+    if ( m_dwLastError == ERROR_SUCCESS )
+      return TRUE;
+  }
+
+  wxLogSysError(m_dwLastError, _("Can't set value of '%s'"),
+                GetFullName(this, szValue));
+  return FALSE;
+#endif
+}
+
+bool wxRegKey::QueryValue(const wxChar *szValue, wxMemoryBuffer& buffer) const
+{
+  if ( CONST_CAST Open() ) {
+    // first get the type and size of the data
+    DWORD dwType, dwSize;
+    m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
+                                      &dwType, NULL, &dwSize);
+    
+    if ( m_dwLastError == ERROR_SUCCESS ) {
+        if ( dwSize ) {
+            const RegBinary pBuf = (RegBinary)buffer.GetWriteBuf(dwSize);
+            m_dwLastError = RegQueryValueEx((HKEY) m_hKey,
+                                            WXSTRINGCAST szValue,
+                                            RESERVED,
+                                            &dwType,
+                                            pBuf,
+                                            &dwSize);
+            buffer.UngetWriteBuf(dwSize);
+	} else {
+	    buffer.SetDataLen(0);
+        }
+    }
+
+    
+    if ( m_dwLastError != ERROR_SUCCESS ) {
+      wxLogSysError(m_dwLastError, _("Can't read value of key '%s'"),
+                    GetName().c_str());
+      return FALSE;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+
 #endif  //Win32
 
 bool wxRegKey::QueryValue(const wxChar *szValue,
-- 
2.50.0

