00001 // $Id: varstr.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 #include "camtypes.h" 00100 //#include "varstr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00101 00102 00103 /************************************************************************************** 00104 > static BOOL StringVar::Init() 00105 00106 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00107 Created: 31st January 2006 00108 Inputs:- 00109 Outputs: TRUE if this class initialises OK 00110 FALSE otherwise 00111 Purpose: Test StringVar functionality in debug builds. 00112 Scope: Public 00113 00114 ***************************************************************************************/ 00115 00116 BOOL StringVar::Init() 00117 { 00118 #if defined(_DEBUG) && 0 00119 StringVar t1(_T("Test string\n")); 00120 StringVar t2(_T("0123456789012345678901234567890123456789") // 8*40 = 320 chars 00121 _T("0123456789012345678901234567890123456789") 00122 _T("0123456789012345678901234567890123456789") 00123 _T("0123456789012345678901234567890123456789") 00124 _T("0123456789012345678901234567890123456789") 00125 _T("0123456789012345678901234567890123456789") 00126 _T("0123456789012345678901234567890123456789") 00127 _T("0123456789012345678901234567890123456789") 00128 ); 00129 String_32 st32(_T(" Woohoo!\n")); 00130 00131 StringVar t3; 00132 t3 = st32; 00133 t3 += t1; 00134 t3 += t2; 00135 TRACEUSER("Phil", _T("StringVar Test 1 = %s"), (TCHAR*)t3); 00136 00137 StringVar t4(st32); 00138 StringVar t5(_R(IDS_MANY)); 00139 t4 += TCHAR('-') + t5; // Implicit cast? 00140 TRACEUSER("Phil", _T("StringVar Test 2 = %s\n"), (TCHAR*)t4); 00141 #endif 00142 00143 return TRUE; 00144 } 00145 00146 00147 00148 /************************************************************************************** 00149 > StringVar::StringVar(const TCHAR* psz = 0) 00150 00151 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00152 Created: 30th January 2006 00153 Inputs: An optional pointer to a (constant) Unicode character array - if 00154 omitted then the String becomes empty (NOT the null pointer). 00155 Purpose: Constructs a string of the appropriate maximum length. 00156 Errors: ASSERTion failure if the passed character array is too long for 00157 this length of string. 00158 Scope: Public 00159 ***************************************************************************************/ 00160 00161 StringVar::StringVar(const TCHAR* psz) 00162 { 00163 text = NULL; 00164 length = 0; 00165 00166 UINT32 newlen = camStrlen(psz); 00167 EnsureAlloc(newlen); 00168 SafeCopy(psz, newlen); 00169 } 00170 00171 00172 00173 /************************************************************************************** 00174 > StringVar::StringVar(const StringBase& other) 00175 00176 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00177 Created: 30th January 2006 00178 Inputs: An optional pointer to a (constant) Unicode character array - if 00179 omitted then the String becomes empty (NOT the null pointer). 00180 Purpose: Constructs a string of the appropriate maximum length. 00181 Errors: ASSERTion failure if the passed character array is too long for 00182 this length of string, or if psz is NULL. 00183 Scope: Public 00184 ***************************************************************************************/ 00185 00186 StringVar::StringVar(const StringBase& other) 00187 { 00188 text = NULL; 00189 length = 0; 00190 00191 UINT32 newlen = other.Length(); 00192 EnsureAlloc(newlen); 00193 SafeCopy((const TCHAR*)other, newlen); 00194 } 00195 00196 00197 00198 /************************************************************************************** 00199 > StringVar::StringVar(UINT32 resID, UINT32 hinst = 0) 00200 00201 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00202 Created: 30th January 2006 00203 Inputs: An optional pointer to a (constant) Unicode character array - if 00204 omitted then the String becomes empty (NOT the null pointer). 00205 Purpose: Constructs a string of the appropriate maximum length. 00206 Errors: ASSERTion failure if the passed character array is too long for 00207 this length of string, or if psz is NULL. 00208 Scope: Public 00209 ***************************************************************************************/ 00210 00211 StringVar::StringVar(UINT32 resID, UINT32 hinst) 00212 { 00213 text = NULL; 00214 length = 0; 00215 00216 const TCHAR* pResText = CamResource::GetText(resID); 00217 UINT32 len = camStrlen(pResText); 00218 00219 EnsureAlloc(len); 00220 SafeCopy(pResText, len); 00221 } 00222 00223 00224 00225 /************************************************************************************** 00226 > StringVar::StringVar(const wxString& wxs) 00227 00228 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00229 Created: 30th January 2006 00230 Inputs: An optional pointer to a (constant) Unicode character array - if 00231 omitted then the String becomes empty (NOT the null pointer). 00232 Purpose: Constructs a string of the appropriate maximum length. 00233 Errors: ASSERTion failure if the passed character array is too long for 00234 this length of string, or if psz is NULL. 00235 Scope: Public 00236 ***************************************************************************************/ 00237 00238 StringVar::StringVar(const wxString& wxs) 00239 { 00240 text = NULL; 00241 length = 0; 00242 00243 UINT32 newlen = wxs.Len(); 00244 EnsureAlloc(newlen); 00245 SafeCopy((const TCHAR*)wxs, newlen); 00246 } 00247 00248 00249 00250 /************************************************************************************** 00251 > StringVar& StringVar::operator+=(const StringBase& rhs) 00252 00253 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00254 Created: 31st January 2006 00255 Inputs: The string to add to the end of this string. 00256 Returns: A reference to the lhs, ie. this StringVar as an lvalue. 00257 Purpose: Append string y onto the end of string x, eg. 00258 x = TEXT("hello"); 00259 cout << (x += TEXT(" world!")) << endl; 00260 ***************************************************************************************/ 00261 inline StringVar& StringVar::operator+=(const StringBase& rhs) 00262 { 00263 ERROR3IF(this==NULL, "StringVar this pointer is NULL!"); 00264 ERROR3IF(text==NULL || (const TCHAR*)rhs==NULL, "Call to StringVar::operator+= for an unALLOCated String"); 00265 00266 if (text && (const TCHAR*)rhs) 00267 SafeCat((const TCHAR*)rhs); 00268 00269 return *this; 00270 } 00271 00272 00273 00274 /************************************************************************************** 00275 > StringVar& StringVar::operator+=(const TCHAR* s) 00276 00277 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00278 Created: 31st January 2006 00279 Inputs: The C-style character "string" to add to the end of this String. 00280 Returns: A reference to the lhs, ie. this StringBase as an lvalue. 00281 Purpose: Append string y onto the end of string x, eg. 00282 x = TEXT("hello"); 00283 cout << (x += TEXT(" world!")) << endl; 00284 ***************************************************************************************/ 00285 inline StringVar& StringVar::operator+=(const TCHAR* s) 00286 { 00287 ERROR3IF(this==NULL, "StringVar this pointer is NULL!"); 00288 ERROR3IF(text==NULL || s==NULL, "Call to String::operator+= for an unALLOCated String"); 00289 00290 if (text && s) 00291 SafeCat(s); 00292 00293 return *this; 00294 } 00295 00296 00297 00298 /************************************************************************************** 00299 > StringVar& StringVar::operator+=(const TCHAR ch) 00300 00301 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00302 Created: 31st January 2006 00303 Inputs: A character to add to the end of this String. 00304 Returns: A reference to the lhs, ie. this StringVar as an lvalue. 00305 Purpose: Appends this character to the end of this string 00306 ***************************************************************************************/ 00307 StringVar& StringVar::operator+=(const TCHAR ch) 00308 { 00309 ERROR3IF(this==NULL, "StringVar this pointer is NULL!"); 00310 ERROR3IF(text==NULL, "Call to String::operator+= for an unALLOCated String"); 00311 00312 if (text && ch!=0) 00313 { 00314 TCHAR tch[2]; 00315 tch[0] = ch; 00316 tch[1] = 0; 00317 SafeCat(tch); 00318 } 00319 00320 return *this; 00321 } 00322 00323 00324 00325 /************************************************************************************** 00326 > StringVar& StringVar::operator=(const StringBase& rhs) 00327 00328 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00329 Created: 1st February 2006 00330 Inputs: A reference to a constant String. 00331 Returns: A reference to this. 00332 Purpose: Assignment (set equal to) operator, eg. 00333 StringBase x("rhubarb"); 00334 x = "custard"; 00335 ***************************************************************************************/ 00336 StringVar& StringVar::operator=(const StringBase& other) 00337 { 00338 ERROR3IF(this==NULL, "StringVar this pointer is NULL!"); 00339 ERROR3IF(text==NULL || (const TCHAR*)other==NULL, "Call to String::operator= for an unALLOCated String"); 00340 00341 if (text && (const TCHAR*)other) 00342 { 00343 UINT32 newlen = other.Length(); 00344 EnsureAlloc(newlen); 00345 SafeCopy((const TCHAR*)other, newlen); 00346 } 00347 return *this; 00348 } 00349 00350 00351 00352 /************************************************************************************** 00353 > StringVar& StringVar::operator=(const TCHAR* pcsz) 00354 00355 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00356 Created: 1st February 2006 00357 Inputs: A pointer to a constant C-style (possibly wide-character) string. 00358 Returns: A reference to this. 00359 Purpose: Assignment (set equal to) operator, eg. 00360 StringBase x("rhubarb"); 00361 x = "custard"; 00362 ***************************************************************************************/ 00363 StringVar& StringVar::operator=(const TCHAR* s) 00364 { 00365 ERROR3IF(this==NULL, "StringVar this pointer is NULL!"); 00366 ERROR3IF(text==NULL || s==NULL, "Call to String::operator= for an unALLOCated String or 0 char*"); 00367 00368 if (text && s) 00369 { 00370 UINT32 newlen = camStrlen(s); 00371 EnsureAlloc(newlen); 00372 SafeCopy(s, newlen); 00373 } 00374 00375 return *this; 00376 } 00377 00378 00379 00380 /************************************************************************************** 00381 > StringVar& StringVar::operator=(const TCHAR ch) 00382 00383 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00384 Created: 1st February 2006 00385 Inputs: ch - a single character 00386 Returns: A reference to this. 00387 Purpose: Assigns the single character to this string 00388 ***************************************************************************************/ 00389 inline StringVar& StringVar::operator=(const TCHAR ch) 00390 { 00391 ERROR3IF(this==NULL, "StringVar this pointer is NULL!"); 00392 ERROR3IF(text==NULL, "Call to String::operator= for an unALLOCated String"); 00393 00394 EnsureAlloc(1); 00395 if (text && length>=2) // length includes term 00396 { 00397 text[0] = ch; 00398 text[1] = 0; 00399 } 00400 00401 return *this; 00402 } 00403 00404 00405 00406 00407 /************************************************************************************** 00408 00409 > void StringVar::SafeCat(const TCHAR* string) 00410 00411 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00412 Created: 31st January 2006 00413 00414 Inputs: string 0-terminated source string 00415 Outputs: - 00416 Returns: - 00417 Purpose: Appends string to the end of this 00418 SeeAlso: StringBase::Alloc, StringVar::Alloc 00419 00420 ***************************************************************************************/ 00421 00422 void StringVar::SafeCat(const TCHAR* string) 00423 { 00424 ERROR3IF(this==NULL || string==NULL, "StringBase::SafeCat given NULL params"); 00425 if (string==NULL) 00426 return; 00427 00428 // Are we going to overflow ? 00429 UINT32 newlen = camStrlen(text) + camStrlen(string); 00430 EnsureAlloc(newlen); 00431 00432 // Now we can concatenate the specified string, if we allocated the buffer correcetly 00433 if (text && length>0 && (length-1) >= newlen) 00434 camStrcat(text, string); 00435 } 00436 00437 00438 00439 /************************************************************************************** 00440 00441 > void StringVar::SafeCopy(const TCHAR* string, UINT32 maxlen=0) 00442 00443 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00444 Created: 1st February 2006 00445 00446 Inputs: string 0-terminated source string 00447 Outputs: - 00448 Returns: - 00449 Purpose: Assigns string to this carefully avoiding buffer overflow 00450 00451 ***************************************************************************************/ 00452 00453 void StringVar::SafeCopy(const TCHAR* string, UINT32 maxlen) 00454 { 00455 ERROR3IF(this==NULL || string==NULL, "StringBase::SafeCopy given NULL params"); 00456 00457 if (text!=NULL && length>0 && string!=NULL) 00458 { 00459 if (maxlen==0) 00460 maxlen = camStrlen(string); 00461 00462 maxlen = ((length-1)<maxlen) ? length-1 : maxlen; // length includes term 00463 00464 camStrncpy(text, string, maxlen+1); // Copy the string AND the terminating 0 character 00465 } 00466 } 00467 00468 00469 00470 /************************************************************************************** 00471 00472 > void StringVar::EnsureAlloc(UINT32 newlen) 00473 00474 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00475 Created: 31st January 2006 00476 00477 Inputs: string 0-terminated destination string 00478 Outputs: - 00479 Returns: - 00480 Purpose: Appends string to the end of this 00481 SeeAlso: StringBase::Alloc, StringVar::Alloc 00482 00483 ***************************************************************************************/ 00484 00485 void StringVar::EnsureAlloc(UINT32 newlen) 00486 { 00487 // Note: length includes zero termination character 00488 if (length==0 || newlen > (length-1)) // length includes term 00489 { 00490 // We need to reallocate 00491 TCHAR* pOldText = text; 00492 text = NULL; 00493 00494 // Allocate room for the new string plus extra room to avoid repeated reallocation 00495 // And round to a 64 char boundary so that allocations slot together more efficiently. 00496 // And ensure that we always allocate >0 00497 // (Remember Alloc adds 1 character for the terminator so we subtract 1 from newlen) 00498 newlen = (newlen/64 + 1)*64 - 1; 00499 Alloc(newlen); 00500 00501 if (text!=NULL && pOldText!=NULL) 00502 camStrcpy(text, pOldText); 00503 } 00504 } 00505 00506 00507 #if !defined(EXCLUDE_FROM_XARLIB) 00508 /************************************************************************************** 00509 > void StringVar::MakePercent(INT32 Value); 00510 void StringVar::MakePercent(double Value); 00511 void StringVar::MakePercent(TCHAR* Value); 00512 00513 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00514 Created: 31st January 2006 00515 Inputs: Takes a number / string 00516 Purpose: Set the string equal to the given argument + a % character, or however 00517 the current locale wants it 00518 Example: String_32 Str; 00519 Str.MakePercent(23); 00520 For UK, Str now equals "23%" 00521 **************************************************************************************/ 00522 00523 void StringVar::MakePercent(INT32 Value) 00524 { 00525 EnsureAlloc(32); 00526 StringBase::MakePercent(Value); 00527 } 00528 00529 void StringVar::MakePercent(double Value) 00530 { 00531 EnsureAlloc(32); 00532 StringBase::MakePercent(Value); 00533 } 00534 00535 void StringVar::MakePercent(TCHAR* Value) 00536 { 00537 EnsureAlloc(32); 00538 StringBase::MakePercent(Value); 00539 } 00540 #endif 00541