// ------------------------------------------------------------------------------------------------ // MODULE : Chaine // LANGAGE : C++ // CREATEUR : Adolfo VIDE // DATE : Jeudi 15 Octobre 1992 // DESCRIPTION : // COMMENTAIRE : // SCCSID : @(#)b_string.cpp 1.1 11:49:56 18 Dec 1996 // ---------------------------------------------------------------------------- // Copyright (c) 1999 Digital Imaging Group, Inc. // For conditions of distribution and use, see copyright notice // in Flashpix.h // ---------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------ #include "b_string.h" // ------------------------------------------------------------------------------------------------ // Includes // -------- #include #include #include #include #ifdef macintosh #include "graphic.h" #endif // Constants // --------- // #define ESPACE "\p " // Variables // --------- char lpDecimalSeparator = '.'; char lpThousandSeparator = ','; // ------------------------------------------------------------------------------------------------ #ifdef macintosh #pragma segment Chaine #endif // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // Private C functions // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // Methods // ------------------------------------------------------------------------------------------------ Chaine::Chaine() { lng = 0; } Chaine::Chaine(const Chaine& laChaine) { long size = laChaine.Longueur()+1; size = ((unsigned long) size > sizeof(Chaine) ? sizeof(Chaine) : size); BlockMove(&laChaine,this,size); } Chaine::Chaine(const unsigned char *const pStr) { BlockMove(pStr,this,*pStr+1); car[*pStr] = '\0'; } Chaine::Chaine(float reel, short nbDec) { short i; short nb; float arrondi = (float)0.5; unsigned char chiffre; unsigned char inutile; long intPart = 0; long decPart = 0; lng = 0; if (nbDec > 9) nbDec = 9; if (reel < 0) { reel = -reel; car[lng++] = '-'; } for (nb=nbDec;nb--;) arrondi /= 10; reel += arrondi; for (i=0;reel>=1;i++,reel /= (float)10.0) if (i > 32) break; if (i) { while (i--) { reel *= 10; car[lng++] = (chiffre = (unsigned char)reel) + '0'; reel -= chiffre; intPart = intPart*10 + chiffre; } } else { car[lng++] = '0'; } inutile = lng; car[lng++] = lpDecimalSeparator; while (nbDec--) { reel *= 10; car[lng++] = (chiffre = (unsigned char)reel) + '0'; reel -= chiffre; decPart = decPart*10 + chiffre; if (chiffre) inutile = lng; } lng = inutile; // Avoid the "negative 0" case if ((intPart == 0) && (decPart == 0)) { car[0] = '0'; lng = 1; } car[lng] = '\0'; } Chaine::Chaine(float reel, short nbDec, unsigned char decSep) { short i; short nb; float arrondi = (float)0.5; unsigned char chiffre; unsigned char inutile; long intPart = 0; long decPart = 0; lng = 0; if (nbDec > 9) nbDec = 9; if (reel < 0) { reel = -reel; car[lng++] = '-'; } for (nb=nbDec;nb--;) arrondi /= 10; reel += arrondi; for (i=0;reel>=1;i++,reel /= (float)10.0) if (i > 32) break; if (i) { while (i--) { reel *= 10; car[lng++] = (chiffre = (unsigned char)reel) + '0'; reel -= chiffre; intPart = intPart*10 + chiffre; } } else { car[lng++] = '0'; } inutile = lng; car[lng++] = decSep; while (nbDec--) { reel *= 10; car[lng++] = (chiffre = (unsigned char)reel) + '0'; reel -= chiffre; decPart = decPart*10 + chiffre; if (chiffre) inutile = lng; } lng = inutile; // Avoid the "negative 0" case if ((intPart == 0) && (decPart == 0)) { car[0] = '0'; lng = 1; } car[lng] = '\0'; } Chaine::Chaine(const CStringHolder& s) { size_t size = strlen(s.GetString()); size = (size > MAX_CHAINE ? MAX_CHAINE : size); this->lng = size; BlockMove(s.GetString(),this->car,size); this->car[size]='\0'; } Chaine::operator float() const { long i; float reel = (float)0; float decimale = (float)1; Boolean negatif = FALSE; for(i=0;car[i]==' ';) if (++i>=lng) goto fin; if (car[i] == '-') { negatif = TRUE; if (++i>=lng) goto fin; } else if (car[i] == '+') if (++i>=lng) goto fin; while ((car[i] >= '0') && (car[i] <= '9')) { reel *= (float)10; reel += car[i] - '0'; if (++i>=lng) goto fin; } if ((car[i] == ',') || (car[i] == '.')) { if (++i>=lng) goto fin; while ((car[i] >= '0') && (car[i] <= '9')) { decimale *= 10; reel *= 10; reel += car[i] - '0'; if (++i>=lng) goto fin; } } fin: if (negatif) reel = -reel; if (decimale > 1) reel /= decimale; return reel; } ref_Chaine Chaine::operator+= (const Chaine& s) { if (s.lng) { if (s.lng + lng > MAX_CHAINE) { BlockMove(s.car,car+lng,MAX_CHAINE-lng); lng = MAX_CHAINE; } else { BlockMove(s.car,car+lng,s.lng); lng += s.lng; } } return *this; } ref_Chaine Chaine::operator+= (const unsigned char* s) { if (s[0]) { if (s[0] + lng > MAX_CHAINE) { BlockMove(s+1,car+lng,MAX_CHAINE-lng); lng = MAX_CHAINE; } else { BlockMove(s+1,car+lng,s[0]); lng += s[0]; } } return *this; } ref_Chaine Chaine::operator+= (const CStringHolder& s) { size_t len = strlen(s.GetString()); if (len > 0) { if (len + lng > MAX_CHAINE) { BlockMove(s.GetString(),car+lng,MAX_CHAINE-lng); lng = MAX_CHAINE; } else { BlockMove(s.GetString(),car+lng,len); lng += len; } } return *this; } Chaine operator+ (const Chaine& s1, const Chaine& s2) { Chaine s = s1; s += s2; return s; } Chaine operator+ (const Chaine& s1, const unsigned char* s2) { Chaine s = s1; s += s2; return s; } Chaine operator+ (const unsigned char* s1, const Chaine& s2) { Chaine s; s += s1; s += s2; return s; } Chaine operator+ (const Chaine& s1, const CStringHolder& s2) { Chaine s = s1; s += s2; return s; } Chaine operator+ (const CStringHolder& s1, const Chaine& s2) { Chaine s; s += s1; s += s2; return s; } Chaine::operator long() const { // note: float is an operator override. // This takes a string, uses the float override, // then converts to long float nb = *this; return (long)nb; } // If 'this' contains a meta sequence of ^0, ^1 or ^2, then insert // in the position specified by 'numParam' void Chaine::PlaceParametre(const Chaine& replaceStr, short numParam ) { #ifndef macintosh // Look for the correct parameter char toSearch[] = { '^', '0', '\0' }; if (numParam == 1) toSearch[1] = '1'; else if (numParam == 2) toSearch[1] = '2'; // Search const char * foundStr = strstr((const char*)Texte(), toSearch); // If found, build the string with replacment if (foundStr != NULL) { char modifiedStr[2*256]; int nbUnchangedStartingChars; // Copy unmodified start of string *this nbUnchangedStartingChars = foundStr - (const char*)Texte(); strncpy(modifiedStr, (const char*)Texte(), nbUnchangedStartingChars); modifiedStr[nbUnchangedStartingChars] = '\0'; // Replace "^i" by replaceStr strcat(modifiedStr, (const char*)replaceStr.Texte()); // Copy unmodified end of string *this strcat(modifiedStr, foundStr+strlen(toSearch)); // Copy modifiedStr to *this *this = Chaine(CStringHolder(modifiedStr)); } #else Handle localString = NewHandle(lng); Handle localReplace = NewHandle(replaceStr.Longueur()); BlockMove(car,*localString,lng); BlockMove((Ptr)replaceStr.Texte(),*localReplace,replaceStr.Longueur()); // replace the correct parameter if (numParam == 1) ReplaceText(localString,localReplace,(unsigned char*) "\p^1"); else if (numParam == 2) ReplaceText(localString,localReplace,(unsigned char*) "\p^2"); else ReplaceText(localString,localReplace,(unsigned char*) "\p^0"); lng = (unsigned char)GetHandleSize(localString); if (lng) BlockMove(*localString,car,lng); DisposHandle(localString); DisposHandle(localReplace); #endif } #ifdef macintosh void Chaine::TruncChaine(GrafPtr theGraphicPointer, unsigned char numberOfCharacters) // this can be used only for constant character width fonts { short size; size = TextWidth("a",0,1); TruncString(short(numberOfCharacters)*size, *this, truncEnd); numberOfCharacters++; if (Longueur() < numberOfCharacters) { memset(&car[lng], ' ', size_t(numberOfCharacters) - size_t(lng)); lng = numberOfCharacters; } } void Chaine::JustifyChaineRight(GrafPtr theGraphicPointer, long numberOfCharacters) // this can be used only for constant character width fonts { Chaine temp; if (Longueur() < numberOfCharacters) // if the lenght is lower than numberOfCharacters { // add the right number of blanks of the left size_t blankWidth = size_t(numberOfCharacters) - size_t(lng); memset(temp.Texte(), ' ', blankWidth); BlockMove(this->Texte(), (temp.Texte()) + blankWidth, lng); temp.lng += blankWidth + lng; lng += blankWidth; *this = temp; } else { // else short size; // trunc the chaine to the required numberOfCharacters numberOfCharacters++; // truncChaine truncs at numberOfCharacters-1 and adds ... size = TextWidth("a",0,1); // at numberOfCharacters TruncString(short(numberOfCharacters)*size, *this, truncEnd); } } #endif // macintosh void Chaine::TruncChaine(unsigned char numberOfCharacters) // this can be used only for constant character width fonts { if (Longueur() >= numberOfCharacters) lng = numberOfCharacters; else { memset(&car[lng], ' ', size_t(numberOfCharacters) - size_t(lng)); lng = numberOfCharacters; } } Chaine63::Chaine63() { lng = 0; } Chaine63::Chaine63(const unsigned char *const pStr) { BlockMove(pStr,this,*pStr+1); car[*pStr] = '\0'; } Chaine63::Chaine63(float reel, short nbDec) { short i; short nb; float arrondi = (float)0.5; unsigned char chiffre; unsigned char inutile; lng = 0; if (nbDec > 9) nbDec = 9; if (reel < 0) { reel = -reel; car[lng++] = '-'; } for (nb=nbDec;nb--;) arrondi /= 10; reel += arrondi; for (i=0;reel>=1;i++,reel /= (float)10.0) if (i > 32) break; if (i) { while (i--) { reel *= 10; car[lng++] = (chiffre = (unsigned char)reel) + '0'; reel -= chiffre; } } else { car[lng++] = '0'; } inutile = lng; car[lng++] = lpDecimalSeparator; while (nbDec--) { reel *= 10; car[lng++] = (chiffre = (unsigned char)reel) + '0'; reel -= chiffre; if (chiffre) inutile = lng; } lng = inutile; } Chaine63::Chaine63(const CStringHolder& s) { size_t size = strlen(s.GetString()); size = (size > 63 ? 63 : size); this->lng = size; BlockMove(s.GetString(),this->car,size); } Chaine63::~Chaine63() { } Chaine63::operator float() const { long i; float reel = (float)0; float decimale = (float)1; Boolean negatif = FALSE; for(i=0;car[i]==' ';) if (++i>=lng) goto fin; if (car[i] == '-') { negatif = TRUE; if (++i>=lng) goto fin; } else if (car[i] == '+') if (++i>=lng) goto fin; while ((car[i] >= '0') && (car[i] <= '9')) { reel *= 10; reel += car[i] - '0'; if (++i>=lng) goto fin; } if ((car[i] == ',') || (car[i] == '.')) { if (++i>=lng) goto fin; while ((car[i] >= '0') && (car[i] <= '9')) { decimale *= 10; reel *= 10; reel += car[i] - '0'; if (++i>=lng) goto fin; } } fin: if (negatif) reel = -reel; if (decimale > 1) reel /= decimale; return reel; } ref_Chaine63 Chaine63::operator+= (const Chaine63& s) { if (s.lng) { if (s.lng + lng > 63) { BlockMove(s.car,car+lng,63-lng); lng = 63; } else { BlockMove(s.car,car+lng,s.lng); lng += s.lng; } } return *this; } ref_Chaine63 Chaine63::operator+= (const unsigned char* s) { if (s[0]) { if (s[0] + lng > 63) { BlockMove(s+1,car+lng,63-lng); lng = 63; } else { BlockMove(s+1,car+lng,s[0]); lng += s[0]; } } return *this; } ref_Chaine63 Chaine63::operator+= (const CStringHolder& s) { size_t len = strlen(s.GetString()); if (len > 0) { if (len + lng > 63) { BlockMove(s.GetString(),car+lng,63-lng); lng = 63; } else { BlockMove(s.GetString(),car+lng,len); lng += len; } } return *this; } Chaine63 operator+ (const Chaine63& s1, const Chaine63& s2) { Chaine63 s = s1; s += s2; return s; } Chaine63 operator+ (const Chaine63& s1, const unsigned char* s2) { Chaine63 s = s1; s += s2; return s; } Chaine63 operator+ (const unsigned char* s1, const Chaine63& s2) { Chaine63 s; s += s1; s += s2; return s; } Chaine63 operator+ (const Chaine63& s1, const CStringHolder& s2) { Chaine63 s = s1; s += s2; return s; } Chaine63 operator+ (const CStringHolder& s1, const Chaine63& s2) { Chaine63 s; s += s1; s += s2; return s; } #ifdef macintosh void Chaine63::PlaceParametre(const Chaine63& replaceStr, short numParam ) { #ifndef macintosh // Look for the correct parameter char * toSearch = "^0"; if (numParam == 1) toSearch[1] = '1'; else if (numParam == 2) toSearch[1] = '2'; // Search char * foundStr = strstr(Texte(), toSearch); // If found, build the string with replacment if (foundStr != NULL) { char modifiedStr[2*256]; int nbUnchangedStartingChars; // Copy unmodified start of string *this nbUnchangedStartingChars = foundStr - Texte(); strncpy(modifiedStr, (const char*)Texte(), nbUnchangedStartingChars); modifiedStr[nbUnchangedStartingChars] = '\0'; // Replace "^i" by replaceStr strcat(modifiedStr, replaceStr.Texte()); // Copy unmodified end of string *this strcat(modifiedStr, foundStr+strlen(toSearch)); // Copy modifiedStr to *this *this = Chaine63(CStringHolder(modifiedStr)); } #else Handle localString = NewHandle(lng); Handle localReplace = NewHandle(replaceStr.Longueur()); BlockMove(car,*localString,lng); BlockMove((Ptr)replaceStr.Texte(),*localReplace,replaceStr.Longueur()); // replace the correct parameter if (numParam == 1) ReplaceText(localString,localReplace,(unsigned char*) "\p^1"); else if (numParam == 2) ReplaceText(localString,localReplace,(unsigned char*) "\p^2"); else ReplaceText(localString,localReplace,(unsigned char*) "\p^0"); lng = (unsigned char)GetHandleSize(localString); if (lng) BlockMove(*localString,car,lng); DisposHandle(localString); DisposHandle(localReplace); #endif } void Chaine63::TruncChaine(GrafPtr theGraphicPointer, unsigned char numberOfCharacters) // this can be used only for constant character width fonts { short size; size = TextWidth("a",0,1); TruncString(short(numberOfCharacters)*size, *this, truncEnd); // while (Longueur() < numberOfCharacters+1){ // *this += ESPACE; // } numberOfCharacters++; if (Longueur() < numberOfCharacters) { memset(&car[lng], ' ', size_t(numberOfCharacters) - size_t(lng)); lng = numberOfCharacters; } } void Chaine63::JustifyChaineRight(GrafPtr /*theGraphicPointer*/, long /*numberOfCharacters*/) { } #endif // macintosh void Chaine63::TruncChaine(unsigned char numberOfCharacters) // this can be used only for constant character width fonts { if (Longueur() >= numberOfCharacters) lng = numberOfCharacters; else { memset(&car[lng], ' ', size_t(numberOfCharacters) - size_t(lng)); lng = numberOfCharacters; } } // ------------------------------------------------------------------------------------------------ // Exported C functions // ------------------------------------------------------------------------------------------------ #ifdef macintosh void LoadInternationalSeparators() { Intl0Hndl itl0Resource = (Intl0Hndl)GetIntlResource(0); if (itl0Resource) { if ((*itl0Resource)->decimalPt == '.' || (*itl0Resource)->decimalPt == ',') lpDecimalSeparator = (*itl0Resource)->decimalPt; lpThousandSeparator = (*itl0Resource)->thousSep; } } #endif // macintosh