2 Copyright (C) 1999-2007 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
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
60 // screwy but intentional
62 char *idStr::__toupper
101 // idStrings are equal until end point
107 if ( c1 >= 'a' && c1 <= 'z' )
112 if ( c2 >= 'a' && c2 <= 'z' )
124 // strings greater than
152 if ( c1 >= 'a' && c1 <= 'z' )
157 if ( c2 >= 'a' && c2 <= 'z' )
169 // strings greater than
198 // strings are equal until end point
209 // strings greater than
241 // strings greater than
255 Checks a string to see if it contains only numerical values.
258 bool idStr::isNumeric
275 for( i = 0; i < len; i++ )
277 if ( !isdigit( str[ i ] ) )
279 if ( ( str[ i ] == '.' ) && !dot )
302 sprintf( text, "%f", b );
303 result.append( text );
319 sprintf( text, "%d", b );
320 result.append( text );
336 sprintf( text, "%u", b );
337 result.append( text );
342 idStr& idStr::operator+=
350 sprintf( text, "%f", a );
356 idStr& idStr::operator+=
364 sprintf( text, "%d", a );
370 idStr& idStr::operator+=
378 sprintf( text, "%u", a );
384 void idStr::CapLength
392 if ( length() <= newlen )
395 EnsureDataWritable ();
397 m_data->data[newlen] = 0;
398 m_data->len = newlen;
401 void idStr::EnsureDataWritable
411 if ( !m_data->refcount )
417 m_data = new strdata;
419 EnsureAlloced ( len + 1, false );
420 strncpy ( m_data->data, olddata->data, len+1 );
426 void idStr::EnsureAlloced (int amount, bool keepold) {
429 m_data = new strdata();
432 // Now, let's make sure it's writable
433 EnsureDataWritable ();
436 bool wasalloced = ( m_data->alloced != 0 );
438 if ( amount < m_data->alloced ) {
447 mod = amount % STR_ALLOC_GRAN;
451 newsize = amount + STR_ALLOC_GRAN - mod;
453 m_data->alloced = newsize;
456 newbuffer = new char[m_data->alloced];
457 if ( wasalloced && keepold ) {
458 strcpy ( newbuffer, m_data->data );
461 if ( m_data->data ) {
462 delete [] m_data->data;
464 m_data->data = newbuffer;
467 void idStr::BackSlashesToSlashes
475 EnsureDataWritable ();
477 for ( i=0; i < m_data->len; i++ )
479 if ( m_data->data[i] == '\\' )
480 m_data->data[i] = '/';
493 char buffer[0x10000];
497 va_start (argptr,fmt);
498 len = vsprintf (buffer,fmt,argptr);
501 assert ( len < size );
503 strncpy (dst, buffer, size-1);
507 #pragma warning(disable : 4189) // local variable is initialized but not referenced
514 This is a fairly rigorous test of the idStr class's functionality.
515 Because of the fairly global and subtle ramifications of a bug occuring
516 in this class, it should be run after any changes to the class.
517 Add more tests as functionality is changed. Tests should include
518 any possible bounds violation and NULL data tests.
529 idStr a; // a.len == 0, a.data == "\0"
530 idStr b; // b.len == 0, b.data == "\0"
531 idStr c( "test" ); // c.len == 4, c.data == "test\0"
532 idStr d( c ); // d.len == 4, d.data == "test\0"
533 idStr e( reinterpret_cast<const char *>(NULL) );
534 // e.len == 0, e.data == "\0" ASSERT!
537 i = a.length(); // i == 0
538 i = c.length(); // i == 4
540 const char *s1 = a.c_str(); // s1 == "\0"
541 const char *s2 = c.c_str(); // s2 == "test\0"
543 t = new idStr(); // t->len == 0, t->data == "\0"
546 b = "test"; // b.len == 4, b.data == "test\0"
547 t = new idStr( "test" ); // t->len == 4, t->data == "test\0"
550 a = c; // a.len == 4, a.data == "test\0"
552 a = NULL; // a.len == 0, a.data == "\0" ASSERT!
553 a = c + d; // a.len == 8, a.data == "testtest\0"
554 a = c + "wow"; // a.len == 7, a.data == "testwow\0"
555 a = c + reinterpret_cast<const char *>(NULL);
556 // a.len == 4, a.data == "test\0" ASSERT!
557 a = "this" + d; // a.len == 8, a.data == "thistest\0"
558 a = reinterpret_cast<const char *>(NULL) + d;
559 // a.len == 4, a.data == "test\0" ASSERT!
560 a += c; // a.len == 8, a.data == "testtest\0"
561 a += "wow"; // a.len == 11, a.data == "testtestwow\0"
562 a += reinterpret_cast<const char *>(NULL);
563 // a.len == 11, a.data == "testtestwow\0" ASSERT!
565 a = "test"; // a.len == 4, a.data == "test\0"
566 ch = a[ 0 ]; // ch == 't'
567 ch = a[ -1 ]; // ch == 0 ASSERT!
568 ch = a[ 1000 ]; // ch == 0 ASSERT!
569 ch = a[ 0 ]; // ch == 't'
570 ch = a[ 1 ]; // ch == 'e'
571 ch = a[ 2 ]; // ch == 's'
572 ch = a[ 3 ]; // ch == 't'
573 ch = a[ 4 ]; // ch == '\0' ASSERT!
574 ch = a[ 5 ]; // ch == '\0' ASSERT!
576 a[ 1 ] = 'b'; // a.len == 4, a.data == "tbst\0"
577 a[ -1 ] = 'b'; // a.len == 4, a.data == "tbst\0" ASSERT!
578 a[ 0 ] = '0'; // a.len == 4, a.data == "0bst\0"
579 a[ 1 ] = '1'; // a.len == 4, a.data == "01st\0"
580 a[ 2 ] = '2'; // a.len == 4, a.data == "012t\0"
581 a[ 3 ] = '3'; // a.len == 4, a.data == "0123\0"
582 a[ 4 ] = '4'; // a.len == 4, a.data == "0123\0" ASSERT!
583 a[ 5 ] = '5'; // a.len == 4, a.data == "0123\0" ASSERT!
584 a[ 7 ] = '7'; // a.len == 4, a.data == "0123\0" ASSERT!
586 a = "test"; // a.len == 4, a.data == "test\0"
587 b = "no"; // b.len == 2, b.data == "no\0"
589 i = ( a == b ); // i == 0
590 i = ( a == c ); // i == 1
592 i = ( a == "blow" ); // i == 0
593 i = ( a == "test" ); // i == 1
594 i = ( a == NULL ); // i == 0 ASSERT!
596 i = ( "test" == b ); // i == 0
597 i = ( "test" == a ); // i == 1
598 i = ( NULL == a ); // i == 0 ASSERT!
600 i = ( a != b ); // i == 1
601 i = ( a != c ); // i == 0
603 i = ( a != "blow" ); // i == 1
604 i = ( a != "test" ); // i == 0
605 i = ( a != NULL ); // i == 1 ASSERT!
607 i = ( "test" != b ); // i == 1
608 i = ( "test" != a ); // i == 0
609 i = ( NULL != a ); // i == 1 ASSERT!
611 a = "test"; // a.data == "test"
612 b = a; // b.data == "test"
614 a = "not"; // a.data == "not", b.data == "test"
616 a = b; // a.data == b.data == "test"
618 a += b; // a.data == "testtest", b.data = "test"
622 a[1] = '1'; // a.data = "t1st", b.data = "test"
626 #pragma warning(default : 4189) // local variable is initialized but not referenced
627 #pragma warning(disable : 4514) // unreferenced inline function has been removed