1 /**************************************************************************
2 ** (c) Copyright 1997, Andromeda Technology & Automation
3 ***************************************************************************
4 ** MODULE INFORMATION *
5 ***********************
6 ** FILE NAME : string.cpp
7 ** SYSTEM NAME : Andromeda X-Windows Encapsulation
8 ** VERSION NUMBER : $Revision: 1.3 $
10 ** DESCRIPTION : String class implementation.
15 ***************************************************************************
16 ** ADMINISTRATIVE INFORMATION *
17 ********************************
18 ** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
19 ** CREATION DATE : Nov 17, 1997
20 ** LAST UPDATE : Nov 03, 2002
22 **************************************************************************/
24 /*****************************
26 Revision 1.3 2002-11-03 13:18:57 arjen
27 New functions - String::escape() and String::unescape()
29 Revision 1.2 2002/09/28 06:42:11 arjen
30 A few small bug fixes.
32 Revision 1.1 2002/07/25 08:01:27 arjen
33 First checkin, AXE release 0.2
35 *****************************/
37 static const char RCSID[] = "$Id: string.cpp,v 1.3 2002-11-03 13:18:57 arjen Exp $";
43 // Constructors and destructors for the String class
45 String::String() // Create an empty String
52 String::String(char c) // Create a String from a char
61 String::String(const char *s) // Create a String from a char *
64 p->s = new char[strlen(s)+1];
69 String::String(const String& x) // Create a String from another String
75 String::String(const substring &x)
79 p->s = new char[x.len+1];
80 strncpy(p->s, x.str->p->s+x.start, x.len);
81 p->s[x.len] = '\0'; // strncpy does not add the \0
95 * Assignment operators must handle cleanup of their left-hand operand.
98 String& String::operator=(const char c)
115 String& String::operator=(const char *s)
125 p->s = new char[strlen(s)+1];
131 /* Make sure that assignment of an object to itself works correctly: */
133 String& String::operator=(const String& x)
146 /* Numerical conversion */
148 String::String(int i)
151 p->s = new char[15]; // A little longer than needed...
152 sprintf(p->s, "%d", i);
156 String::String(long i)
159 p->s = new char[15]; // A little longer than needed...
160 sprintf(p->s, "%ld", i);
164 String::String(unsigned long i)
167 p->s = new char[15]; // A little longer than needed...
168 sprintf(p->s, "%lu", i);
172 String::String(double d)
175 p->s = new char[25]; // A little longer than needed...
176 sprintf(p->s, "%.3f", d);
180 /* String concatenation */
182 String& String::operator+=(const String& x)
184 char *s = new char[strlen(p->s) + strlen(x.p->s) + 1];
202 String& String::operator+=(const char * str)
204 char *s = new char[strlen(p->s) + strlen(str) + 1];
222 String operator+(const String& x, const String& y)
230 String operator+(const String& x, const char * y)
238 String operator+(const char * x, const String& y)
246 /* Shift operators */
249 String operator<<(const String &x, int n)
257 String & String::operator<<=(int n)
259 // Make sure we are the only one being shifted.
263 char *s = new char[strlen(p->s) + 1];
272 // Shift left means we really have to copy all characters.
274 int len = strlen(p->s);
279 // Shift more than we have: the String becomes empty.
284 for (i = 0; i <= len - n; i++)
293 String operator>>(const String &x, int n)
301 String & String::operator>>=(int n)
303 // Make sure we are the only one being shifted.
307 char *s = new char[strlen(p->s) + 1];
316 // Shift right is simple: just put the '\0' n places back.
319 int len = strlen(p->s);
323 // Shift more than we have: the String becomes empty.
328 p->s[len - n] = '\0';
334 /* Substring selection and assignment */
336 substring String::operator()(int start, int len)
346 String& substring::operator=(const String &x)
348 char *s = new char[strlen(x.p->s) + ~*str - len + 1];
350 strncpy(s, str->p->s, start);
353 strcat(s, str->p->s+start+len);
358 /* Input and output */
360 std::ostream& operator<<(std::ostream& s, const String& x)
367 std::istream& operator>>(std::istream& s, String& x)
378 while (s && buf[i] != '\n');
388 * The subscript operator is provided for access to individual characters
391 char& String::operator[](int i)
396 String String::upper()
401 up.p->s = new char[strlen(p->s)+1];
403 for(i=0; p->s[i]; i++)
405 up.p->s[i] = toupper(p->s[i]);
412 String String::lower()
417 low.p->s = new char[strlen(p->s)+1];
419 for(i=0; p->s[i]; i++)
421 low.p->s[i] = tolower(p->s[i]);
428 String String::escape()
430 const int BUFSIZE = 500;
432 char buffer[BUFSIZE];
434 int i; // Index in buffer[]
435 int j; // Index in *this
438 for (j = 0; p->s[j] != '\0'; j++)
499 if (p->s[j] > '\x20' && p->s[j] < '\x7F')
501 buffer[i++] = p->s[j];
507 // Turn into hexadecimal representation
511 nibble = (p->s[j] >> 4) & 0x0f;
512 buffer[i++] = nibble < 10 ? nibble + '0' : nibble - 10 + 'A';
513 nibble = p->s[j] & 0x0f;
514 buffer[i++] = nibble < 10 ? nibble + '0' : nibble - 10 + 'A';
526 String String::unescape()
531 unescaped.p->s = new char[strlen(p->s)+1];
592 while (*s >= '0' && *s <= '7')
603 s++; // Skip the initial 'x'
607 *d += *s > '9' ? toupper(*s) - 'A' + 10 : *s - '0';
630 // Find the first occurance of 'c'
632 int String::index(char c)
636 found = strchr(p->s, c);
643 // Find the last occurance of 'c'
645 int String::rindex(char c)
649 found = strrchr(p->s, c);
656 /* In: see if I am part of x, return -1 if not found */
658 int String::in(String & x)
662 match = strstr(x.p->s, p->s);
664 return match - x.p->s;