- Added wxStreamBuffer::Truncate() (Stas Sergeev)
- Allow using wxEventLoop in console applications (Lukasz Michalski)
- Added functions for Base64 en/decoding (Charles Reimers)
+- Added support for binary data to wxConfig (Charles Reimers)
- Added functions for atomically inc/decrementing integers (Armel Asselin)
- wxLogInterposer has been added to replace wxLogPassThrough and new
wxLogInterposerTemp was added
Reads a bool value, returning \true if the value was found. If the value was
not found, {\it defaultVal} is used instead.
+\constfunc{bool}{Read}{\param{const wxString\& }{ key}, \param{wxMemoryBuffer*}{ buf}}
+
+Reads a binary block, returning \true if the value was found. If the value was
+not found, {\it buf} is not changed.
+
\pythonnote{In place of a single overloaded method name, wxPython
implements the following methods:\par
\indented{2cm}{\begin{twocollist}
\func{bool}{Write}{\param{const wxString\& }{ key}, \param{bool}{ value}}
+\func{bool}{Write}{\param{const wxString\& }{ key}, \param{const wxMemoryBuffer\&}{ buf}}
+
These functions write the specified value to the config file and return \true on success.
\pythonnote{In place of a single overloaded method name, wxPython
#include "wx/defs.h"
#include "wx/string.h"
#include "wx/object.h"
+#include "wx/base64.h"
class WXDLLIMPEXP_FWD_BASE wxArrayString;
bool Read(const wxString& key, bool* val) const;
bool Read(const wxString& key, bool* val, bool defVal) const;
+ // read a binary data block
+ bool Read(const wxString& key, wxMemoryBuffer* data) const
+ { return DoReadBinary(key, data); }
+ // no default version since it does not make sense for binary data
+
// convenience functions returning directly the value (we don't have them for
// int/double/bool as there would be ambiguities with the long one then)
wxString Read(const wxString& key,
bool Write(const wxString& key, bool value)
{ return DoWriteBool(key, value); }
+ bool Write(const wxString& key, const wxMemoryBuffer& buf)
+ { return DoWriteBinary(key, buf); }
+
// we have to provide a separate version for C strings as otherwise they
// would be converted to bool and not to wxString as expected!
bool Write(const wxString& key, const char *value)
virtual bool DoReadInt(const wxString& key, int *pi) const;
virtual bool DoReadDouble(const wxString& key, double* val) const;
virtual bool DoReadBool(const wxString& key, bool* val) const;
+ virtual bool DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const = 0;
virtual bool DoWriteString(const wxString& key, const wxString& value) = 0;
virtual bool DoWriteLong(const wxString& key, long value) = 0;
virtual bool DoWriteInt(const wxString& key, int value);
virtual bool DoWriteDouble(const wxString& key, double value);
virtual bool DoWriteBool(const wxString& key, bool value);
+ virtual bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf) = 0;
private:
// are we doing automatic environment variable expansion?
protected:
virtual bool DoReadString(const wxString& key, wxString *pStr) const;
virtual bool DoReadLong(const wxString& key, long *pl) const;
+ virtual bool DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const;
virtual bool DoWriteString(const wxString& key, const wxString& szValue);
virtual bool DoWriteLong(const wxString& key, long lValue);
+ virtual bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf);
private:
// GetXXXFileName helpers: return ('/' terminated) directory names
// read/write
bool DoReadString(const wxString& key, wxString *pStr) const;
bool DoReadLong(const wxString& key, long *plResult) const;
+ bool DoReadBinary(const wxString& key, wxMemoryBuffer *buf) const;
bool DoWriteString(const wxString& key, const wxString& szValue);
bool DoWriteLong(const wxString& key, long lValue);
+ bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf);
private:
// helpers
#include "wx/object.h"
#include "wx/confbase.h"
+#include "buffer.h"
// ----------------------------------------------------------------------------
// wxRegConfig
// implement read/write methods
virtual bool DoReadString(const wxString& key, wxString *pStr) const;
virtual bool DoReadLong(const wxString& key, long *plResult) const;
+ virtual bool DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const;
virtual bool DoWriteString(const wxString& key, const wxString& szValue);
virtual bool DoWriteLong(const wxString& key, long lValue);
+ virtual bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf);
private:
// these keys are opened during all lifetime of wxRegConfig object
// implement read/write methods
virtual bool DoReadString(const wxString& key, wxString *pStr) const;
virtual bool DoReadLong(const wxString& key, long *plResult) const;
+ virtual bool DoReadBinary(const wxString& key, wxMemoryBuffer *buf) const;
virtual bool DoWriteString(const wxString& key, const wxString& szValue);
virtual bool DoWriteLong(const wxString& key, long lValue);
+ virtual bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf);
private:
// current path (not '/' terminated)
#include "wx/fileconf.h"
#include "wx/filefn.h"
+#include "wx/base64.h"
+
#include "wx/stdpaths.h"
#if defined(__WXMAC__)
return str.ToLong(pl);
}
+bool wxFileConfig::DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const
+{
+ wxCHECK_MSG( buf, false, _T("NULL buffer") );
+
+ wxString str;
+ if ( !Read(key, &str) )
+ return false;
+
+ *buf = wxBase64Decode(str);
+ return true;
+}
+
bool wxFileConfig::DoWriteString(const wxString& key, const wxString& szValue)
{
wxConfigPathChanger path(this, key);
return Write(key, wxString::Format(_T("%ld"), lValue));
}
+bool wxFileConfig::DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf)
+{
+ return Write(key, wxBase64Encode(buf));
+}
+
bool wxFileConfig::Flush(bool /* bCurrentOnly */)
{
if ( !IsDirty() || !m_fnLocalFile.GetFullPath() )
return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, plVal);
}
+bool TryGetValue(const wxRegKey& key, const wxString& str, wxMemoryBuffer &plVal)
+{
+ return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, plVal);
+}
+
// ============================================================================
// implementation
// ============================================================================
return false;
}
+bool wxRegConfig::DoReadBinary(const wxString& key, wxMemoryBuffer *buf) const
+{
+ wxCHECK_MSG( buf, false, _T("wxRegConfig::Read(): NULL param") );
+
+ wxConfigPathChanger path(this, key);
+
+ bool bQueryGlobal = true;
+
+ // if immutable key exists in global key we must check that it's not
+ // overriden by the local key with the same name
+ if ( IsImmutable(path.Name()) ) {
+ if ( TryGetValue(m_keyGlobal, path.Name(), *buf) ) {
+ if ( m_keyLocal.Exists() && LocalKey().HasValue(path.Name()) ) {
+ wxLogWarning(wxT("User value for immutable key '%s' ignored."),
+ path.Name().c_str());
+ }
+
+ return true;
+ }
+ else {
+ // don't waste time - it's not there anyhow
+ bQueryGlobal = false;
+ }
+ }
+
+ // first try local key
+ if ( (m_keyLocal.Exists() && TryGetValue(LocalKey(), path.Name(), *buf)) ||
+ (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), *buf)) ) {
+ return true;
+ }
+
+ return false;
+}
+
bool wxRegConfig::DoWriteString(const wxString& key, const wxString& szValue)
{
wxConfigPathChanger path(this, key);
return LocalKey().SetValue(path.Name(), lValue);
}
+bool wxRegConfig::DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf)
+{
+ wxConfigPathChanger path(this, key);
+
+ if ( IsImmutable(path.Name()) ) {
+ wxLogError(wxT("Can't change immutable entry '%s'."), path.Name().c_str());
+ return false;
+ }
+
+ return LocalKey().SetValue(path.Name(), buf);
+}
+
// ----------------------------------------------------------------------------
// renaming
// ----------------------------------------------------------------------------
return false;
}
+bool DoReadBinary(const wxString& key, wxMemoryBuffer *buf) const
+{
+ /* TODO */
+ return false;
+}
+
bool wxPrefConfig::DoWriteString(const wxString& key, const wxString& szValue)
{
/* TODO */
return false;
}
+bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf)
+{
+ /* TODO */
+ return false;
+}
+
// ----------------------------------------------------------------------------
// renaming
// ----------------------------------------------------------------------------
CPPUNIT_TEST( GetGroups );
CPPUNIT_TEST( HasEntry );
CPPUNIT_TEST( HasGroup );
+ CPPUNIT_TEST( Binary );
CPPUNIT_TEST( Save );
CPPUNIT_TEST( DeleteEntry );
CPPUNIT_TEST( DeleteGroup );
void GetGroups();
void HasEntry();
void HasGroup();
+ void Binary();
void Save();
void DeleteEntry();
void DeleteGroup();
CPPUNIT_ASSERT( !fc.HasGroup(_T("foot")) );
}
+void FileConfigTestCase::Binary()
+{
+ wxStringInputStream sis(
+ "[root]\n"
+ "binary=Zm9vCg==\n"
+ );
+ wxFileConfig fc(sis);
+
+ wxMemoryBuffer buf;
+ fc.Read("/root/binary", &buf);
+
+ CPPUNIT_ASSERT( memcmp("foo\n", buf.GetData(), buf.GetDataLen()) == 0 );
+
+ buf.SetDataLen(0);
+ buf.AppendData("\0\1\2", 3);
+ fc.Write("/root/012", buf);
+ wxVERIFY_FILECONFIG(
+ "[root]\n"
+ "binary=Zm9vCg==\n"
+ "012=AAEC\n",
+ fc
+ );
+}
+
void FileConfigTestCase::Save()
{
wxStringInputStream sis(testconfig);