1
/////////////////////////////////////////////////////////////////////////////
3
// Author : John Labenski
5
// Copyright: John Labenski, 2002
6
// License : wxWidgets v2
7
/////////////////////////////////////////////////////////////////////////////
9
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
10
#pragma implementation "optvalue.h"
13
// For compilers that support precompilation, includes "wx/wx.h"
14
#include "wx/wxprec.h"
21
#include "wx/object.h"
22
#include "wx/string.h"
23
#include "wx/gdicmn.h"
26
#include "wx/tokenzr.h"
27
#include "wx/things/optvalue.h"
29
#include "wx/arrimpl.cpp"
30
WX_DEFINE_OBJARRAY(wxArrayOptionValue);
32
//----------------------------------------------------------------------------
33
// Global wxString utilities
34
//----------------------------------------------------------------------------
36
wxArrayString wxStringToWords( const wxString &string )
40
// wxString word, s = string.Strip(wxString::both);
41
// wxMemoryInputStream memstream( s.c_str(), string.Length() );
42
// wxTextInputStream textstream(memstream);
43
// while (!memstream.Eof())
45
// word = textstream.ReadWord();
46
// if (!word.IsEmpty()) arr.Add(word.Strip(wxString::both));
51
wxString s = string.Strip(wxString::both);
54
arr.Add(s.BeforeFirst(wxT(' ')));
55
s = s.AfterFirst(wxT(' ')).Strip(wxString::both);
61
//----------------------------------------------------------------------------
62
// wxOptionValueRefData
63
//----------------------------------------------------------------------------
65
class wxOptionValueRefData: public wxObjectRefData
68
wxOptionValueRefData() : wxObjectRefData() {}
70
wxOptionValueRefData(const wxOptionValueRefData& data) : wxObjectRefData()
73
m_optionNames = data.m_optionNames;
74
m_optionValues = data.m_optionValues;
75
m_children = data.m_children;;
78
~wxOptionValueRefData() {}
81
wxArrayString m_optionNames;
82
wxArrayString m_optionValues;
83
wxArrayOptionValue m_children;
86
#define M_OPTVALUDATA ((wxOptionValueRefData *)m_refData)
88
//----------------------------------------------------------------------------
89
// wxOptionValue - a ref counted wxString key, wxString value container
90
//----------------------------------------------------------------------------
92
IMPLEMENT_DYNAMIC_CLASS(wxOptionValue, wxObject);
94
wxObjectRefData *wxOptionValue::CreateRefData() const
96
return new wxOptionValueRefData;
98
wxObjectRefData *wxOptionValue::CloneRefData(const wxObjectRefData *data) const
100
return new wxOptionValueRefData(*(const wxOptionValueRefData *)data);
103
bool wxOptionValue::Create()
106
m_refData = new wxOptionValueRefData();
110
bool wxOptionValue::Create( const wxOptionValue &optValue )
112
wxCHECK_MSG( optValue.Ok(), false, wxT("Invalid wxOptionValue") );
119
bool wxOptionValue::Create( const wxString &string )
122
m_refData = new wxOptionValueRefData();
124
int i, start = 0, length = string.Length();
128
const wxChar *s = string.GetData();
130
// const wxChar comma = 44; // comma
131
const wxChar tab = 9; // tab
132
// const wxChar space = 32; // space
133
const wxChar cr = 13; // carrage return
134
const wxChar lf = 10; // line feed
135
const wxChar openbracket = wxT('[');
136
const wxChar closebracket = wxT(']');
137
const wxChar equals = wxT('=');
138
const wxChar ccr = wxT('\n');
140
bool has_type = false;
142
for (i=0; i<length; i++, s++) // find opening [ for type
144
if (*s == openbracket)
147
s++; // don't include bracket in type
154
for (i=start; i<length; i++, s++) // find closing ] for type
156
if ((*s == closebracket))
158
M_OPTVALUDATA->m_type = buff;
163
else if ((*s != tab) && (*s != cr) && (*s != lf) && (*s != ccr))
173
for (i=start; i<length; i++) // add options
175
// add up characters until an = sign then the word before is the name
176
// the rest of the string before that is the value for the previous name
181
buff.Trim(false).Trim(true);
184
const wxChar *t = buff.GetData();
186
for (j = buff.Length()-1; j>=0; j--)
188
const wxChar c = t[j];
189
if ((c == cr) || (c == lf) || (c == ccr) || (c == tab))
196
M_OPTVALUDATA->m_optionNames.Add(buff.Mid(j));
197
buff.Remove(j).Trim(true);
200
M_OPTVALUDATA->m_optionValues.Add(buff);
207
buff.Trim(false).Trim(true);
209
M_OPTVALUDATA->m_optionValues.Add(buff);
211
if ((M_OPTVALUDATA->m_optionValues.GetCount() != M_OPTVALUDATA->m_optionNames.GetCount()))
214
wxPrintf(wxT("wxOptionValue::wxOptionValue( const wxString &string BUSTED\n"));
216
wxPrintf(wxT("[%s]\n"), M_OPTVALUDATA->m_type.c_str());
217
for (i=0; i<(int)M_OPTVALUDATA->m_optionNames.GetCount(); i++)
218
wxPrintf(wxT("{%s}\n"), M_OPTVALUDATA->m_optionNames[i].c_str());
219
for (i=0; i<(int)M_OPTVALUDATA->m_optionValues.GetCount(); i++)
220
wxPrintf(wxT("{%s}\n"), M_OPTVALUDATA->m_optionValues[i].c_str());
224
return ((M_OPTVALUDATA->m_optionValues.GetCount() > 0) &&
225
(M_OPTVALUDATA->m_optionValues.GetCount() !=
226
M_OPTVALUDATA->m_optionNames.GetCount()));
229
bool wxOptionValue::Copy( const wxOptionValue &optValue )
231
wxCHECK_MSG( optValue.Ok(), false, wxT("Invalid wxOptionValue") );
235
M_OPTVALUDATA->m_type = optValue.GetType();
236
M_OPTVALUDATA->m_optionNames = optValue.GetOptionNames();
237
M_OPTVALUDATA->m_optionValues = optValue.GetOptionValues();
238
if (optValue.GetChildrenCount())
239
M_OPTVALUDATA->m_children = *optValue.GetChildren();
241
M_OPTVALUDATA->m_children.Clear();
246
bool wxOptionValue::Ok() const
248
return M_OPTVALUDATA != NULL;
251
void wxOptionValue::Destroy()
256
//-----------------------------------------------------------------------------
258
wxString wxOptionValue::GetType() const
260
wxCHECK_MSG( Ok(), wxEmptyString, wxT("Invalid wxOptionValue") );
261
return M_OPTVALUDATA->m_type;
264
void wxOptionValue::SetType( const wxString &type )
266
wxCHECK_RET( Ok(), wxT("Invalid wxOptionValue") );
267
M_OPTVALUDATA->m_type = type;
270
//-----------------------------------------------------------------------------
272
size_t wxOptionValue::GetChildrenCount() const
274
wxCHECK_MSG( Ok(), 0, wxT("Invalid wxOptionValue") );
275
return M_OPTVALUDATA->m_children.GetCount();
277
wxArrayOptionValue *wxOptionValue::GetChildren() const
279
wxCHECK_MSG( Ok(), NULL, wxT("Invalid wxOptionValue") );
280
return &M_OPTVALUDATA->m_children;
282
bool wxOptionValue::AddChild( const wxOptionValue& child )
284
wxCHECK_MSG( Ok() && child.Ok(), 0, wxT("Invalid wxOptionValue") );
285
M_OPTVALUDATA->m_children.Add(child);
288
void wxOptionValue::DeleteChildren()
290
wxCHECK_RET( Ok(), wxT("Invalid wxOptionValue") );
291
M_OPTVALUDATA->m_children.Clear();
294
//-----------------------------------------------------------------------------
296
size_t wxOptionValue::GetOptionCount() const
298
wxCHECK_MSG( Ok(), 0, wxT("Invalid wxOptionValue") );
299
return M_OPTVALUDATA->m_optionNames.GetCount();
302
wxArrayString wxOptionValue::GetOptionNames() const
304
wxCHECK_MSG( Ok(), wxArrayString(), wxT("Invalid wxOptionValue") );
305
return M_OPTVALUDATA->m_optionNames;
307
wxArrayString wxOptionValue::GetOptionValues() const
309
wxCHECK_MSG( Ok(), wxArrayString(), wxT("Invalid wxOptionValue") );
310
return M_OPTVALUDATA->m_optionValues;
313
wxString wxOptionValue::GetOptionName( size_t n ) const
315
wxCHECK_MSG( Ok() && (n<M_OPTVALUDATA->m_optionNames.GetCount()),
316
wxEmptyString, wxT("Invalid wxOptionValue") );
317
return M_OPTVALUDATA->m_optionNames[n];
320
wxString wxOptionValue::GetOptionValue( size_t n ) const
322
wxCHECK_MSG( Ok() && (n<M_OPTVALUDATA->m_optionValues.GetCount()),
323
wxEmptyString, wxT("Invalid wxOptionValue") );
324
return M_OPTVALUDATA->m_optionValues[n];
327
int wxOptionValue::HasOption(const wxString& name) const
329
wxCHECK_MSG( Ok(), wxNOT_FOUND, wxT("Invalid wxOptionValue") );
330
int index = M_OPTVALUDATA->m_optionNames.Index(name, false);
334
int wxOptionValue::FindOption(const wxString &part_of_option_name) const
336
wxCHECK_MSG( Ok(), wxNOT_FOUND, wxT("Invalid wxOptionValue") );
337
int i, count = M_OPTVALUDATA->m_optionNames.GetCount();
339
for (i=0; i<count; i++)
341
if (M_OPTVALUDATA->m_optionNames[i].Contains(part_of_option_name))
347
bool wxOptionValue::DeleteOption(const wxString &name)
349
wxCHECK_MSG( Ok(), false, wxT("Invalid wxOptionValue"));
350
int index = M_OPTVALUDATA->m_optionNames.Index(name, false);
351
if (index == wxNOT_FOUND) return false;
352
M_OPTVALUDATA->m_optionNames.RemoveAt(index);
353
M_OPTVALUDATA->m_optionValues.RemoveAt(index);
357
bool wxOptionValue::DeleteOption( size_t n )
359
wxCHECK_MSG( Ok(), false, wxT("Invalid wxOptionValue") );
360
wxCHECK_MSG( n < M_OPTVALUDATA->m_optionValues.GetCount(), false, wxT("invalid index"));
361
M_OPTVALUDATA->m_optionNames.RemoveAt(n);
362
M_OPTVALUDATA->m_optionValues.RemoveAt(n);
366
//-----------------------------------------------------------------------------
369
// Option functions (arbitrary name/value mapping)
370
void wxOptionValue::SetOption(const wxString& name, const wxString& value, bool force)
372
wxCHECK_RET( Ok() && (name.Length() > 0), wxT("Invalid wxOptionValue or option") );
374
int idx = M_OPTVALUDATA->m_optionNames.Index(name, false);
375
if (idx == wxNOT_FOUND)
377
M_OPTVALUDATA->m_optionNames.Add(name);
378
M_OPTVALUDATA->m_optionValues.Add(value);
382
M_OPTVALUDATA->m_optionNames[idx] = name;
383
M_OPTVALUDATA->m_optionValues[idx] = value;
387
void wxOptionValue::SetOption(const wxString &name, bool update, const wxChar *format, ...)
390
va_start(argptr, format);
392
s.PrintfV(format, argptr);
394
SetOption(name, s, update);
397
//-----------------------------------------------------------------------------
400
wxString wxOptionValue::GetOption(const wxString& name) const
402
wxCHECK_MSG( Ok(), wxEmptyString, wxT("Invalid wxOptionValue") );
404
int idx = M_OPTVALUDATA->m_optionNames.Index(name, false);
405
if (idx != wxNOT_FOUND)
406
return M_OPTVALUDATA->m_optionValues[idx];
408
return wxEmptyString;
411
int wxOptionValue::GetOptionInt(const wxString& name) const
413
return wxAtoi(GetOption(name));
416
bool wxOptionValue::GetOption(const wxString& name, wxString &value ) const
418
wxString s = GetOption(name);
419
if (!s.IsEmpty()) { value = s; return true; }
422
bool wxOptionValue::GetOption(const wxString& name, int *value ) const
425
if (GetOption(name).ToLong(&n))
432
bool wxOptionValue::GetOption(const wxString& name, float *value ) const
435
if (GetOption(name, &n))
442
bool wxOptionValue::GetOption(const wxString& name, double *value ) const
445
if (GetOption(name).ToDouble(&n))
453
int wxOptionValue::GetOption(const wxString& name, const wxChar *format, ...) const
455
wxString n = GetOption(name);
456
if (n.IsEmpty()) return 0;
458
va_start(argptr, format);
459
// int i = wxVsscanf(n.c_str(), format, argptr); // VisualStudio doesn't have this
460
int i = wxSscanf(n.c_str(), format, argptr);
465
int wxOptionValue::GetOption(const wxString& name, wxArrayInt &values,
466
int count, const wxString& delims) const
468
wxString value = GetOption(name);
469
wxStringTokenizer tokens(value, delims, wxTOKEN_STRTOK);
472
while (((count < 0) || (read_count <= count)) && tokens.HasMoreTokens())
475
if (!tokens.GetNextToken().ToLong(&num)) return read_count;
482
bool wxOptionValue::GetOption(const wxString& name, unsigned char *value, int count,
483
const wxString& delims) const
485
wxArrayInt intArr; intArr.Alloc(count);
486
if (GetOption(name, intArr, count, delims) != count)
489
for (int i = 0; i < count; i++) value[i] = (unsigned char)intArr[i];
492
bool wxOptionValue::GetOption(const wxString& name, int *value, int count,
493
const wxString& delims) const
495
wxArrayInt intArr; intArr.Alloc(count);
496
if (GetOption(name, intArr, count, delims) != count)
499
for (int i = 0; i < count; i++) value[i] = intArr[i];
502
bool wxOptionValue::GetOption(const wxString& name, long *value, int count,
503
const wxString& delims) const
505
wxArrayInt intArr; intArr.Alloc(count);
506
if (GetOption(name, intArr, count, delims) != count)
509
for (int i = 0; i < count; i++) value[i] = intArr[i];
512
bool wxOptionValue::GetOption(const wxString& name, float *value, int count,
513
const wxString& delims) const
515
double *nums = (double*)malloc(sizeof(double)*count);
516
if (GetOption(name, nums, count, delims))
518
for (int i=0; i < count; i++) value[i] = (float)nums[i];
525
bool wxOptionValue::GetOption(const wxString& name, double *value, int count,
526
const wxString& delims) const
528
wxString optValue = GetOption(name);
529
wxStringTokenizer tokens(optValue, delims, wxTOKEN_STRTOK);
531
double *nums = (double*)malloc(sizeof(double)*count);
534
while ((read_count <= count) && tokens.HasMoreTokens())
536
if (!tokens.GetNextToken().ToDouble(&num))
541
if (read_count >= count) break;
545
if (read_count == count)
547
for (int i = 0; i < count; i++) value[i] = nums[i];
557
bool wxOptionValue::GetOption(const wxString& name, int *v1, int *v2,
558
const wxString& delims) const
561
if (GetOption(name, intArr, 2, delims) != 2)
564
if (v1) *v1 = intArr[0];
565
if (v2) *v2 = intArr[1];
568
bool wxOptionValue::GetOption(const wxString& name, int *v1, int *v2, int *v3,
569
const wxString& delims) const
572
if (GetOption(name, intArr, 3, delims) != 3)
575
if (v1) *v1 = intArr[0];
576
if (v2) *v2 = intArr[1];
577
if (v3) *v3 = intArr[2];
580
bool wxOptionValue::GetOption(const wxString& name, float *v1, float *v2, float *v3,
581
const wxString& delims) const
584
if (GetOption(name, nums, 3, delims))
587
if (v1) *v1 = (float)nums[0];
588
if (v2) *v2 = (float)nums[1];
589
if (v3) *v3 = (float)nums[2];
593
bool wxOptionValue::GetOption(const wxString& name, wxRect &value,
594
const wxString& delims) const
597
if (GetOption(name, intArr, 4, delims) != 4)
600
value = wxRect(intArr[0], intArr[1], intArr[2], intArr[3]);