]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/Utils/common/Collections.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / Utils / common / Collections.cpp
1 //####COPYRIGHTBEGIN####
2 //                                                                          
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
8 // This program is free software; you can redistribute it and/or modify it 
9 // under the terms of the GNU General Public License as published by the Free 
10 // Software Foundation; either version 2 of the License, or (at your option) 
11 // any later version.
12 // 
13 // This program is distributed in the hope that it will be useful, but WITHOUT 
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
15 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
16 // more details.
17 // 
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc., 
20 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 //
22 // ----------------------------------------------------------------------------
23 //                                                                          
24 //####COPYRIGHTEND####
25
26 // include winsock2.h early to eliminate fd_set warning
27 #ifdef __CYGWIN__
28 #include <winsock2.h>
29 #endif
30
31 #include "Collections.h"
32
33 void String::Format (LPCTSTR  const pszFormat,...)
34 {
35   va_list args;
36   va_start(args, pszFormat);
37   vFormat(pszFormat,args);
38   va_end(args);
39 }
40
41 String String::SFormat (LPCTSTR  const pszFormat,...)
42 {
43   String s;
44   va_list args;
45   va_start(args, pszFormat);
46   s.vFormat(pszFormat,args);
47   va_end(args);
48   return s;
49 }
50
51 void String::vFormat(LPCTSTR  pszFormat, va_list marker)
52 {
53   for(int nLength=100;nLength;) {
54     TCHAR *buf=new TCHAR[1+nLength];
55     int n=_vsntprintf(buf, nLength, pszFormat, marker ); 
56     if(-1==n){
57       nLength*=2;  // NT behavior
58     } else if (n<nLength){
59       string::operator=(buf);
60       nLength=0;   // trigger exit from loop
61     } else {
62       nLength=n+1; // UNIX behavior generally, or NT behavior when buffer size exactly matches required length
63     }
64     delete [] buf;
65   }
66 }
67
68 TCHAR * String::GetBuffer(unsigned int nLength)
69 {
70   assert(NULL==m_pszBuf);
71   nLength=MAX(nLength,size()); // to accommodate _tcscpy below
72   m_pszBuf=new TCHAR[1+nLength];
73   m_nBufferLength=nLength;
74   _tcscpy(m_pszBuf,c_str());
75   return m_pszBuf;
76 }
77
78 void String::ReleaseBuffer()
79 {
80   assert(m_pszBuf);
81   m_pszBuf[m_nBufferLength]=_TCHAR('\0'); // just in case the terminating null has been forgotten
82   string::operator=(m_pszBuf);
83   delete [] m_pszBuf;
84   m_pszBuf=0;
85 }
86
87 String String::CStrToUnicodeStr(const char *psz)
88 {
89   String str;
90 #ifdef _UNICODE
91   int nLength=1+strlen(psz);
92   MultiByteToWideChar(CP_ACP, 0, psz, -1, str.GetBuffer(nLength), nLength);
93   str.ReleaseBuffer();
94 #else
95   str=psz;
96 #endif
97   return str;
98 }
99
100 int String::Chop(StringArray &ar,TCHAR cSep,bool bObserveStrings/*=TRUE*/) const
101 {
102   assert('\0'!=cSep);
103 #define IsSep(c) (cSep==_TCHAR(' ')?_istspace(c):c==cSep)
104   LPCTSTR c=c_str();
105   ar.clear();
106   while(*c){
107     // Spaces are slightly different from other separators - we treat multiple instances as
108     // just one (a la sscanf)
109     if(_istspace(cSep)){
110       while(IsSep(*c))c++;
111     } else if (ar.size()>0) {
112       c++;
113     }
114     if(*c){
115       String strTok;
116       if(bObserveStrings){
117         bool bInString=false;
118         do{
119           if(*c==_TCHAR('\\') && c[1]){
120             strTok+=c[1];
121             c++;
122           } else if(*c==_TCHAR('"')){
123             bInString ^= 1;
124           } else if (!bInString && IsSep(*c)) {
125             break;
126           } else {
127             strTok+=*c;
128           }
129         } while (*++c);
130       } else {
131         do {
132           if(IsSep(*c)) {
133             break;
134           } else {
135             strTok+=*c;
136           }
137         } while (*++c);
138       }
139       ar.push_back(strTok);
140     }
141   }
142   return ar.size();
143 }
144
145 char * String::GetCString() const
146 {
147   char *psz=new char[1+size()];
148 #ifdef _UNICODE
149   WideCharToMultiByte(CP_ACP, 0, c_str(), -1, psz, 1+size(), NULL, NULL);
150 #else
151   strcpy(psz,c_str());
152 #endif
153   return psz;
154 }
155
156 void String::Replace(LPCTSTR psz1, LPCTSTR psz2, bool bObserveEscapes)
157 {
158   for(unsigned int nOffset=0;nOffset<size();){
159     LPCTSTR psz=c_str()+nOffset;
160     const TCHAR *pc=_tcsstr(psz,psz1);
161     if(pc){
162       if(bObserveEscapes && pc>psz && _TCHAR('\\')==pc[-1]){
163         // Substitution protected by escape
164         nOffset=(pc-psz)+_tcslen(psz1);
165       } else {
166         String strNew(psz,pc-psz); // before the substitution
167         strNew+=psz2;              // substitution text
168         pc+=_tcslen(psz1);         // past the substituted text
169         strNew+=pc;                // after the substitution
170         string::operator=(strNew);
171         nOffset=(pc-psz)+_tcslen(psz2);
172       }
173     } else {
174       break;
175     }
176   }
177 }