OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
StdRegistry.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Some wrappers for easier access to the Windows registry */
19 
20 #include "C4Include.h"
21 #include "platform/StdRegistry.h"
22 
23 #ifdef _WIN32
25 #include <stdio.h>
26 
27 StdCopyStrBuf GetRegistryString(const char *szSubKey, const char *szValueName)
28 {
29  HKEY ckey;
30 
31  // Open the key
32  if (RegOpenKeyExW(HKEY_CURRENT_USER, GetWideChar(szSubKey), 0, KEY_READ, &ckey)!=ERROR_SUCCESS)
33  return StdCopyStrBuf();
34 
35  // Get the value
36  DWORD dwValSize = 128;
37  BYTE *sValue = new BYTE[dwValSize];
38  while(true)
39  {
40  DWORD valtype;
41  switch(RegQueryValueExW(ckey, GetWideChar(szValueName), nullptr, &valtype,
42  sValue, &dwValSize))
43  {
44  case ERROR_SUCCESS:
45  RegCloseKey(ckey);
46  if (valtype == REG_SZ)
47  {
48  StdCopyStrBuf nrv(reinterpret_cast<wchar_t*>(sValue));
49  delete[] sValue;
50  return nrv;
51  } else {
52  default:
53  delete[] sValue;
54  return StdCopyStrBuf();
55  }
56  break;
57  case ERROR_MORE_DATA:
58  delete[] sValue;
59  sValue = new BYTE[dwValSize];
60  break;
61  }
62  }
63 }
64 
65 bool SetRegistryString(const char *szSubKey,
66  const char *szValueName,
67  const char *szValue)
68 {
69 
70  long qerr;
71  HKEY ckey;
72  DWORD disposition;
73 
74  // Open the key
75  if ((qerr=RegCreateKeyExW(HKEY_CURRENT_USER,
76  GetWideChar(szSubKey),
77  0,
78  nullptr,
79  REG_OPTION_NON_VOLATILE,
80  KEY_ALL_ACCESS,
81  nullptr,
82  &ckey,
83  &disposition
84  ))!=ERROR_SUCCESS) return false;
85 
86  // Set the value
87  StdBuf v = GetWideCharBuf(szValue);
88  if ((qerr=RegSetValueExW(ckey,
89  GetWideChar(szValueName),
90  0,
91  REG_SZ,
92  getBufPtr<BYTE>(v),
93  v.getSize()
94  ))!=ERROR_SUCCESS) { RegCloseKey(ckey); return false; }
95 
96  // Close the key
97  RegCloseKey(ckey);
98 
99  return true;
100 }
101 
102 static bool DeleteRegistryKey(HKEY hKey, const wchar_t *szSubKey)
103 {
104  HKEY ckey;
105  // Open the key
106  if (RegOpenKeyExW(hKey, szSubKey, 0, KEY_ALL_ACCESS, &ckey) != ERROR_SUCCESS) return false;
107  // Delete all subkeys
108  wchar_t strChild[1024 + 1];
109  while (RegEnumKeyW(ckey, 0, strChild, 1024) == ERROR_SUCCESS)
110  if (!DeleteRegistryKey(ckey, strChild))
111  return false;
112  // Close the key
113  RegCloseKey(ckey);
114 
115  // Delete the key
116  if (RegDeleteKeyW(hKey, szSubKey) != ERROR_SUCCESS) return false;
117  // Success
118  return true;
119 }
120 
121 static bool SetRegClassesRoot(const wchar_t *szSubKey,
122  const wchar_t *szValueName,
123  const wchar_t *szStringValue)
124 {
125 
126  long qerr;
127  HKEY ckey;
128  DWORD disposition;
129 
130  // Open the key
131  if ((qerr=RegCreateKeyExW(HKEY_CLASSES_ROOT,
132  szSubKey,
133  0,
134  nullptr,
135  REG_OPTION_NON_VOLATILE,
136  KEY_ALL_ACCESS,
137  nullptr,
138  &ckey,
139  &disposition
140  ))!=ERROR_SUCCESS) return false;
141 
142  // Set the value
143  if ((qerr=RegSetValueExW(ckey,
144  szValueName,
145  0,
146  REG_SZ,
147  (const BYTE*)szStringValue,
148  (wcslen(szStringValue) + 1) * sizeof(wchar_t)
149  ))!=ERROR_SUCCESS) { RegCloseKey(ckey); return false; }
150 
151  // Close the key
152  RegCloseKey(ckey);
153 
154  return true;
155 }
156 
157 bool SetRegShell(const wchar_t *szClassName,
158  const wchar_t *szShellName,
159  const wchar_t *szShellCaption,
160  const wchar_t *szCommand,
161  bool fMakeDefault)
162 {
163  wchar_t szKeyName[256+1];
164  // Set shell caption
165  _snwprintf(szKeyName,256,L"%s\\Shell\\%s",szClassName,szShellName);
166  if (!SetRegClassesRoot(szKeyName, nullptr, szShellCaption)) return false;
167  // Set shell command
168  _snwprintf(szKeyName,256,L"%s\\Shell\\%s\\Command",szClassName,szShellName);
169  if (!SetRegClassesRoot(szKeyName, nullptr, szCommand)) return false;
170  // Set as default command
171  if (fMakeDefault)
172  {
173  _snwprintf(szKeyName, 256,L"%s\\Shell", szClassName);
174  if (!SetRegClassesRoot(szKeyName, nullptr, szShellName)) return false;
175  }
176  return true;
177 }
178 
179 bool RemoveRegShell(const char *szClassName,
180  const char *szShellName)
181 {
182  wchar_t strKey[256+1];
183  _snwprintf(strKey, 256, L"%s\\Shell\\%s", GetWideChar(szClassName).p, GetWideChar(szShellName).p);
184  if (!DeleteRegistryKey(HKEY_CLASSES_ROOT, strKey)) return false;
185  return true;
186 }
187 
188 //------------------------------ Window Position ------------------------------------------
189 
190 bool StoreWindowPosition(HWND hwnd,
191  const char *szWindowName,
192  const char *szSubKey,
193  bool fStoreSize)
194 {
195  RECT winpos;
196  char regstr[100];
197  if (IsZoomed(hwnd))
198  return SetRegistryString(szSubKey,szWindowName,"Maximized");
199  if (IsIconic(hwnd))
200  return SetRegistryString(szSubKey,szWindowName,"Minimized");
201  if (!GetWindowRect(hwnd,&winpos)) return false;
202  if (fStoreSize) sprintf(regstr,"%ld,%ld,%ld,%ld",winpos.left,winpos.top,winpos.right-winpos.left,winpos.bottom-winpos.top);
203  else sprintf(regstr,"%ld,%ld",winpos.left,winpos.top);
204  return SetRegistryString(szSubKey,szWindowName,regstr);
205 }
206 
207 bool RestoreWindowPosition(HWND hwnd,
208  const char *szWindowName,
209  const char *szSubKey,
210  bool fHidden)
211 {
212  char buffer2[5];
213  int x,y,wdt,hgt;
214  bool fSetSize=true;
215  StdCopyStrBuf regstr = GetRegistryString(szSubKey,szWindowName);
216  // No position stored: cannot restore
217  if (regstr.isNull())
218  return false;
219  if (regstr == "Maximized")
220  return !!ShowWindow(hwnd,SW_MAXIMIZE | SW_NORMAL);
221  if (regstr == "Minimized")
222  return !!ShowWindow(hwnd,SW_MINIMIZE | SW_NORMAL);
223  SCopySegment(regstr.getData(),0,buffer2,',',4); sscanf(buffer2,"%i",&x);
224  SCopySegment(regstr.getData(),1,buffer2,',',4); sscanf(buffer2,"%i",&y);
225  if (SCopySegment(regstr.getData(),2,buffer2,',',4)) sscanf(buffer2,"%i",&wdt); else fSetSize=false;
226  if (SCopySegment(regstr.getData(),3,buffer2,',',4)) sscanf(buffer2,"%i",&hgt); else fSetSize=false;
227  if (!fSetSize)
228  {
229  RECT winpos; if (!GetWindowRect(hwnd,&winpos)) return false;
230  wdt=winpos.right-winpos.left; hgt=winpos.bottom-winpos.top;
231  }
232  // Move window
233  WINDOWPLACEMENT wp; memset(&wp, 0, sizeof(WINDOWPLACEMENT)); wp.length = sizeof(WINDOWPLACEMENT);
234  GetWindowPlacement(hwnd, &wp);
235  RECT normalpos;
236  normalpos.left = x; normalpos.right = wdt + x;
237  normalpos.top = y; normalpos.bottom = hgt + y;
238  wp.rcNormalPosition = normalpos;
239  if (SetWindowPlacement(hwnd, &wp))
240  return false;
241  // Hide window
242  if (fHidden)
243  return !!ShowWindow(hwnd, SW_HIDE);
244  // Show window
245  return !!ShowWindow(hwnd, SW_NORMAL);
246 }
247 
248 //------------------------------ Registry compiler ------------------------------------------
249 
250 // *** StdCompilerConfigWrite
251 
252 StdCompilerConfigWrite::StdCompilerConfigWrite(HKEY hRoot, const char *szPath)
253  : iDepth(0), pKey(new Key())
254 {
255  pKey->Name = szPath;
256  pKey->subindex = 0;
257  pKey->Handle = 0;
258  CreateKey(hRoot);
259 }
260 
261 StdCompilerConfigWrite::~StdCompilerConfigWrite()
262 {
263  assert(!iDepth);
264  if (pKey->Handle) RegCloseKey(pKey->Handle);
265  delete pKey;
266 }
267 
268 bool StdCompilerConfigWrite::Name(const char *szName)
269 {
270  // Open parent key (if not already done so)
271  CreateKey();
272  // Push new subkey onto the stack
273  Key *pnKey = new Key();
274  pnKey->Handle = 0;
275  pnKey->subindex = 0;
276  if (pKey->LastChildName == szName)
277  pnKey->Name.Format("%s%d", szName, (int)++pKey->subindex);
278  else
279  {
280  pnKey->Name = szName;
281  pKey->LastChildName = szName;
282  }
283  pnKey->Parent = pKey;
284  pKey = pnKey;
285  iDepth++;
286  last_written_string.clear();
287  return true;
288 }
289 
290 void StdCompilerConfigWrite::NameEnd(bool fBreak)
291 {
292  assert(iDepth);
293  // Close current key
294  if (pKey->Handle)
295  RegCloseKey(pKey->Handle);
296  // Pop
297  Key *poKey = pKey;
298  pKey = poKey->Parent;
299  delete poKey;
300  iDepth--;
301  last_written_string.clear();
302 }
303 
304 bool StdCompilerConfigWrite::FollowName(const char *szName)
305 {
306  NameEnd(); return Name(szName);
307 }
308 
309 bool StdCompilerConfigWrite::Default(const char *szName)
310 {
311  // Open parent
312  CreateKey();
313  // Remove key/value (failsafe)
314  DeleteRegistryKey(pKey->Handle, GetWideChar(szName));
315  RegDeleteValueW(pKey->Handle, GetWideChar(szName));
316  // Handled
317  return true;
318 }
319 
320 bool StdCompilerConfigWrite::Separator(Sep eSep)
321 {
322  // Just append separator and re-write last string
323  const char s[2] = { SeparatorToChar(eSep) , '\0' };
324  WriteString(s);
325  return true;
326 }
327 
328 void StdCompilerConfigWrite::DWord(int32_t &rInt)
329 {
330  WriteDWord(rInt);
331 }
332 void StdCompilerConfigWrite::DWord(uint32_t &rInt)
333 {
334  WriteDWord(rInt);
335 }
336 void StdCompilerConfigWrite::Word(int16_t &rInt)
337 {
338  WriteDWord(rInt);
339 }
340 void StdCompilerConfigWrite::Word(uint16_t &rInt)
341 {
342  WriteDWord(rInt);
343 }
344 void StdCompilerConfigWrite::Byte(int8_t &rInt)
345 {
346  WriteDWord(rInt);
347 }
348 void StdCompilerConfigWrite::Byte(uint8_t &rInt)
349 {
350  WriteDWord(rInt);
351 }
352 void StdCompilerConfigWrite::Boolean(bool &rBool)
353 {
354  WriteDWord(rBool ? 1 : 0);
355 }
356 void StdCompilerConfigWrite::Character(char &rChar)
357 {
358  WriteString(FormatString("%c", rChar).getData());
359 }
360 
361 void StdCompilerConfigWrite::String(char *szString, size_t iMaxLength, RawCompileType eType)
362 {
363  WriteString(szString);
364 }
365 
366 void StdCompilerConfigWrite::String(char **pszString, RawCompileType eType)
367 {
368  WriteString(pszString ? *pszString : "");
369 }
370 
371 void StdCompilerConfigWrite::String(std::string &str, RawCompileType eType)
372 {
373  WriteString(str.c_str());
374 }
375 
376 void StdCompilerConfigWrite::Raw(void *pData, size_t iSize, RawCompileType eType)
377 {
378  excCorrupt("Raw values aren't supported for registry compilers!");
379 }
380 
381 void StdCompilerConfigWrite::Begin()
382 {
383  assert(!iDepth);
384 }
385 
386 void StdCompilerConfigWrite::End()
387 {
388  assert(!iDepth);
389 }
390 
391 void StdCompilerConfigWrite::CreateKey(HKEY hParent)
392 {
393  // Already open?
394  if (pKey->Handle)
395  return;
396  // Open/Create registry key
397  if (RegCreateKeyExW(hParent ? hParent : pKey->Parent->Handle,
398  pKey->Name.GetWideChar(),
399  0, nullptr, REG_OPTION_NON_VOLATILE,
400  KEY_WRITE, nullptr,
401  &pKey->Handle, nullptr) != ERROR_SUCCESS)
402  excCorrupt("Could not create key %s!", pKey->Name.getData());
403 }
404 
405 void StdCompilerConfigWrite::WriteDWord(uint32_t iVal)
406 {
407  // Set the value
408  if (RegSetValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
409  0, REG_DWORD, reinterpret_cast<const BYTE *>(&iVal),
410  sizeof(iVal)) != ERROR_SUCCESS)
411  excCorrupt("Could not write key %s!", pKey->Name.getData());
412 }
413 
414 void StdCompilerConfigWrite::WriteString(const char *szString)
415 {
416  // Append to write-string and just re-write
417  // This is probably pretty inefficient, but config saving only uses it for a few key overloads
418  last_written_string += szString;
419  StdBuf v = GetWideCharBuf(last_written_string.c_str());
420  if (RegSetValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
421  0, REG_SZ, getBufPtr<BYTE>(v), v.getSize()) != ERROR_SUCCESS)
422  excCorrupt("Could not write key %s!", pKey->Name.getData());
423 }
424 
425 // *** StdCompilerConfigRead
426 
427 StdCompilerConfigRead::StdCompilerConfigRead(HKEY hRoot, const char *szPath)
428  : iDepth(0), pKey(new Key())
429 {
430  pKey->Name = szPath;
431  pKey->Virtual = false;
432  pKey->subindex = 0;
433  // Open root
434  if (RegOpenKeyExW(hRoot, GetWideChar(szPath),
435  0, KEY_READ,
436  &pKey->Handle) != ERROR_SUCCESS)
437  pKey->Handle = 0;
438 }
439 
440 StdCompilerConfigRead::~StdCompilerConfigRead()
441 {
442  assert(!iDepth);
443  if (pKey->Handle) RegCloseKey(pKey->Handle);
444  delete pKey;
445 }
446 
447 bool StdCompilerConfigRead::Name(const char *szName)
448 {
449  // Adjust key name for lists
450  StdCopyStrBuf sName;
451  if (pKey->LastChildName == szName)
452  sName.Format("%s%d", szName, (int)++pKey->subindex);
453  else
454  {
455  sName = szName;
456  pKey->LastChildName = szName;
457  }
458  bool fFound = true;
459  // Try to open registry key
460  HKEY hSubKey; DWORD dwType = 0;
461  if (RegOpenKeyExW(pKey->Handle, sName.GetWideChar(),
462  0, KEY_READ,
463  &hSubKey) != ERROR_SUCCESS)
464  {
465  hSubKey = 0;
466  // Try to query value (exists?)
467  if (RegQueryValueExW(pKey->Handle, sName.GetWideChar(),
468  0, &dwType, nullptr, nullptr) != ERROR_SUCCESS)
469  fFound = false;
470  }
471  // Push new subkey on the stack
472  Key *pnKey = new Key();
473  pnKey->Handle = hSubKey;
474  pnKey->Name = sName;
475  pnKey->subindex = 0;
476  pnKey->Parent = pKey;
477  pnKey->Virtual = !fFound;
478  pnKey->Type = dwType;
479  pKey = pnKey;
480  iDepth++;
481  ResetLastString();
482  return fFound;
483 }
484 
485 void StdCompilerConfigRead::NameEnd(bool fBreak)
486 {
487  assert(iDepth);
488  // Close current key
489  if (pKey->Handle)
490  RegCloseKey(pKey->Handle);
491  // Pop
492  Key *poKey = pKey;
493  pKey = poKey->Parent;
494  delete poKey;
495  iDepth--;
496  ResetLastString();
497 }
498 
499 void StdCompilerConfigRead::ResetLastString()
500 {
501  has_read_string = false;
502  has_separator_mismatch = false;
503  last_read_string.clear();
504 }
505 
506 bool StdCompilerConfigRead::FollowName(const char *szName)
507 {
508  NameEnd(); return Name(szName);
509 }
510 
511 bool StdCompilerConfigRead::Separator(Sep eSep)
512 {
513  // Make sure there's a string to work on
514  ReadString();
515  // Match?
516  if (last_read_string.size() && (last_read_string.front() == SeparatorToChar(eSep)))
517  {
518  // Match found. Just advance.
519  last_read_string = last_read_string.substr(1);
520  return true;
521  }
522  else
523  {
524  // Separator mismatch? Let all read attempts fail until the correct separator is found or the naming ends.
525  has_separator_mismatch = true;
526  return false;
527  }
528 }
529 
530 void StdCompilerConfigRead::DWord(int32_t &rInt)
531 {
532  rInt = int32_t(ReadDWord());
533 }
534 void StdCompilerConfigRead::DWord(uint32_t &rInt)
535 {
536  rInt = ReadDWord();
537 }
538 void StdCompilerConfigRead::Word(int16_t &rInt)
539 {
540  rInt = int16_t(ReadDWord());
541 }
542 void StdCompilerConfigRead::Word(uint16_t &rInt)
543 {
544  rInt = uint16_t(ReadDWord());
545 }
546 void StdCompilerConfigRead::Byte(int8_t &rInt)
547 {
548  rInt = int8_t(ReadDWord());
549 }
550 void StdCompilerConfigRead::Byte(uint8_t &rInt)
551 {
552  rInt = uint8_t(ReadDWord());
553 }
554 void StdCompilerConfigRead::Boolean(bool &rBool)
555 {
556  try
557  {
558  ReadString();
559  rBool = (!has_separator_mismatch && (last_read_string == "true"));
560  }
561  catch (NotFoundException *pExc)
562  {
563  delete pExc;
564  uint32_t iVal = ReadDWord();
565  rBool = !! iVal;
566  }
567 }
568 void StdCompilerConfigRead::Character(char &rChar)
569 {
570  try
571  {
572  ReadString();
573  rChar = (last_read_string.length() && !has_separator_mismatch) ? last_read_string.front() : '\0';
574  }
575  catch (NotFoundException *pExc)
576  {
577  delete pExc;
578  uint32_t iVal = ReadDWord();
579  rChar = char(iVal);
580  }
581 }
582 
583 void StdCompilerConfigRead::String(char *szString, size_t iMaxLength, RawCompileType eType)
584 {
585  std::string s;
586  String(s, eType);
587  SCopy(s.c_str(), szString, iMaxLength);
588 }
589 
590 void StdCompilerConfigRead::String(char **pszString, RawCompileType eType)
591 {
592  // Read string, copy into buffer and release buffer (to use buffer allocation method)
593  std::string s;
594  String(s, eType);
595  StdStrBuf sbuf(s.c_str(), true);
596  *pszString = sbuf.GrabPointer();
597 }
598 
599 void StdCompilerConfigRead::String(std::string &str, RawCompileType type)
600 {
601  // Read from string until end marker is found
602  ReadString();
603  if (has_separator_mismatch || !last_read_string.length()) { str = "\0"; return; }
604  size_t string_end_pos = 0;
605  const char *s = last_read_string.c_str();
606  size_t spos = 0;
607  while (!IsStringEnd(s[spos], type)) ++spos;
608  if (spos < last_read_string.length())
609  {
610  str = last_read_string.substr(0, spos);
611  last_read_string = last_read_string.substr(spos);
612  }
613  else
614  {
615  str = last_read_string;
616  last_read_string.clear();
617  }
618 }
619 
620 void StdCompilerConfigRead::Raw(void *pData, size_t iSize, RawCompileType eType)
621 {
622  excCorrupt(0, "Raw values aren't supported for registry compilers!");
623 }
624 
625 void StdCompilerConfigRead::Begin()
626 {
627  assert(!iDepth);
628 }
629 
630 void StdCompilerConfigRead::End()
631 {
632  assert(!iDepth);
633 }
634 
635 uint32_t StdCompilerConfigRead::ReadDWord()
636 {
637  // Virtual key?
638  if (pKey->Virtual)
639  { excNotFound("Could not read value %s! Parent key doesn't exist!", pKey->Name.getData()); return 0; }
640  // Wrong type?
641  if (pKey->Type != REG_DWORD && pKey->Type != REG_DWORD_LITTLE_ENDIAN)
642  { excNotFound("Wrong value type!"); return 0; }
643  // Clear previous string
644  ResetLastString();
645  // Read
646  uint32_t iVal; DWORD iSize = sizeof(iVal);
647  if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
648  0, nullptr,
649  reinterpret_cast<LPBYTE>(&iVal),
650  &iSize) != ERROR_SUCCESS)
651  { excNotFound("Could not read value %s!", pKey->Name.getData()); return 0; }
652  // Check size
653  if (iSize != sizeof(iVal))
654  { excCorrupt("Wrong size of a DWord!"); return 0; }
655  // Return
656  return iVal;
657 }
658 
659 void StdCompilerConfigRead::ReadString()
660 {
661  // Already read?
662  if (!has_read_string)
663  {
664  ResetLastString();
665  // Virtual key?
666  if (pKey->Virtual)
667  {
668  excNotFound("Could not read value %s! Parent key doesn't exist!", pKey->Name.getData()); return;
669  }
670  // Wrong type?
671  if (pKey->Type != REG_SZ)
672  {
673  excNotFound("Wrong value type!"); return;
674  }
675  // Get size of string
676  DWORD iSize;
677  if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
678  0, nullptr,
679  nullptr,
680  &iSize) != ERROR_SUCCESS)
681  {
682  excNotFound("Could not read value %s!", pKey->Name.getData()); return;
683  }
684  // Allocate string
685  StdBuf Result; Result.SetSize(iSize);
686  // Read
687  if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
688  0, nullptr,
689  reinterpret_cast<BYTE *>(Result.getMData()),
690  &iSize) != ERROR_SUCCESS)
691  {
692  excNotFound("Could not read value %s!", pKey->Name.getData()); return;
693  }
694  // Check size
695  if (wcslen(getBufPtr<wchar_t>(Result)) + 1 != iSize / sizeof(wchar_t))
696  {
697  excCorrupt("Wrong size of a string!"); return;
698  }
699  // Remember string
700  StdStrBuf str_result(getBufPtr<wchar_t>(Result));
701  last_read_string = str_result.getData();
702  has_read_string = true;
703  }
704 }
705 
706 #endif // _WIN32
const char * getData() const
Definition: StdBuf.h:450
char * GrabPointer()
Definition: StdBuf.h:467
Definition: StdBuf.h:37
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:122
C4String * String(const char *str)
Definition: C4AulDefFunc.h:31
#define sprintf
Definition: Standard.h:171
StdStrBuf::wchar_t_holder GetWideChar(const char *utf8, bool double_null_terminate=false)
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
Definition: Standard.cpp:243
uint8_t BYTE
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:181
size_t getSize() const
Definition: StdBuf.h:109
void SetSize(size_t inSize)
Definition: StdBuf.h:212
StdBuf GetWideCharBuf(const char *utf8)
bool isNull() const
Definition: StdBuf.h:449
uint32_t DWORD
#define s
void * getMData()
Definition: StdBuf.h:108
int iSize
Definition: TstC4NetIO.cpp:35
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:277