void FString::StripLeftRight (const char *charset) { size_t max = Len(), i, j, k; if (max == 0) return; for (i = 0; i < max; ++i) { if (!strchr (charset, Chars[i])) break; } for (j = max - 1; j >= i; --j) { if (!strchr (charset, Chars[j])) break; } if (Data()->RefCount <= 1) { for (k = 0; i <= j; ++i, ++k) { Chars[k] = Chars[i]; } Chars[k] = '\0'; ReallocBuffer (k); } else { FStringData *old = Data(); AllocBuffer (j - i); StrCopy (Chars, old->Chars(), j - i); old->Release(); } }
void FString::Insert (size_t index, const char *instr, size_t instrlen) { if (instrlen > 0) { size_t mylen = Len(); if (index >= mylen) { AppendCStrPart(instr, instrlen); } else if (Data()->RefCount <= 1) { ReallocBuffer(mylen + instrlen); memmove(Chars + index + instrlen, Chars + index, (mylen - index + 1) * sizeof(char)); memcpy(Chars + index, instr, instrlen * sizeof(char)); } else { FStringData *old = Data(); AllocBuffer(mylen + instrlen); StrCopy(Chars, old->Chars(), index); StrCopy(Chars + index, instr, instrlen); StrCopy(Chars + index + instrlen, old->Chars() + index, mylen - index); old->Release(); } } }
void FString::StripRight (const char *charset) { size_t max = Len(), i; if (max == 0) return; for (i = --max; i > 0; i--) { if (!strchr (charset, Chars[i])) break; } if (i == max) { // Nothing to strip. return; } if (Data()->RefCount <= 1) { Chars[i+1] = '\0'; ReallocBuffer (i+1); } else { FStringData *old = Data(); AllocBuffer (i+1); StrCopy (Chars, old->Chars(), i+1); old->Release(); } }
void FString::StripLeftRight () { size_t max = Len(), i, j, k; if (max == 0) return; for (i = 0; i < max; ++i) { if (!isspace((unsigned char)Chars[i])) break; } for (j = max - 1; j >= i; --j) { if (!isspace((unsigned char)Chars[j])) break; } if (i == 0 && j == max - 1) { // Nothing to strip. return; } if (Data()->RefCount <= 1) { for (k = 0; i <= j; ++i, ++k) { Chars[k] = Chars[i]; } Chars[k] = '\0'; ReallocBuffer (k); } else { FStringData *old = Data(); AllocBuffer(j - i + 1); StrCopy(Chars, old->Chars(), j - i + 1); old->Release(); } }
void FString::Remove(size_t index, size_t remlen) { if (index < Len()) { if (index + remlen >= Len()) { Truncate((long)index); } else { remlen = Len() - remlen < remlen ? Len() - remlen : remlen; if (Data()->RefCount == 1) { // Can do this in place memmove(Chars + index, Chars + index + remlen, Len() - index - remlen); memset(Chars + Len() - remlen, 0, remlen); Data()->Len -= (unsigned)remlen; } else { // Must do it in a copy FStringData *old = Data(); AllocBuffer(old->Len - remlen); StrCopy(Chars, old->Chars(), index); StrCopy(Chars + index, old->Chars() + index + remlen, old->Len - index - remlen); old->Release(); } } } }
void FString::StripLeft (const char *charset) { size_t max = Len(), i, j; if (max == 0) return; for (i = 0; i < max; ++i) { if (!strchr (charset, Chars[i])) break; } if (i == 0) { // Nothing to strip. return; } if (Data()->RefCount <= 1) { for (j = 0; i <= max; ++j, ++i) { Chars[j] = Chars[i]; } ReallocBuffer (j-1); } else { FStringData *old = Data(); AllocBuffer (max - i); StrCopy (Chars, old->Chars() + i, max - i); old->Release(); } }
FStringData *FStringData::MakeCopy () { FStringData *copy = Alloc (Len); copy->Len = Len; FString::StrCopy (copy->Chars(), Chars(), Len); return copy; }
FString &FString::operator = (const char *copyStr) { if (copyStr != Chars) { if (copyStr == NULL || *copyStr == '\0') { Data()->Release(); NullString.RefCount++; Chars = &NullString.Nothing[0]; } else { // In case copyStr is inside us, we can't release it until // we've finished the copy. FStringData *old = Data(); if (copyStr < Chars || copyStr >= Chars + old->Len) { // We know the string isn't in our buffer, so release it now // to reduce the potential for needless memory fragmentation. old->Release(); old = NULL; } size_t len = strlen (copyStr); AllocBuffer (len); StrCopy (Chars, copyStr, len); if (old != NULL) { old->Release(); } } } return *this; }
void FString::ReallocBuffer (size_t newlen) { if (Data()->RefCount > 1) { // If more than one reference, we must use a new copy FStringData *old = Data(); AllocBuffer (newlen); StrCopy (Chars, old->Chars(), newlen < old->Len ? newlen : old->Len); old->Release(); } else { if (newlen > Data()->AllocLen) { Chars = (char *)(Data()->Realloc(newlen) + 1); } Data()->Len = (unsigned int)newlen; } }
char *FString::LockBuffer() { if (Data()->RefCount == 1) { // We're the only user, so we can lock it straight away Data()->RefCount = -1; } else if (Data()->RefCount < -1) { // Already locked; just add to the lock count Data()->RefCount--; } else { // Somebody else is also using this character buffer, so create a copy FStringData *old = Data(); AllocBuffer (old->Len); StrCopy (Chars, old->Chars(), old->Len); old->Release(); Data()->RefCount = -1; } return Chars; }
void FString::StripRight (const char *charset) { size_t max = Len(), i; for (i = max; i-- > 0; ) { if (!strchr (charset, Chars[i])) break; } if (Data()->RefCount <= 1) { Chars[i+1] = '\0'; ReallocBuffer (i+1); } else { FStringData *old = Data(); AllocBuffer (i+1); StrCopy (Chars, old->Chars(), i+1); old->Release(); } }
void FString::StripRight () { size_t max = Len(), i; for (i = max - 1; i-- > 0; ) { if (!isspace(Chars[i])) break; } if (Data()->RefCount <= 1) { Chars[i+1] = '\0'; ReallocBuffer (i+1); } else { FStringData *old = Data(); AllocBuffer (i+1); StrCopy (Chars, old->Chars(), i+1); old->Release(); } }
void FString::StripLeft () { size_t max = Len(), i, j; for (i = 0; i < max; ++i) { if (!isspace(Chars[i])) break; } if (Data()->RefCount <= 1) { for (j = 0; i <= max; ++j, ++i) { Chars[j] = Chars[i]; } ReallocBuffer (j-1); } else { FStringData *old = Data(); AllocBuffer (max - i); StrCopy (Chars, old->Chars() + i, max - i); old->Release(); } }