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