Part of fixing #7226:
* the libbe_build version of BString was broken, at least with respect to LockBuffer() on an empty string - replaced the implementation and header with our current version (keeping the type-related changes required by the build-version) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40526 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+389
-306
@@ -1,393 +1,432 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2003, OpenBeOS
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// File Name: String.h
|
||||
// Author(s): Stefano Ceccherini ([email protected])
|
||||
// Description: String class supporting common string operations.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef __BSTRING__
|
||||
#define __BSTRING__
|
||||
|
||||
|
||||
#include <BeBuild.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
class BStringRef;
|
||||
|
||||
|
||||
class BString {
|
||||
public:
|
||||
BString();
|
||||
BString(const char *);
|
||||
BString(const BString &);
|
||||
BString(const char *, int32 maxLength);
|
||||
BString();
|
||||
BString(const char* string);
|
||||
BString(const BString& string);
|
||||
BString(const char* string, int32 maxLength);
|
||||
~BString();
|
||||
|
||||
~BString();
|
||||
// Access
|
||||
const char* String() const;
|
||||
int32 Length() const;
|
||||
int32 CountChars() const;
|
||||
int32 CountBytes(int32 fromCharOffset,
|
||||
int32 charCount) const;
|
||||
|
||||
/*---- Access --------------------------------------------------------------*/
|
||||
const char *String() const;
|
||||
/* returns null-terminated string */
|
||||
// Assignment
|
||||
BString& operator=(const BString& string);
|
||||
BString& operator=(const char* string);
|
||||
BString& operator=(char c);
|
||||
|
||||
int32 Length() const;
|
||||
/* length of corresponding string */
|
||||
BString& SetTo(const char* string);
|
||||
BString& SetTo(const char* string, int32 maxLength);
|
||||
|
||||
int32 CountChars() const;
|
||||
/* returns number of UTF8 characters in string */
|
||||
/*---- Assignment ----------------------------------------------------------*/
|
||||
BString &operator=(const BString &);
|
||||
BString &operator=(const char *);
|
||||
BString &operator=(char);
|
||||
BString& SetTo(const BString& string);
|
||||
BString& Adopt(BString& from);
|
||||
|
||||
BString &SetTo(const char *);
|
||||
BString &SetTo(const char *, int32 length);
|
||||
BString& SetTo(const BString& string, int32 maxLength);
|
||||
BString& Adopt(BString& from, int32 maxLength);
|
||||
|
||||
BString &SetTo(const BString &from);
|
||||
BString &Adopt(BString &from);
|
||||
/* leaves <from> empty, avoiding a copy */
|
||||
BString& SetTo(char c, int32 count);
|
||||
|
||||
BString &SetTo(const BString &, int32 length);
|
||||
BString &Adopt(BString &from, int32 length);
|
||||
/* leaves <from> empty, avoiding a copy */
|
||||
BString& SetToChars(const char* string, int32 charCount);
|
||||
BString& SetToChars(const BString& string, int32 charCount);
|
||||
BString& AdoptChars(BString& from, int32 charCount);
|
||||
|
||||
BString &SetTo(char, int32 count);
|
||||
// Substring copying
|
||||
BString& CopyInto(BString& into, int32 fromOffset,
|
||||
int32 length) const;
|
||||
void CopyInto(char* into, int32 fromOffset,
|
||||
int32 length) const;
|
||||
|
||||
/*---- Substring copying ---------------------------------------------------*/
|
||||
BString &CopyInto(BString &into, int32 fromOffset,
|
||||
int32 length) const;
|
||||
/* returns <into> ref as it's result; doesn't do
|
||||
* anything if <into> is <this>
|
||||
*/
|
||||
BString& CopyCharsInto(BString& into, int32 fromCharOffset,
|
||||
int32 charCount) const;
|
||||
bool CopyCharsInto(char* into, int32* intoLength,
|
||||
int32 fromCharOffset, int32 charCount) const;
|
||||
|
||||
void CopyInto(char *into, int32 fromOffset,
|
||||
int32 length) const;
|
||||
/* caller guarantees that <into> is large enough */
|
||||
// Appending
|
||||
BString& operator+=(const BString& string);
|
||||
BString& operator+=(const char* string);
|
||||
BString& operator+=(char c);
|
||||
|
||||
/*---- Appending -----------------------------------------------------------*/
|
||||
BString &operator+=(const BString &);
|
||||
BString &operator+=(const char *);
|
||||
BString &operator+=(char);
|
||||
BString& Append(const BString& string);
|
||||
BString& Append(const char* string);
|
||||
|
||||
BString &Append(const BString &);
|
||||
BString &Append(const char *);
|
||||
BString& Append(const BString& string, int32 length);
|
||||
BString& Append(const char* string, int32 length);
|
||||
BString& Append(char c, int32 count);
|
||||
|
||||
BString &Append(const BString &, int32 length);
|
||||
BString &Append(const char *, int32 length);
|
||||
BString &Append(char, int32 count);
|
||||
BString& AppendChars(const BString& string, int32 charCount);
|
||||
BString& AppendChars(const char* string, int32 charCount);
|
||||
|
||||
/*---- Prepending ----------------------------------------------------------*/
|
||||
BString &Prepend(const char *);
|
||||
BString &Prepend(const BString &);
|
||||
BString &Prepend(const char *, int32);
|
||||
BString &Prepend(const BString &, int32);
|
||||
BString &Prepend(char, int32 count);
|
||||
// Prepending
|
||||
BString& Prepend(const char* string);
|
||||
BString& Prepend(const BString& string);
|
||||
BString& Prepend(const char* string, int32 length);
|
||||
BString& Prepend(const BString& string, int32 length);
|
||||
BString& Prepend(char c, int32 count);
|
||||
|
||||
/*---- Inserting ----------------------------------------------------------*/
|
||||
BString &Insert(const char *, int32 pos);
|
||||
BString &Insert(const char *, int32 length, int32 pos);
|
||||
BString &Insert(const char *, int32 fromOffset,
|
||||
int32 length, int32 pos);
|
||||
BString& PrependChars(const char* string, int32 charCount);
|
||||
BString& PrependChars(const BString& string,
|
||||
int32 charCount);
|
||||
|
||||
BString &Insert(const BString &, int32 pos);
|
||||
BString &Insert(const BString &, int32 length, int32 pos);
|
||||
BString &Insert(const BString &, int32 fromOffset,
|
||||
int32 length, int32 pos);
|
||||
BString &Insert(char, int32 count, int32 pos);
|
||||
// Inserting
|
||||
BString& Insert(const char* string, int32 position);
|
||||
BString& Insert(const char* string, int32 length,
|
||||
int32 position);
|
||||
BString& Insert(const char* string, int32 fromOffset,
|
||||
int32 length, int32 position);
|
||||
BString& Insert(const BString& string, int32 position);
|
||||
BString& Insert(const BString& string, int32 length,
|
||||
int32 position);
|
||||
BString& Insert(const BString& string, int32 fromOffset,
|
||||
int32 length, int32 position);
|
||||
BString& Insert(char c, int32 count, int32 position);
|
||||
|
||||
/*---- Removing -----------------------------------------------------------*/
|
||||
BString &Truncate(int32 newLength, bool lazy = true);
|
||||
/* pass false in <lazy> to ensure freeing up the
|
||||
* truncated memory
|
||||
*/
|
||||
BString& InsertChars(const char* string, int32 charPosition);
|
||||
BString& InsertChars(const char* string, int32 charCount,
|
||||
int32 charPosition);
|
||||
BString& InsertChars(const char* string,
|
||||
int32 fromCharOffset, int32 charCount,
|
||||
int32 charPosition);
|
||||
BString& InsertChars(const BString& string,
|
||||
int32 charPosition);
|
||||
BString& InsertChars(const BString& string, int32 charCount,
|
||||
int32 charPosition);
|
||||
BString& InsertChars(const BString& string,
|
||||
int32 fromCharOffset, int32 charCount,
|
||||
int32 charPosition);
|
||||
|
||||
BString &Remove(int32 from, int32 length);
|
||||
// Removing
|
||||
BString& Truncate(int32 newLength, bool lazy = true);
|
||||
BString& TruncateChars(int32 newCharCount, bool lazy = true);
|
||||
|
||||
BString &RemoveFirst(const BString &);
|
||||
BString &RemoveLast(const BString &);
|
||||
BString &RemoveAll(const BString &);
|
||||
BString& Remove(int32 from, int32 length);
|
||||
BString& RemoveChars(int32 fromCharOffset, int32 charCount);
|
||||
|
||||
BString &RemoveFirst(const char *);
|
||||
BString &RemoveLast(const char *);
|
||||
BString &RemoveAll(const char *);
|
||||
BString& RemoveFirst(const BString& string);
|
||||
BString& RemoveLast(const BString& string);
|
||||
BString& RemoveAll(const BString& string);
|
||||
|
||||
BString &RemoveSet(const char *setOfCharsToRemove);
|
||||
BString& RemoveFirst(const char* string);
|
||||
BString& RemoveLast(const char* string);
|
||||
BString& RemoveAll(const char* string);
|
||||
|
||||
BString &MoveInto(BString &into, int32 from, int32 length);
|
||||
void MoveInto(char *into, int32 from, int32 length);
|
||||
/* caller guarantees that <into> is large enough */
|
||||
BString& RemoveSet(const char* setOfBytesToRemove);
|
||||
BString& RemoveCharsSet(const char* setOfCharsToRemove);
|
||||
|
||||
BString& MoveInto(BString& into, int32 from, int32 length);
|
||||
void MoveInto(char* into, int32 from, int32 length);
|
||||
|
||||
/*---- Compare functions ---------------------------------------------------*/
|
||||
bool operator<(const BString &) const;
|
||||
bool operator<=(const BString &) const;
|
||||
bool operator==(const BString &) const;
|
||||
bool operator>=(const BString &) const;
|
||||
bool operator>(const BString &) const;
|
||||
bool operator!=(const BString &) const;
|
||||
BString& MoveCharsInto(BString& into, int32 fromCharOffset,
|
||||
int32 charCount);
|
||||
bool MoveCharsInto(char* into, int32* intoLength,
|
||||
int32 fromCharOffset, int32 charCount);
|
||||
|
||||
bool operator<(const char *) const;
|
||||
bool operator<=(const char *) const;
|
||||
bool operator==(const char *) const;
|
||||
bool operator>=(const char *) const;
|
||||
bool operator>(const char *) const;
|
||||
bool operator!=(const char *) const;
|
||||
// Compare functions
|
||||
bool operator<(const BString& string) const;
|
||||
bool operator<=(const BString& string) const;
|
||||
bool operator==(const BString& string) const;
|
||||
bool operator>=(const BString& string) const;
|
||||
bool operator>(const BString& string) const;
|
||||
bool operator!=(const BString& string) const;
|
||||
|
||||
/*---- strcmp-style compare functions --------------------------------------*/
|
||||
int Compare(const BString &) const;
|
||||
int Compare(const char *) const;
|
||||
int Compare(const BString &, int32 n) const;
|
||||
int Compare(const char *, int32 n) const;
|
||||
int ICompare(const BString &) const;
|
||||
int ICompare(const char *) const;
|
||||
int ICompare(const BString &, int32 n) const;
|
||||
int ICompare(const char *, int32 n) const;
|
||||
bool operator<(const char* string) const;
|
||||
bool operator<=(const char* string) const;
|
||||
bool operator==(const char* string) const;
|
||||
bool operator>=(const char* string) const;
|
||||
bool operator>(const char* string) const;
|
||||
bool operator!=(const char* string) const;
|
||||
|
||||
/*---- Searching -----------------------------------------------------------*/
|
||||
int32 FindFirst(const BString &) const;
|
||||
int32 FindFirst(const char *) const;
|
||||
int32 FindFirst(const BString &, int32 fromOffset) const;
|
||||
int32 FindFirst(const char *, int32 fromOffset) const;
|
||||
int32 FindFirst(char) const;
|
||||
int32 FindFirst(char, int32 fromOffset) const;
|
||||
operator const char*() const;
|
||||
|
||||
int32 FindLast(const BString &) const;
|
||||
int32 FindLast(const char *) const;
|
||||
int32 FindLast(const BString &, int32 beforeOffset) const;
|
||||
int32 FindLast(const char *, int32 beforeOffset) const;
|
||||
int32 FindLast(char) const;
|
||||
int32 FindLast(char, int32 beforeOffset) const;
|
||||
// strcmp()-style compare functions
|
||||
int Compare(const BString& string) const;
|
||||
int Compare(const char* string) const;
|
||||
int Compare(const BString& string, int32 length) const;
|
||||
int Compare(const char* string, int32 length) const;
|
||||
|
||||
int32 IFindFirst(const BString &) const;
|
||||
int32 IFindFirst(const char *) const;
|
||||
int32 IFindFirst(const BString &, int32 fromOffset) const;
|
||||
int32 IFindFirst(const char *, int32 fromOffset) const;
|
||||
int CompareChars(const BString& string,
|
||||
int32 charCount) const;
|
||||
int CompareChars(const char* string,
|
||||
int32 charCount) const;
|
||||
|
||||
int32 IFindLast(const BString &) const;
|
||||
int32 IFindLast(const char *) const;
|
||||
int32 IFindLast(const BString &, int32 beforeOffset) const;
|
||||
int32 IFindLast(const char *, int32 beforeOffset) const;
|
||||
int ICompare(const BString& string) const;
|
||||
int ICompare(const char* string) const;
|
||||
int ICompare(const BString& string, int32 length) const;
|
||||
int ICompare(const char* string, int32 length) const;
|
||||
|
||||
/*---- Replacing -----------------------------------------------------------*/
|
||||
// Searching
|
||||
int32 FindFirst(const BString& string) const;
|
||||
int32 FindFirst(const char* string) const;
|
||||
int32 FindFirst(const BString& string,
|
||||
int32 fromOffset) const;
|
||||
int32 FindFirst(const char* string,
|
||||
int32 fromOffset) const;
|
||||
int32 FindFirst(char c) const;
|
||||
int32 FindFirst(char c, int32 fromOffset) const;
|
||||
|
||||
BString &ReplaceFirst(char replaceThis, char withThis);
|
||||
BString &ReplaceLast(char replaceThis, char withThis);
|
||||
BString &ReplaceAll(char replaceThis, char withThis,
|
||||
int32 fromOffset = 0);
|
||||
BString &Replace(char replaceThis, char withThis,
|
||||
int32 maxReplaceCount, int32 fromOffset = 0);
|
||||
BString &ReplaceFirst(const char *replaceThis,
|
||||
const char *withThis);
|
||||
BString &ReplaceLast(const char *replaceThis,
|
||||
const char *withThis);
|
||||
BString &ReplaceAll(const char *replaceThis,
|
||||
const char *withThis, int32 fromOffset = 0);
|
||||
BString &Replace(const char *replaceThis, const char *withThis,
|
||||
int32 maxReplaceCount, int32 fromOffset = 0);
|
||||
int32 FindFirstChars(const BString& string,
|
||||
int32 fromCharOffset) const;
|
||||
int32 FindFirstChars(const char* string,
|
||||
int32 fromCharOffset) const;
|
||||
|
||||
BString &IReplaceFirst(char replaceThis, char withThis);
|
||||
BString &IReplaceLast(char replaceThis, char withThis);
|
||||
BString &IReplaceAll(char replaceThis, char withThis,
|
||||
int32 fromOffset = 0);
|
||||
BString &IReplace(char replaceThis, char withThis,
|
||||
int32 maxReplaceCount, int32 fromOffset = 0);
|
||||
BString &IReplaceFirst(const char *replaceThis,
|
||||
const char *withThis);
|
||||
BString &IReplaceLast(const char *replaceThis,
|
||||
const char *withThis);
|
||||
BString &IReplaceAll(const char *replaceThis,
|
||||
const char *withThis, int32 fromOffset = 0);
|
||||
BString &IReplace(const char *replaceThis, const char *withThis,
|
||||
int32 maxReplaceCount, int32 fromOffset = 0);
|
||||
int32 FindLast(const BString& string) const;
|
||||
int32 FindLast(const char* string) const;
|
||||
int32 FindLast(const BString& string,
|
||||
int32 beforeOffset) const;
|
||||
int32 FindLast(const char* string,
|
||||
int32 beforeOffset) const;
|
||||
int32 FindLast(char c) const;
|
||||
int32 FindLast(char c, int32 beforeOffset) const;
|
||||
|
||||
BString &ReplaceSet(const char *setOfChars, char with);
|
||||
BString &ReplaceSet(const char *setOfChars, const char *with);
|
||||
/*---- Unchecked char access -----------------------------------------------*/
|
||||
char operator[](int32 index) const;
|
||||
char &operator[](int32 index);
|
||||
int32 FindLastChars(const BString& string,
|
||||
int32 beforeCharOffset) const;
|
||||
int32 FindLastChars(const char* string,
|
||||
int32 beforeCharOffset) const;
|
||||
|
||||
/*---- Checked char access -------------------------------------------------*/
|
||||
char ByteAt(int32 index) const;
|
||||
int32 IFindFirst(const BString& string) const;
|
||||
int32 IFindFirst(const char* string) const;
|
||||
int32 IFindFirst(const BString& string,
|
||||
int32 fromOffset) const;
|
||||
int32 IFindFirst(const char* string,
|
||||
int32 fromOffset) const;
|
||||
|
||||
/*---- Fast low-level manipulation -----------------------------------------*/
|
||||
char *LockBuffer(int32 maxLength);
|
||||
int32 IFindLast(const BString& string) const;
|
||||
int32 IFindLast(const char* string) const;
|
||||
int32 IFindLast(const BString& string,
|
||||
int32 beforeOffset) const;
|
||||
int32 IFindLast(const char* string,
|
||||
int32 beforeOffset) const;
|
||||
|
||||
/* Make room for characters to be added by C-string like manipulation.
|
||||
* Returns the equivalent of String(), <maxLength> includes space for
|
||||
* trailing zero while used as C-string, it is illegal to call other
|
||||
* BString routines that rely on data/length consistency until
|
||||
* UnlockBuffer sets things up again.
|
||||
*/
|
||||
// Replacing
|
||||
BString& ReplaceFirst(char replaceThis, char withThis);
|
||||
BString& ReplaceLast(char replaceThis, char withThis);
|
||||
BString& ReplaceAll(char replaceThis, char withThis,
|
||||
int32 fromOffset = 0);
|
||||
BString& Replace(char replaceThis, char withThis,
|
||||
int32 maxReplaceCount, int32 fromOffset = 0);
|
||||
BString& ReplaceFirst(const char* replaceThis,
|
||||
const char* withThis);
|
||||
BString& ReplaceLast(const char* replaceThis,
|
||||
const char* withThis);
|
||||
BString& ReplaceAll(const char* replaceThis,
|
||||
const char* withThis, int32 fromOffset = 0);
|
||||
BString& Replace(const char* replaceThis,
|
||||
const char* withThis, int32 maxReplaceCount,
|
||||
int32 fromOffset = 0);
|
||||
|
||||
BString &UnlockBuffer(int32 length = -1);
|
||||
BString& ReplaceAllChars(const char* replaceThis,
|
||||
const char* withThis, int32 fromCharOffset);
|
||||
BString& ReplaceChars(const char* replaceThis,
|
||||
const char* withThis, int32 maxReplaceCount,
|
||||
int32 fromCharOffset);
|
||||
|
||||
/* Finish using BString as C-string, adjusting length. If no length
|
||||
* passed in, strlen of internal data is used to determine it.
|
||||
* BString is in consistent state after this.
|
||||
*/
|
||||
BString& IReplaceFirst(char replaceThis, char withThis);
|
||||
BString& IReplaceLast(char replaceThis, char withThis);
|
||||
BString& IReplaceAll(char replaceThis, char withThis,
|
||||
int32 fromOffset = 0);
|
||||
BString& IReplace(char replaceThis, char withThis,
|
||||
int32 maxReplaceCount, int32 fromOffset = 0);
|
||||
BString& IReplaceFirst(const char* replaceThis,
|
||||
const char* withThis);
|
||||
BString& IReplaceLast(const char* replaceThis,
|
||||
const char* withThis);
|
||||
BString& IReplaceAll(const char* replaceThis,
|
||||
const char* withThis, int32 fromOffset = 0);
|
||||
BString& IReplace(const char* replaceThis,
|
||||
const char* withThis, int32 maxReplaceCount,
|
||||
int32 fromOffset = 0);
|
||||
|
||||
/*---- Upercase<->Lowercase ------------------------------------------------*/
|
||||
BString &ToLower();
|
||||
BString &ToUpper();
|
||||
BString& ReplaceSet(const char* setOfBytes, char with);
|
||||
BString& ReplaceSet(const char* setOfBytes,
|
||||
const char* with);
|
||||
|
||||
BString &Capitalize();
|
||||
/* Converts first character to upper-case, rest to
|
||||
* lower-case
|
||||
*/
|
||||
BString& ReplaceCharsSet(const char* setOfChars,
|
||||
const char* with);
|
||||
|
||||
BString &CapitalizeEachWord();
|
||||
/* Converts first character in each
|
||||
* non-alphabethycal-character-separated
|
||||
* word to upper-case, rest to lower-case
|
||||
*/
|
||||
/*----- Escaping and Deescaping --------------------------------------------*/
|
||||
BString &CharacterEscape(const char *original,
|
||||
const char *setOfCharsToEscape, char escapeWith);
|
||||
/* copies original into <this>, escaping characters
|
||||
* specified in <setOfCharsToEscape> by prepending
|
||||
* them with <escapeWith>
|
||||
*/
|
||||
BString &CharacterEscape(const char *setOfCharsToEscape,
|
||||
char escapeWith);
|
||||
/* escapes characters specified in <setOfCharsToEscape>
|
||||
* by prepending them with <escapeWith>
|
||||
*/
|
||||
// Unchecked char access
|
||||
char operator[](int32 index) const;
|
||||
|
||||
BString &CharacterDeescape(const char *original, char escapeChar);
|
||||
/* copy <original> into the string removing the escaping
|
||||
* characters <escapeChar>
|
||||
*/
|
||||
BString &CharacterDeescape(char escapeChar);
|
||||
/* remove the escaping characters <escapeChar> from
|
||||
* the string
|
||||
*/
|
||||
|
||||
/*---- Simple sprintf replacement calls ------------------------------------*/
|
||||
/*---- Slower than sprintf but type and overflow safe ----------------------*/
|
||||
BString &operator<<(const char *);
|
||||
BString &operator<<(const BString &);
|
||||
BString &operator<<(char);
|
||||
BString &operator<<(int);
|
||||
BString &operator<<(unsigned int);
|
||||
BString &operator<<(unsigned long);
|
||||
BString &operator<<(long);
|
||||
BString &operator<<(unsigned long long);
|
||||
BString &operator<<(long long);
|
||||
BString &operator<<(float);
|
||||
/* float output hardcodes %.2f style formatting */
|
||||
|
||||
/*----- Private or reserved ------------------------------------------------*/
|
||||
private:
|
||||
void _Init(const char *, int32);
|
||||
void _DoAssign(const char *, int32);
|
||||
void _DoAppend(const char *, int32);
|
||||
char *_GrowBy(int32);
|
||||
char *_OpenAtBy(int32, int32);
|
||||
char *_ShrinkAtBy(int32, int32);
|
||||
void _DoPrepend(const char *, int32);
|
||||
|
||||
int32 _FindAfter(const char *, int32, int32) const;
|
||||
int32 _IFindAfter(const char *, int32, int32) const;
|
||||
int32 _ShortFindAfter(const char *, int32) const;
|
||||
int32 _FindBefore(const char *, int32, int32) const;
|
||||
int32 _IFindBefore(const char *, int32, int32) const;
|
||||
BString &_DoReplace(const char *, const char *, int32, int32,
|
||||
bool);
|
||||
void _SetLength(int32);
|
||||
|
||||
#if DEBUG
|
||||
void _SetUsingAsCString(bool);
|
||||
void _AssertNotUsingAsCString() const;
|
||||
#if __GNUC__ > 3
|
||||
BStringRef operator[](int32 index);
|
||||
#else
|
||||
void _SetUsingAsCString(bool) {}
|
||||
void _AssertNotUsingAsCString() const {}
|
||||
char& operator[](int32 index);
|
||||
#endif
|
||||
|
||||
char *_Alloc( int32);
|
||||
// Checked char access
|
||||
char ByteAt(int32 index) const;
|
||||
const char* CharAt(int32 charIndex, int32* bytes = NULL) const;
|
||||
bool CharAt(int32 charIndex, char* buffer,
|
||||
int32* bytes) const;
|
||||
|
||||
struct PosVect;
|
||||
void _ReplaceAtPositions( const PosVect* positions,
|
||||
int32 searchLen,
|
||||
const char* with,
|
||||
int32 withLen);
|
||||
// Fast low-level manipulation
|
||||
char* LockBuffer(int32 maxLength);
|
||||
BString& UnlockBuffer(int32 length = -1);
|
||||
|
||||
protected:
|
||||
char *_privateData;
|
||||
// Upercase <-> Lowercase
|
||||
BString& ToLower();
|
||||
BString& ToUpper();
|
||||
|
||||
BString& Capitalize();
|
||||
BString& CapitalizeEachWord();
|
||||
|
||||
// Escaping and De-escaping
|
||||
BString& CharacterEscape(const char* original,
|
||||
const char* setOfCharsToEscape,
|
||||
char escapeWith);
|
||||
BString& CharacterEscape(const char* setOfCharsToEscape,
|
||||
char escapeWith);
|
||||
BString& CharacterDeescape(const char* original,
|
||||
char escapeChar);
|
||||
BString& CharacterDeescape(char escapeChar);
|
||||
|
||||
// Trimming
|
||||
BString& Trim();
|
||||
|
||||
// Insert
|
||||
BString& operator<<(const char* string);
|
||||
BString& operator<<(const BString& string);
|
||||
BString& operator<<(char c);
|
||||
BString& operator<<(int value);
|
||||
BString& operator<<(unsigned int value);
|
||||
BString& operator<<(unsigned long value);
|
||||
BString& operator<<(long value);
|
||||
BString& operator<<(unsigned long long value);
|
||||
BString& operator<<(long long value);
|
||||
// float output hardcodes %.2f style formatting
|
||||
BString& operator<<(float value);
|
||||
|
||||
private:
|
||||
class PosVect;
|
||||
friend class BStringRef;
|
||||
|
||||
// Management
|
||||
status_t _MakeWritable();
|
||||
status_t _MakeWritable(int32 length, bool copy);
|
||||
static char* _Allocate(int32 length);
|
||||
char* _Resize(int32 length);
|
||||
void _Init(const char* src, int32 length);
|
||||
char* _Clone(const char* data, int32 length);
|
||||
char* _OpenAtBy(int32 offset, int32 length);
|
||||
char* _ShrinkAtBy(int32 offset, int32 length);
|
||||
|
||||
// Data
|
||||
void _SetLength(int32 length);
|
||||
bool _DoAppend(const char* string, int32 length);
|
||||
bool _DoPrepend(const char* string, int32 length);
|
||||
bool _DoInsert(const char* string, int32 offset,
|
||||
int32 length);
|
||||
|
||||
// Search
|
||||
int32 _ShortFindAfter(const char* string,
|
||||
int32 length) const;
|
||||
int32 _FindAfter(const char* string, int32 offset,
|
||||
int32 length) const;
|
||||
int32 _IFindAfter(const char* string, int32 offset,
|
||||
int32 length) const;
|
||||
int32 _FindBefore(const char* string, int32 offset,
|
||||
int32 length) const;
|
||||
int32 _IFindBefore(const char* string, int32 offset,
|
||||
int32 length) const;
|
||||
|
||||
// Escape
|
||||
BString& _DoCharacterEscape(const char* string,
|
||||
const char *setOfCharsToEscape, char escapeChar);
|
||||
BString& _DoCharacterDeescape(const char* string,
|
||||
char escapeChar);
|
||||
|
||||
// Replace
|
||||
BString& _DoReplace(const char* findThis,
|
||||
const char* replaceWith, int32 maxReplaceCount,
|
||||
int32 fromOffset, bool ignoreCase);
|
||||
void _ReplaceAtPositions(const PosVect* positions,
|
||||
int32 searchLength, const char* with,
|
||||
int32 withLength);
|
||||
|
||||
private:
|
||||
vint32& _ReferenceCount();
|
||||
const vint32& _ReferenceCount() const;
|
||||
bool _IsShareable() const;
|
||||
void _FreePrivateData();
|
||||
|
||||
char* fPrivateData;
|
||||
};
|
||||
|
||||
/*----- Comutative compare operators --------------------------------------*/
|
||||
bool operator<(const char *, const BString &);
|
||||
bool operator<=(const char *, const BString &);
|
||||
bool operator==(const char *, const BString &);
|
||||
bool operator>(const char *, const BString &);
|
||||
bool operator>=(const char *, const BString &);
|
||||
bool operator!=(const char *, const BString &);
|
||||
|
||||
/*----- Non-member compare for sorting, etc. ------------------------------*/
|
||||
int Compare(const BString &, const BString &);
|
||||
int ICompare(const BString &, const BString &);
|
||||
int Compare(const BString *, const BString *);
|
||||
int ICompare(const BString *, const BString *);
|
||||
// Commutative compare operators
|
||||
bool operator<(const char* a, const BString& b);
|
||||
bool operator<=(const char* a, const BString& b);
|
||||
bool operator==(const char* a, const BString& b);
|
||||
bool operator>(const char* a, const BString& b);
|
||||
bool operator>=(const char* a, const BString& b);
|
||||
bool operator!=(const char* a, const BString& b);
|
||||
|
||||
|
||||
// Non-member compare for sorting, etc.
|
||||
int Compare(const BString& a, const BString& b);
|
||||
int ICompare(const BString& a, const BString& b);
|
||||
int Compare(const BString* a, const BString* b);
|
||||
int ICompare(const BString* a, const BString* b);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/*---- No user serviceable parts after this -------------------------------*/
|
||||
|
||||
inline int32
|
||||
BString::Length() const
|
||||
{
|
||||
return _privateData ? (*((int32 *)_privateData - 1) & 0x7fffffff) : 0;
|
||||
/* the most significant bit is reserved; accessing
|
||||
* it in any way will cause the computer to explode
|
||||
*/
|
||||
// the most significant bit is reserved; accessing
|
||||
// it in any way will cause the computer to explode
|
||||
return fPrivateData ? (*(((int32 *)fPrivateData) - 1) & 0x7fffffff) : 0;
|
||||
}
|
||||
|
||||
inline const char *
|
||||
|
||||
inline const char*
|
||||
BString::String() const
|
||||
{
|
||||
if (!_privateData)
|
||||
if (!fPrivateData)
|
||||
return "";
|
||||
return _privateData;
|
||||
return fPrivateData;
|
||||
}
|
||||
|
||||
|
||||
inline BString &
|
||||
BString::SetTo(const char *str)
|
||||
BString::SetTo(const char* string)
|
||||
{
|
||||
return operator=(str);
|
||||
return operator=(string);
|
||||
}
|
||||
|
||||
|
||||
inline char
|
||||
BString::operator[](int32 index) const
|
||||
{
|
||||
return _privateData[index];
|
||||
return fPrivateData[index];
|
||||
}
|
||||
|
||||
|
||||
inline char
|
||||
BString::ByteAt(int32 index) const
|
||||
{
|
||||
if (!_privateData || index < 0 || index > Length())
|
||||
if (!fPrivateData || index < 0 || index >= Length())
|
||||
return 0;
|
||||
return _privateData[index];
|
||||
return fPrivateData[index];
|
||||
}
|
||||
|
||||
|
||||
inline BString &
|
||||
BString::operator+=(const BString &string)
|
||||
{
|
||||
@@ -395,6 +434,7 @@ BString::operator+=(const BString &string)
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline BString &
|
||||
BString::Append(const BString &string)
|
||||
{
|
||||
@@ -402,88 +442,131 @@ BString::Append(const BString &string)
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline BString &
|
||||
BString::Append(const char *str)
|
||||
BString::Append(const char* string)
|
||||
{
|
||||
return operator+=(str);
|
||||
return operator+=(string);
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
BString::operator==(const BString &string) const
|
||||
{
|
||||
return strcmp(String(), string.String()) == 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
BString::operator<(const BString &string) const
|
||||
{
|
||||
return strcmp(String(), string.String()) < 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
BString::operator<=(const BString &string) const
|
||||
{
|
||||
return strcmp(String(), string.String()) <= 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
BString::operator>=(const BString &string) const
|
||||
{
|
||||
return strcmp(String(), string.String()) >= 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
BString::operator>(const BString &string) const
|
||||
{
|
||||
return strcmp(String(), string.String()) > 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
BString::operator!=(const BString &string) const
|
||||
{
|
||||
return strcmp(String(), string.String()) != 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
BString::operator!=(const char *str) const
|
||||
BString::operator!=(const char* string) const
|
||||
{
|
||||
return !operator==(str);
|
||||
return !operator==(string);
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
BString::operator const char*() const
|
||||
{
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator<(const char *str, const BString &string)
|
||||
{
|
||||
return string > str;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator<=(const char *str, const BString &string)
|
||||
{
|
||||
return string >= str;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator==(const char *str, const BString &string)
|
||||
{
|
||||
return string == str;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator>(const char *str, const BString &string)
|
||||
{
|
||||
return string < str;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator>=(const char *str, const BString &string)
|
||||
{
|
||||
return string <= str;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator!=(const char *str, const BString &string)
|
||||
{
|
||||
return string != str;
|
||||
}
|
||||
|
||||
#endif /* __BSTRING__ */
|
||||
|
||||
// #pragma mark - BStringRef
|
||||
|
||||
|
||||
class BStringRef {
|
||||
public:
|
||||
BStringRef(BString& string, int32 position);
|
||||
~BStringRef() {}
|
||||
|
||||
operator char() const;
|
||||
|
||||
char* operator&();
|
||||
const char* operator&() const;
|
||||
|
||||
BStringRef& operator=(char c);
|
||||
BStringRef& operator=(const BStringRef& rc);
|
||||
|
||||
private:
|
||||
BString& fString;
|
||||
int32 fPosition;
|
||||
};
|
||||
|
||||
#endif // __BSTRING__
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2004-2010, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _UTF8_FUNCTIONS_H
|
||||
#define _UTF8_FUNCTIONS_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
static inline bool
|
||||
IsInsideGlyph(uchar ch)
|
||||
{
|
||||
return (ch & 0xc0) == 0x80;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
UTF8NextCharLenUnsafe(const char *text)
|
||||
{
|
||||
const char *ptr = text;
|
||||
|
||||
do {
|
||||
ptr++;
|
||||
} while (IsInsideGlyph(*ptr));
|
||||
|
||||
return ptr - text;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
UTF8NextCharLen(const char *text)
|
||||
{
|
||||
if (text == NULL || *text == 0)
|
||||
return 0;
|
||||
|
||||
return UTF8NextCharLenUnsafe(text);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
UTF8PreviousCharLen(const char *text, const char *limit)
|
||||
{
|
||||
const char *ptr = text;
|
||||
|
||||
if (ptr == NULL || limit == NULL)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
if (ptr == limit)
|
||||
break;
|
||||
ptr--;
|
||||
} while (IsInsideGlyph(*ptr));
|
||||
|
||||
return text - ptr;
|
||||
}
|
||||
|
||||
|
||||
/*! UTF8CountBytes gets the length (in bytes) of a UTF8 string. Up to
|
||||
numChars characters are read. If numChars is a negative value it is ignored
|
||||
and the string is read up to the terminating 0.
|
||||
*/
|
||||
static inline uint32
|
||||
UTF8CountBytes(const char *bytes, int32 numChars)
|
||||
{
|
||||
if (bytes == NULL)
|
||||
return 0;
|
||||
|
||||
if (numChars < 0)
|
||||
numChars = INT_MAX;
|
||||
|
||||
const char *base = bytes;
|
||||
while (bytes[0] != '\0') {
|
||||
if ((bytes[0] & 0xc0) != 0x80) {
|
||||
if (--numChars < 0)
|
||||
break;
|
||||
}
|
||||
bytes++;
|
||||
}
|
||||
|
||||
return bytes - base;
|
||||
}
|
||||
|
||||
|
||||
/*! UTF8CountChars gets the length (in characters) of a UTF8 string. Up to
|
||||
numBytes bytes are read. If numBytes is a negative value it is ignored
|
||||
and the string is read up to the terminating 0.
|
||||
*/
|
||||
static inline uint32
|
||||
UTF8CountChars(const char *bytes, int32 numBytes)
|
||||
{
|
||||
if (bytes == NULL)
|
||||
return 0;
|
||||
|
||||
uint32 length = 0;
|
||||
const char *last;
|
||||
if (numBytes < 0)
|
||||
last = (const char *)SIZE_MAX;
|
||||
else
|
||||
last = bytes + numBytes - 1;
|
||||
|
||||
while (bytes[0] && bytes <= last) {
|
||||
if ((bytes++[0] & 0xc0) != 0x80)
|
||||
length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/*! UTF8ToCharCode converts the input that includes potential multibyte chars
|
||||
to UTF-32 char codes that can be used by FreeType. The string pointer is
|
||||
then advanced to the next character in the string. In case the terminating
|
||||
0 is reached, the string pointer is not advanced anymore and nulls are
|
||||
returned. This makes it safe to overruns and enables streamed processing
|
||||
of UTF8 strings.
|
||||
*/
|
||||
static inline uint32
|
||||
UTF8ToCharCode(const char **bytes)
|
||||
{
|
||||
#define UTF8_SUBSTITUTE_CHARACTER 0xfffd
|
||||
|
||||
uint32 result;
|
||||
if (((*bytes)[0] & 0x80) == 0) {
|
||||
// a single byte character
|
||||
result = (*bytes)[0];
|
||||
if (result != '\0') {
|
||||
// do not advance beyond the terminating '\0'
|
||||
(*bytes)++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (((*bytes)[0] & 0xc0) == 0x80) {
|
||||
// not a proper multibyte start
|
||||
(*bytes)++;
|
||||
return UTF8_SUBSTITUTE_CHARACTER;
|
||||
}
|
||||
|
||||
// start of a multibyte character
|
||||
uint8 mask = 0x80;
|
||||
result = (uint32)((*bytes)[0] & 0xff);
|
||||
(*bytes)++;
|
||||
|
||||
while (result & mask) {
|
||||
if (mask == 0x02) {
|
||||
// seven byte char - invalid
|
||||
return UTF8_SUBSTITUTE_CHARACTER;
|
||||
}
|
||||
|
||||
result &= ~mask;
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
while (((*bytes)[0] & 0xc0) == 0x80) {
|
||||
result <<= 6;
|
||||
result += (*bytes)[0] & 0x3f;
|
||||
(*bytes)++;
|
||||
|
||||
mask <<= 1;
|
||||
if (mask == 0x40)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mask == 0x40)
|
||||
return result;
|
||||
|
||||
if ((*bytes)[0] == '\0') {
|
||||
// string terminated within multibyte char
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
// not enough bytes in multibyte char
|
||||
return UTF8_SUBSTITUTE_CHARACTER;
|
||||
|
||||
#undef UTF8_SUBSTITUTE_CHARACTER
|
||||
}
|
||||
|
||||
#endif // _UTF8_FUNCTIONS_H
|
||||
Reference in New Issue
Block a user