]>
git.saurik.com Git - apt.git/blob - apt-pkg/contrib/strutl.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: strutl.cc,v 1.4 1998/09/22 05:30:28 jgg Exp $
4 /* ######################################################################
6 String Util - Some usefull string functions.
8 strstrip - Remove whitespace from the front and end of a line.
10 This source is placed in the Public Domain, do with it what you will
11 It was originally written by Jason Gunthorpe <jgg@gpu.srv.ualberta.ca>
13 ##################################################################### */
22 // strstrip - Remove white space from the front and back of a string /*{{{*/
23 // ---------------------------------------------------------------------
24 /* This is handy to use when parsing a file. It also removes \n's left
25 over from fgets and company */
26 char *_strstrip(char *String
)
28 for (;*String
!= 0 && (*String
== ' ' || *String
== '\t'); String
++);
33 char *End
= String
+ strlen(String
) - 1;
34 for (;End
!= String
- 1 && (*End
== ' ' || *End
== '\t' || *End
== '\n' ||
35 *End
== '\r'); End
--);
41 // strtabexpand - Converts tabs into 8 spaces /*{{{*/
42 // ---------------------------------------------------------------------
44 char *_strtabexpand(char *String
,size_t Len
)
46 for (char *I
= String
; I
!= I
+ Len
&& *I
!= 0; I
++)
50 if (I
+ 8 > String
+ Len
)
56 /* Assume the start of the string is 0 and find the next 8 char
62 Len
= 8 - ((String
- I
) % 8);
70 memmove(I
+ Len
,I
+ 1,strlen(I
) + 1);
71 for (char *J
= I
; J
+ Len
!= I
; *I
= ' ', I
++);
76 // ParseQuoteWord - Parse a single word out of a string /*{{{*/
77 // ---------------------------------------------------------------------
78 /* This grabs a single word, converts any % escaped characters to their
79 proper values and advances the pointer. Double quotes are understood
80 and striped out as well. This is for URI/URL parsing. */
81 bool ParseQuoteWord(const char *&String
,string
&Res
)
83 // Skip leading whitespace
84 const char *C
= String
;
85 for (;*C
!= 0 && *C
== ' '; C
++);
89 // Jump to the next word
90 for (;*C
!= 0 && *C
!= ' '; C
++)
94 for (C
++;*C
!= 0 && *C
!= '"'; C
++);
100 // Now de-quote characters
103 const char *Start
= String
;
105 for (I
= Buffer
; I
< Buffer
+ sizeof(Buffer
) && Start
!= C
; I
++)
107 if (*Start
== '%' && Start
+ 2 < C
)
112 *I
= (char)strtol(Tmp
,0,16);
125 // Skip ending white space
126 for (;*C
!= 0 && *C
== ' '; C
++);
131 // ParseCWord - Parses a string like a C "" expression /*{{{*/
132 // ---------------------------------------------------------------------
133 /* This expects a series of space seperated strings enclosed in ""'s.
134 It concatenates the ""'s into a single string. */
135 bool ParseCWord(const char *String
,string
&Res
)
137 // Skip leading whitespace
138 const char *C
= String
;
139 for (;*C
!= 0 && *C
== ' '; C
++);
145 if (strlen(String
) >= sizeof(Buffer
))
152 for (C
++; *C
!= 0 && *C
!= '"'; C
++)
161 if (C
!= String
&& isspace(*C
) != 0 && isspace(C
[-1]) != 0)
163 if (isspace(*C
) == 0)
172 // QuoteString - Convert a string into quoted from /*{{{*/
173 // ---------------------------------------------------------------------
175 string
QuoteString(string Str
,const char *Bad
)
178 for (string::iterator I
= Str
.begin(); I
!= Str
.end(); I
++)
180 if (strchr(Bad
,*I
) != 0 || isprint(*I
) == 0 ||
181 *I
<= 0x20 || *I
>= 0x7F)
184 sprintf(Buf
,"%%%02x",(int)*I
);
193 // SizeToStr - Convert a long into a human readable size /*{{{*/
194 // ---------------------------------------------------------------------
195 /* A max of 4 digits are shown before conversion to the next highest unit. The
196 max length of the string will be 5 chars unless the size is > 10
198 string
SizeToStr(double Size
)
207 /* bytes, KiloBytes, MegaBytes, GigaBytes, TeraBytes, PetaBytes,
208 ExaBytes, ZettaBytes, YottaBytes */
209 char Ext
[] = {'b','k','M','G','T','P','E','Z','Y'};
213 if (ASize
< 100 && I
!= 0)
215 sprintf(S
,"%.1f%c",ASize
,Ext
[I
]);
221 sprintf(S
,"%.0f%c",ASize
,Ext
[I
]);
231 // TimeToStr - Convert the time into a string /*{{{*/
232 // ---------------------------------------------------------------------
233 /* Converts a number of seconds to a hms format */
234 string
TimeToStr(unsigned long Sec
)
242 sprintf(S
,"%lid %lih%lim%lis",Sec
/60/60/24,(Sec
/60/60) % 24,(Sec
/60) % 60,Sec
% 60);
248 sprintf(S
,"%lih%lim%lis",Sec
/60/60,(Sec
/60) % 60,Sec
% 60);
254 sprintf(S
,"%lim%lis",Sec
/60,Sec
% 60);
258 sprintf(S
,"%lis",Sec
);
265 // SubstVar - Substitute a string for another string /*{{{*/
266 // ---------------------------------------------------------------------
267 /* This replaces all occurances of Subst with Contents in Str. */
268 string
SubstVar(string Str
,string Subst
,string Contents
)
270 string::size_type Pos
= 0;
271 string::size_type OldPos
= 0;
274 while (OldPos
< Str
.length() &&
275 (Pos
= Str
.find(Subst
,OldPos
)) != string::npos
)
277 Temp
+= string(Str
,OldPos
,Pos
) + Contents
;
278 OldPos
= Pos
+ Subst
.length();
284 return Temp
+ string(Str
,OldPos
);
287 // URItoFileName - Convert the uri into a unique file name /*{{{*/
288 // ---------------------------------------------------------------------
289 /* This converts a URI into a safe filename. It quotes all unsafe characters
290 and converts / to _ and removes the scheme identifier. The resulting
291 file name should be unique and never occur again for a different file */
292 string
URItoFileName(string URI
)
294 string::const_iterator I
= URI
.begin() + URI
.find(':') + 1;
295 for (; I
< URI
.end() && *I
== '/'; I
++);
297 // "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
298 URI
= QuoteString(string(I
,URI
.end() - I
),"\\|{}[]<>\"^~_=!@#$%^&*");
299 string::iterator J
= URI
.begin();
300 for (; J
!= URI
.end(); J
++)
306 // Base64Encode - Base64 Encoding routine for short strings /*{{{*/
307 // ---------------------------------------------------------------------
308 /* This routine performs a base64 transformation on a string. It was ripped
309 from wget and then patched and bug fixed.
311 This spec can be found in rfc2045 */
312 string
Base64Encode(string S
)
315 static char tbl
[64] = {'A','B','C','D','E','F','G','H',
316 'I','J','K','L','M','N','O','P',
317 'Q','R','S','T','U','V','W','X',
318 'Y','Z','a','b','c','d','e','f',
319 'g','h','i','j','k','l','m','n',
320 'o','p','q','r','s','t','u','v',
321 'w','x','y','z','0','1','2','3',
322 '4','5','6','7','8','9','+','/'};
324 // Pre-allocate some space
326 Final
.reserve((4*S
.length() + 2)/3 + 2);
328 /* Transform the 3x8 bits to 4x6 bits, as required by
330 for (string::const_iterator I
= S
.begin(); I
< S
.end(); I
+= 3)
332 char Bits
[3] = {0,0,0};
339 Final
+= tbl
[Bits
[0] >> 2];
340 Final
+= tbl
[((Bits
[0] & 3) << 4) + (Bits
[1] >> 4)];
342 if (I
+ 1 >= S
.end())
345 Final
+= tbl
[((Bits
[1] & 0xf) << 2) + (Bits
[2] >> 6)];
347 if (I
+ 2 >= S
.end())
350 Final
+= tbl
[Bits
[2] & 0x3f];
353 /* Apply the padding elements, this tells how many bytes the remote
354 end should discard */
355 if (S
.length() % 3 == 2)
357 if (S
.length() % 3 == 1)
363 // stringcmp - Arbitary string compare /*{{{*/
364 // ---------------------------------------------------------------------
365 /* This safely compares two non-null terminated strings of arbitary
367 int stringcmp(const char *A
,const char *AEnd
,const char *B
,const char *BEnd
)
369 for (; A
!= AEnd
&& B
!= BEnd
; A
++, B
++)
373 if (A
== AEnd
&& B
== BEnd
)
384 // stringcasecmp - Arbitary case insensitive string compare /*{{{*/
385 // ---------------------------------------------------------------------
387 int stringcasecmp(const char *A
,const char *AEnd
,const char *B
,const char *BEnd
)
389 for (; A
!= AEnd
&& B
!= BEnd
; A
++, B
++)
390 if (toupper(*A
) != toupper(*B
))
393 if (A
== AEnd
&& B
== BEnd
)
399 if (toupper(*A
) < toupper(*B
))