2 * Amiga Generic Set - set of libraries and includes to ease sw development for all Amiga platforms
3 * Copyright (C) 2001-2011 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "LibrarySpool.h"
22 #include <libclass/exec.h>
23 #include <libclass/dos.h>
24 #include <libclass/utility.h>
25 #include <LibC/LibC.h>
28 using namespace GenNS
;
31 static unsigned long ___vFormatFunc
[] =
32 { 0x16c04e75, 0x4e754e75 };
46 lLength
= strlen((const char*)sContents
);
49 void String::SetLength(unsigned long lLen
)
68 String::String(const char* s
)
76 String::String(const String
&s
)
90 const char* String::Data(void) const
92 if (!sContents
) return "";
93 return (char*)sContents
;
96 void String::Clone(const char* sSrc
, unsigned int lLen
)
98 if (lLen
>= lMaxLen
) // not enough space?
99 AllocBuf(lLen
+ 1); // make enough.
100 if (lLen
>= lMaxLen
) // failed?
101 return; // return immediately.
102 if (lLen
> 0) // if there is something to copy,
103 memcpy(sContents
, sSrc
, lLen
); // literally CLONE memory
104 lLength
= lLen
; // update length ;)
105 sContents
[lLen
] = 0; // pad with zeros.
108 void String::Assign(const char *s
)
110 // VPrintf("Assigning %s (%lx)\n", ARRAY((int)s));
111 if (0 == s
) // string not passed?
112 Clone(0, 0); // create an empty string (NO REALLOC)
114 Clone(s
, strlen(s
)); // clone what we have.
115 // VPrintf("Assigned %s (%lx)\n", ARRAY((int)sContents));
118 void String::Assign(const String
*s
)
120 if (0 == s
) // if no string has been passed
121 Clone(0, 0); // create empty one
123 Clone(s
->Data(), s
->Length()); // use what we have.
126 int String::Length() const
128 return lLength
; // this one is easy.
131 String::operator char*(void) const
133 return (char *)Data(); // this one is easy, too
136 String::operator unsigned char*(void) const
138 return (unsigned char*)Data(); // humm
141 String
&String::operator = (const String
& sStr
)
143 Assign(const_cast<String
*>(&sStr
)); // okay...
147 String
&String::operator = (const int64 sVal
)
149 if ((sVal
& 0xffffffff) == sVal
)
151 FormatStr("%ld", ARRAY(sVal
)); // aint hard i guess..
155 FormatStr("0x%lx%08lx", ARRAY((sVal
>> 32) & 0xffffffff, sVal
& 0xffffffff));
157 return *this; // is it..
160 int String::operator < (const String sStr
) const
162 return 0 > strncmp(Data(), sStr
.Data(), Length()); // humm..
165 int String::operator == (const String sStr
) const
167 return 0 == strncmp(Data(), sStr
.Data(), Length()); // humm..
170 int String::operator < (const char* sStr
) const
172 return 0 > strncmp(Data(), sStr
, Length()); // compare only what we are aware of.
175 int String::operator == (const char* sStr
) const
177 return 0 == strncmp(Data(), sStr
, Length()); // compare only what we are aware of.
180 int String::FormatStr(const char *sFmtStr
, void*pParams
)
182 char *temp
= new char[65535];
184 #if defined(__amiga__) & defined(mc68000)
185 Exec
->RawDoFmt(sFmtStr
, pParams
, &___vFormatFunc
, temp
);
186 #elif defined(__AMIGAOS4__)
187 Exec
->RawDoFmt(sFmtStr
, pParams
, 0, temp
);
188 //VSNPrintf((uint8*)temp, 65535, (uint8*)sFmtStr, pParams);
189 #elif !defined(__LINUX__)
190 Exec
->RawDoFmt(sFmtStr
, pParams
, 0, temp
);
192 vsprintf(temp
, sFmtStr
, (va_list)pParams
);
199 void String::AddPath(const char* sElement
)
201 if ((strlen(sElement
) + lLength
) >= (lMaxLen
-4)) // if you need,
202 ReallocBuf(strlen(sElement
) + lLength
+ 5); // get more mem
203 if ((strlen(sElement
) + lLength
) >= (lMaxLen
-4)) // if we failed
205 DOS
->AddPart((char*)sContents
, sElement
, lMaxLen
); // otherwise update
209 void String::AllocBuf(unsigned int lSize
)
213 if (lSize
<= lMaxLen
) // dont care if we dont have to
216 sOld
= sContents
; // backup old stuff.
217 sContents
= new unsigned char[lSize
+1];
219 if (0 != sContents
) // if everything went smooth
223 lMaxLen
= lSize
+ 1; // and update the size.
227 request("Low memory error", "Unable to allocate %ld bytes of memory", "Continue", ARRAY(lSize
));
228 sContents
= sOld
; // revert changes,
230 sContents
[0] = 0; // also update the length
231 lLength
= 0; // etc...
234 void String::ReallocBuf(unsigned int lSize
)
238 if (lSize
<= lMaxLen
) // dont care if we dont have to
241 sOld
= sContents
; // backup old stuff.
242 sContents
= new unsigned char[lSize
+ 1]; // get fresh piece of mem :P
244 if (0 != sContents
) // if everything went smooth
248 memcpy(sContents
, sOld
, lLength
);// copy the whole old block of memory :)
255 lMaxLen
= lSize
+ 1; // and update the size.
259 request("Low memory error", "Unable to allocate %ld bytes of memory", "Continue", ARRAY(lSize
));
260 sContents
= sOld
; // revert changes,
262 sContents
[lLength
] = 0; // make sure no garbage follows.
265 String
String::operator + (const char *sStr
)
267 String
s(*this); // this should be easy
268 s
+= sStr
; // i hope..
272 String
String::operator + (const String
& sStr
)
274 String
s(*this); // same here.
275 s
+= sStr
.Data(); // hope i dont screw up
276 return s
; // or else bad things may happen
279 String
&String::operator += (const char *sStr
)
281 if ((strlen(sStr
)+lLength
) >= lMaxLen
) // if you need
282 ReallocBuf(strlen(sStr
)+lLength
+1); // get more mem
283 if ((strlen(sStr
)+lLength
) >= lMaxLen
) // if you fail
284 return *this; // do not proceed.
286 strncat((char*)sContents
, sStr
, lMaxLen
); // update as much as we can take.
291 String
&String::operator += (const char cChar
)
293 if ((1+lLength
) >= lMaxLen
) // if you need
294 ReallocBuf(lLength
+16); // get more mem
295 if ((1+lLength
) >= lMaxLen
) // if you fail
296 return *this; // do not proceed.
298 sContents
[lLength
++] = cChar
;
299 sContents
[lLength
] = 0;
304 unsigned long String::TrimChars(const char* sChars
)
307 int lNewEnd
= Length();
311 for (lInPos
= 0; sChars
[lInPos
]; ++lInPos
)
313 if (sContents
[lNewStart
] == sChars
[lInPos
])
316 if (lNewStart
>= lNewEnd
)
322 for (lInPos
= 0; sChars
[lInPos
]; ++lInPos
)
324 if (sContents
[lNewEnd
-1] == sChars
[lInPos
])
329 sContents
[lNewEnd
] = 0;
334 String
sTemp((char*)&sContents
[lNewStart
]);
339 char &String::operator [] (int lOffset
)
341 ASSERT(lOffset
>= 0);
342 ASSERT(lOffset
<= (int)lMaxLen
);
343 return (char&)sContents
[lOffset
];
346 String
String::SubString(int lFirst
, int lLen
)
353 lLen
= Length() - lFirst
;
357 for (pos
=0; pos
<lLen
; pos
++)
359 if (!sContents
[lFirst
+pos
])
361 s
[pos
] = sContents
[lFirst
+pos
];
368 String
String::LeftString(int lLen
)
370 return SubString(0, lLen
);
373 String
String::RightString(int lLen
)
375 return SubString (Length()-lLen
, lLen
);
378 bool String::Equals(const char* sOther
)
380 return (0 == strcmp((char*)sContents
, sOther
));
383 bool String::EqualsIgnoreCase(const char* sOther
)
385 return (0 == stricmp((char*)sContents
, sOther
));
388 int String::Compare(const char* sOther
) const
390 return (strcmp((char*)sContents
, sOther
));
393 int String::CompareIgnoreCase(const char* sOther
) const
395 return (stricmp((char*)sContents
, sOther
));
398 int32
String::ToLong()
412 for (unsigned int i
=0; sContents
[i
]; i
++)
417 if ((lValue
== 0) && (i
== 1))
430 if ((c
< '0') || (c
> '9'))
436 if ((c
< '0') || (c
> '1'))
442 if ((c
< '0') || (c
> '7'))
448 if (((c
< '0') || (c
> '9')) &&
449 ((c
< 'a') || (c
> 'f')) &&
450 ((c
< 'A') || (c
> 'F')))
468 int64
String::ToQuad()
482 for (unsigned int i
=0; sContents
[i
]; i
++)
487 if ((lValue
== 0) && (i
== 1))
500 if ((c
< '0') || (c
> '9'))
506 if ((c
< '0') || (c
> '1'))
512 if ((c
< '0') || (c
> '7'))
518 if (((c
< '0') || (c
> '9')) &&
519 ((c
< 'a') || (c
> 'f')) &&
520 ((c
< 'A') || (c
> 'F')))
538 void String::StrLCpy(const char* sSrc
, int lNum
)
540 if (lNum
>= (int)lMaxLen
)
547 for (i
=0; 0 != sSrc
[i
]; ++i
) // while we have sth to copy
549 if (i
>= lNum
) // that will be tough. STOP ASAP
551 sContents
[i
] = sSrc
[i
]; // copy while we have sth to copy
555 while (i
< (int)lMaxLen
) // ERASE TO THE END
564 void String::BstrCpy(BSTR src
)
567 StrLCpy(&((char*)((int)src
<<2))[1], ((char*)((int)src
<<2))[0]);
573 String
&String::Substitute(const char* src
, const char* dst
)
575 int32 sl
= strlen(src
);
578 char *d
= new char[l
];
580 for (i
=0; sContents
[i
] != 0;)
582 if (sContents
[i
] == src
[0])
584 if (strncmp((char*)&sContents
[i
], src
, sl
) == 0)
586 for (int j
=0; dst
[j
] != 0; j
++)
591 char *sd
= new char[l
<<1];
602 d
[p
++] = sContents
[i
++];
605 char *sd
= new char[l
<<1];
619 String
&String::ToUTF8()
621 char *d
= new char[(Length()<<1)+1];
624 for (int i
=0; ((sContents
[i
] != 0) && (i
<Length())); i
++)
626 if (((uint8
)sContents
[i
]) < 0x80)
628 d
[j
++] = sContents
[i
];
632 d
[j
++] = 0xc0+(sContents
[i
] >> 6 & 3);
633 d
[j
++] = 0x80+(sContents
[i
] & 0x3f);
644 String
&String::FromUTF8()
646 char *d
= new char[Length()+1];
649 for (int i
=0; ((sContents
[i
] != 0) && (i
<Length())); i
++)
651 if (((uint8
)sContents
[i
]) < 0x80)
653 d
[j
++] = sContents
[i
];
655 else if (((uint8
)sContents
[i
]) <0xdf)
657 d
[j
] = (sContents
[i
++] & 3) << 6;
658 d
[j
++] |= (sContents
[i
] & 0x3f);
673 // static functions & stuff...
675 void String::strcat(char* pDst, const char* pSrc)
686 void String::strncat(char* pDst, const char* pSrc, long lLen)
688 if (0 == pDst) // no stirng?
692 ++pDst; // find end of string
693 --lLen; // and reduce amount of bytes we can take
694 if (0 >= lLen) // if we reached our bottom limit
697 strncpy(pDst, pSrc, lLen); // copy the remaining bytes.
700 VectorT
<String
> String::Explode()
708 for (s
= 0; s
<Length();)
710 register unsigned char c
= 0;
713 * skip spaces, tabs, hard spaces
726 * ignore end of line etc
728 if ((s
== Length()) || (c
== 10) || (c
== 13) || (c
== 0))
736 while ((s
+e
) < Length())
739 if ((c
== 10) || (c
== 13) || (c
== '"') || (c
== 0))
745 vec
<< SubString(s
, e
);
751 while ((s
+e
) < Length())
754 if ((c
== 10) || (c
== 13) || (c
== ' ') || (c
== '\t') || (c
== 160) || (c
== 0))
758 vec
<< SubString(s
, e
);
767 String
&String::UpperCase()
769 ASSERT(Utility
!= 0);
770 for (int i
=0; i
<Length(); i
++)
772 sContents
[i
] = Utility
->ToUpper(sContents
[i
]);
778 String
&String::LowerCase()
780 ASSERT(Utility
!= 0);
781 for (int i
=0; i
<Length(); i
++)
783 sContents
[i
] = Utility
->ToLower(sContents
[i
]);
791 String
GenNS::operator + (const char *sStr1
, const String sStr2
)