/** * Copyright Mikael Högdahl - triyana@users.sourceforge.net * * This source is distributed under the terms of the Q Public License version 1.0, * created by Trolltech (www.trolltech.com). */ #include #include #include #include #include "MHString.h" #include "MHVector.h" #include "MHUtil.h" /** * Do an sprintf constrcutor * @param int - Size * @param const char* - First string * @param ... - Rest of params */ MHString::MHString(int size, const char* str, ...) { va_list args; char* buffer = new char[size + 1]; va_start (args, str); vsnprintf (buffer, size, str, args); va_end (args); aData = buffer; aLen = STRLEN (buffer); } /** * Align the string * @param bool - true to align right * @param int - Width of string * @param char - Pad string, only one char */ void MHString::align (bool right, int nWidth, char pad) { char* p = new char[nWidth + 1]; int count = 0; if (aLen >= nWidth) { delete []p; return; } p[0] = pad; p[1] = '\0'; while ((nWidth - aLen - strlen(p)) > 0) { count++; p[count] = pad; p[count + 1] = '\0'; } if (right) allocate (p, aData); else allocate (aData, p); delete []p; } /** * Allocate a string */ void MHString::allocate (const char* s) { Clear(); aLen = STRLEN(s); aData = new char[aLen + 1]; strncpy (aData, s, aLen); aData[aLen] = '\0'; } /** * Allocate a string * @param int - Number to convert */ void MHString::allocate (int i) { char s [100]; Clear (); sprintf (s, "%d", i); aLen = STRLEN(s); aData = new char[aLen + 1]; strncpy (aData, s, aLen); aData[aLen] = '\0'; } /** * Allocate a string * @param double - Number to convert */ void MHString::allocate (double d) { char s[100]; Clear (); sprintf (s, "%.*f", 2, d); aLen = STRLEN(s); aData = new char[aLen + 1]; strncpy (aData, s, aLen); aData[aLen] = '\0'; } /** * Allocate a string */ void MHString::allocate (const char* s, const char* s2) { int l1 = STRLEN (s); int l2 = STRLEN (s2); char* c = new char[l1 + l2 + 1]; strncpy (c, s, l1); c[l1] = '\0'; strncat (c, s2, l2); c[l1 + l2] = '\0'; Clear(); aLen = l1 + l2; aData = c; aData[aLen] = '\0'; } /** * Allocate a string */ void MHString::allocate (const char* s, int n) { char s2[100]; sprintf (s2, "%d", n); allocate (s, s2); } /** * Allocate a string */ void MHString::allocate (const char* s, double n) { char s2[100]; sprintf (s2, "%.*f", 2, n); allocate (s, s2); } /** * Convert first letter in each word to uppercase, all other lowercase */ void MHString::CapitalizeAll () { ToLower (); char* source = aData; bool space = true; while (*source) { if (space && *source > ' ' && *source != '\'') { *source = toupper (*source); space = false; } else if (*source <= ' ') space = true; source++; } } /** * Convert first letter in first word to uppercase, all other lowercase */ void MHString::CapitalizeFirst () { ToLower (); } /** * Empty string */ void MHString::Clear () { delete []aData; aData = 0; aLen = 0; } /** * Compare string with another string * @param char* - String to compare with * @return int - 0, -1, 1 */ int MHString::Compare (const char* pBuffer) { if (aData && pBuffer) return strcmp (aData, pBuffer); return -1; } /** * Compare string with another string * @return int - 0, -1, 1 */ int MHString::Compare (const MH* o, int type) { if (type == SORT_STRING) return Compare(((MHString*)o)->Get()); else if (type == SORT_NUM) { double d1 = ToDouble (); double d2 = ((MHString*)o)->ToDouble (); if (fabs (d1 - d2) < 0.0000001) return 0; else if (d1 < d2) return -1; return 1; } return -1; } /** * Compare string with another string * @param char* - String to compare with * @param MHString::STATUS - EXACT or DONT_CARE * @return int - 0, -1, 1 */ int MHString::CompareIgnoreCase (const char* pBuffer) { if (aData && pBuffer) return strncasecmp (aData, pBuffer, aLen); else return -1; } /** * Find string * @param char* - String to find inside current string * @param int - Start in current string * @return int - Pos or -1 */ int MHString::find (const char* word, int start, bool compareCase) { if (start < (aLen - 1)) { if (compareCase == false) { MHString s(aData); MHString s2(word); s.ToLower(); s2.ToLower(); return s.Find(s2, false); } else { const char* s = strstr (aData + start, word); return s - aData; } } return -1; } /** * Get left part of string * @param int - Number of char * @return MHString - New string with left part of original string */ MHString MHString::Left (int count) { MHString s; if (count > 0) { if (count > aLen) count = aLen; char* buffer = new char[count + 1]; strncpy (buffer, aData, count); buffer[count] = '\0'; s.Clear(); s.aData = buffer; s.aLen = count; } return s; } /** * Get middle part of string * @param int - Pos of first char * @param int - Number of char * @return MHString - New string with left part of original string */ MHString MHString::Mid (int start, int count) { MHString s; if (start > 0 && count > 0) { if ((start + count) > aLen) return s; char* buffer = new char[count + 1]; strncpy (buffer, aData + start, count); buffer[count] = '\0'; s.Clear(); s.aData = buffer; s.aLen = count; } return s; } /** * Remove char from head * @param char - Character to remove */ void MHString::Remove (char ch) { if (aLen > 0) { char* tmp = new char[aLen + 1]; char* source = aData; char* dest = tmp; *tmp = *aData; while (*source) { if (*source != ch) { *dest = *source; dest++; } source++; } *dest = '\0'; aLen = STRLEN(tmp); delete aData; aData = tmp; } } /** * Remove char from head * @param char - Character to remove */ void MHString::RemoveHead (char ch) { char* source = aData; if (source && *source) { if (*source == ch) { while (*source == ch) source++; memmove (aData, source, strlen(source) + 1); } aLen = STRLEN(aData); } } /** * Remove char from tail * @param char - Character to remove */ void MHString::RemoveTail (char ch) { char* source = aData + aLen - 1; if (source && *source) { if (*source == ch) { while (*source == ch) { *source = '\0'; source--; } } aLen = STRLEN(aData); } } /** * Get right part of string * @param int - Number of char * @return MHString - New string with left part of original string */ MHString MHString::Right (int count) { MHString s; if (count > 0) { if ((aLen - count) < 0) count = aLen; char* buffer = new char[count + 1]; strncpy (buffer, aData + aLen - count, count); buffer[count] = '\0'; s.Clear(); s.aData = buffer; s.aLen = count; } return s; } /** * Save an array of strings * @param const char* - Filename * @param MHVector* - Vector with MHString objects * @param bool - true to add a new line, default false * @param bool - true to add row counter, default false */ void MHString::Save (const char* fileName, MHVector* v, bool nl, bool row) { FILE* file = fopen (fileName, "w"); if (file) { for (int f = 0; f < v->Size(); f++) { MHString* s = (MHString*) (*v)[f]; char b[20]; snprintf (b, 10, "%05d ", f + 1); if (row) fwrite (b, sizeof(char), 9, file); fwrite (s->Get(), sizeof(char), s->Size(), file); if (nl) fwrite ("\n", sizeof(char), 1, file); } } fclose (file); } /** * Make string smaller * @param int - Number of char */ void MHString::Shrink (int count) { if (count > 0 && count < aLen) { char* buffer = new char[count + 1]; strncpy (buffer, aData, count); buffer[count] = '\0'; Clear(); aData = buffer; aLen = count; } } /** * Split string into many strings * @param char c - Character to split on * @param MHVector* - The result vector * @return int - Number of strings */ int MHString::Split (char c, MHVector* ve) { int nIndex = 0; int nTempPos = 0; char Temp [10000]; Temp[0] = '\0'; while (aData[nIndex] != 0 && nIndex < aLen) { if (aData[nIndex] == c || nTempPos == 9999) { Temp [nTempPos] = '\0'; ve->Push (new MHString(Temp)); nTempPos = 0; Temp [0] = '\0'; } else Temp[nTempPos++] = aData[nIndex]; nIndex++; } // Check if something is left in buffer if (nTempPos > 0) { Temp [nTempPos] = '\0'; ve->Push (new MHString(Temp)); } return ve->Size(); } /** * Split string into many strings * @param MHVector* - The result vector * @param int - Positions in vector even pairs of start and stop, end with -1 * @return int - Number of strings */ int MHString::Split (MHVector* ve, int nFirstPos, ...) { int nIndex = 0; int count; int pos[1000]; va_list ap; va_start (ap, nFirstPos); pos [nIndex++] = nFirstPos; while (nFirstPos != -1) { nFirstPos = va_arg (ap, int); pos[nIndex++] = nFirstPos; if (nIndex == 1000) return 0; } va_end (ap); for (int i = 0; i < (nIndex - 1) && pos[i] != -1 && pos[i + 1] != -1; i += 2) { int start = pos[i]; int stop = pos[i+1]; char buffer[1000]; if (start < 0 && stop >= aLen) return ve->Size(); count = 0; for (int f = start; f <= stop && count < 999; f++) buffer[count++] = aData[f]; buffer[count] = '\0'; ve->Push (new MHString(buffer)); nIndex++; } return ve->Size(); } /** * Do an sprintf operation of this string * @param int - Length of string * @param const char* - First string * @param ... - Rest of params */ void MHString::Sprintf(int len, const char* str, ...) { char* buffer = new char[len + 1]; va_list argp; va_start (argp, str); vsnprintf (buffer, len, str, argp); va_end (argp); Clear(); aData = buffer; aLen = STRLEN(buffer); } /** * Remove all whitespaces first and last in the string */ void MHString::Strip () { if (aLen < 1) return; char* source1 = aData; char* source2 = aData + aLen - 1; while (source1 && *source1 != '\0' && *source1 < 33) *source1++ = '\0'; while (source2 && *source2 != '\0' && *source2 < 33 && source2 > aData) *source2-- = '\0'; int len = source2 - source1 + 1; if (len != aLen) { strncpy (aData, source1, len); aData[len] = '\0'; aLen = len; } } /** * Convert string to lower case */ void MHString::ToLower () { char* source = aData; while (*source) { *source = tolower (*source); source++; } } /** * Conver string upper case */ void MHString::ToUpper () { char* source = aData; while (*source) { *source = toupper (*source); source++; } }