2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 //need to rewrite this
30 #if GDEF_COMPILER_MSVC
31 #pragma warning(disable : 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
32 #pragma warning(disable : 4710) // function 'blah' not inlined
35 static const int STR_ALLOC_GRAN = 20;
37 // screwy but intentional
39 char *idStr::__tolower
58 // screwy but intentional
60 char *idStr::__toupper
94 // idStrings are equal until end point
99 if ( c1 >= 'a' && c1 <= 'z' ) {
103 if ( c2 >= 'a' && c2 <= 'z' ) {
111 else if ( c1 > c2 ) {
112 // strings greater than
137 if ( c1 >= 'a' && c1 <= 'z' ) {
141 if ( c2 >= 'a' && c2 <= 'z' ) {
149 else if ( c1 > c2 ) {
150 // strings greater than
176 // strings are equal until end point
184 else if ( c1 > c2 ) {
185 // strings greater than
212 else if ( c1 > c2 ) {
213 // strings greater than
227 Checks a string to see if it contains only numerical values.
230 bool idStr::isNumeric
244 for ( i = 0; i < len; i++ )
246 if ( !isdigit( str[ i ] ) ) {
247 if ( ( str[ i ] == '.' ) && !dot ) {
267 sprintf( text, "%f", b );
268 result.append( text );
282 sprintf( text, "%d", b );
283 result.append( text );
297 sprintf( text, "%u", b );
298 result.append( text );
303 idStr& idStr::operator+=
309 sprintf( text, "%f", a );
315 idStr& idStr::operator+=
321 sprintf( text, "%d", a );
327 idStr& idStr::operator+=
333 sprintf( text, "%u", a );
339 void idStr::CapLength
345 if ( length() <= newlen ) {
349 EnsureDataWritable();
351 m_data->data[newlen] = 0;
352 m_data->len = newlen;
355 void idStr::EnsureDataWritable
363 if ( !m_data->refcount ) {
370 m_data = new strdata;
372 EnsureAlloced( len + 1, false );
373 strncpy( m_data->data, olddata->data, len + 1 );
379 void idStr::EnsureAlloced( int amount, bool keepold ) {
382 m_data = new strdata();
385 // Now, let's make sure it's writable
386 EnsureDataWritable();
389 bool wasalloced = ( m_data->alloced != 0 );
391 if ( amount < m_data->alloced ) {
401 mod = amount % STR_ALLOC_GRAN;
406 newsize = amount + STR_ALLOC_GRAN - mod;
408 m_data->alloced = newsize;
411 newbuffer = new char[m_data->alloced];
412 if ( wasalloced && keepold ) {
413 strcpy( newbuffer, m_data->data );
416 if ( m_data->data ) {
417 delete [] m_data->data;
419 m_data->data = newbuffer;
422 void idStr::BackSlashesToSlashes
428 EnsureDataWritable();
430 for ( i = 0; i < m_data->len; i++ )
432 if ( m_data->data[i] == '\\' ) {
433 m_data->data[i] = '/';
445 char buffer[0x10000];
449 va_start( argptr,fmt );
450 len = vsprintf( buffer,fmt,argptr );
453 assert( len < size );
455 strncpy( dst, buffer, size - 1 );
458 #if GDEF_COMPILER_MSVC
459 #pragma warning(disable : 4189) // local variable is initialized but not referenced
466 This is a fairly rigorous test of the idStr class's functionality.
467 Because of the fairly global and subtle ramifications of a bug occuring
468 in this class, it should be run after any changes to the class.
469 Add more tests as functionality is changed. Tests should include
470 any possible bounds violation and NULL data tests.
480 idStr a; // a.len == 0, a.data == "\0"
481 idStr b; // b.len == 0, b.data == "\0"
482 idStr c( "test" ); // c.len == 4, c.data == "test\0"
483 idStr d( c ); // d.len == 4, d.data == "test\0"
484 idStr e( static_cast<const char *>( NULL ) );
485 // e.len == 0, e.data == "\0" ASSERT!
489 i = a.length(); // i == 0
490 i = c.length(); // i == 4
492 t = new idStr(); // t->len == 0, t->data == "\0"
495 b = "test"; // b.len == 4, b.data == "test\0"
496 t = new idStr( "test" ); // t->len == 4, t->data == "test\0"
499 a = c; // a.len == 4, a.data == "test\0"
501 a = NULL; // a.len == 0, a.data == "\0" ASSERT!
502 a = c + d; // a.len == 8, a.data == "testtest\0"
503 a = c + "wow"; // a.len == 7, a.data == "testwow\0"
504 a = c + static_cast<const char *>( NULL );
505 // a.len == 4, a.data == "test\0" ASSERT!
506 a = "this" + d; // a.len == 8, a.data == "thistest\0"
507 a = static_cast<const char *>( NULL ) + d;
508 // a.len == 4, a.data == "test\0" ASSERT!
509 a += c; // a.len == 8, a.data == "testtest\0"
510 a += "wow"; // a.len == 11, a.data == "testtestwow\0"
511 a += static_cast<const char *>( NULL );
512 // a.len == 11, a.data == "testtestwow\0" ASSERT!
514 a = "test"; // a.len == 4, a.data == "test\0"
515 ch = a[ 0 ]; // ch == 't'
516 ch = a[ -1 ]; // ch == 0 ASSERT!
517 ch = a[ 1000 ]; // ch == 0 ASSERT!
518 ch = a[ 0 ]; // ch == 't'
519 ch = a[ 1 ]; // ch == 'e'
520 ch = a[ 2 ]; // ch == 's'
521 ch = a[ 3 ]; // ch == 't'
522 ch = a[ 4 ]; // ch == '\0' ASSERT!
523 ch = a[ 5 ]; // ch == '\0' ASSERT!
525 a[ 1 ] = 'b'; // a.len == 4, a.data == "tbst\0"
526 a[ -1 ] = 'b'; // a.len == 4, a.data == "tbst\0" ASSERT!
527 a[ 0 ] = '0'; // a.len == 4, a.data == "0bst\0"
528 a[ 1 ] = '1'; // a.len == 4, a.data == "01st\0"
529 a[ 2 ] = '2'; // a.len == 4, a.data == "012t\0"
530 a[ 3 ] = '3'; // a.len == 4, a.data == "0123\0"
531 a[ 4 ] = '4'; // a.len == 4, a.data == "0123\0" ASSERT!
532 a[ 5 ] = '5'; // a.len == 4, a.data == "0123\0" ASSERT!
533 a[ 7 ] = '7'; // a.len == 4, a.data == "0123\0" ASSERT!
535 a = "test"; // a.len == 4, a.data == "test\0"
536 b = "no"; // b.len == 2, b.data == "no\0"
538 i = ( a == b ); // i == 0
539 i = ( a == c ); // i == 1
541 i = ( a == "blow" ); // i == 0
542 i = ( a == "test" ); // i == 1
543 i = ( a == NULL ); // i == 0 ASSERT!
545 i = ( "test" == b ); // i == 0
546 i = ( "test" == a ); // i == 1
547 i = ( NULL == a ); // i == 0 ASSERT!
549 i = ( a != b ); // i == 1
550 i = ( a != c ); // i == 0
552 i = ( a != "blow" ); // i == 1
553 i = ( a != "test" ); // i == 0
554 i = ( a != NULL ); // i == 1 ASSERT!
556 i = ( "test" != b ); // i == 1
557 i = ( "test" != a ); // i == 0
558 i = ( NULL != a ); // i == 1 ASSERT!
560 a = "test"; // a.data == "test"
561 b = a; // b.data == "test"
563 a = "not"; // a.data == "not", b.data == "test"
565 a = b; // a.data == b.data == "test"
567 a += b; // a.data == "testtest", b.data = "test"
571 a[1] = '1'; // a.data = "t1st", b.data = "test"
574 #if GDEF_COMPILER_MSVC
575 #pragma warning(default : 4189) // local variable is initialized but not referenced
576 #pragma warning(disable : 4514) // unreferenced inline function has been removed