mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 04:43:03 +01:00
Little string class cleanups
This commit is contained in:
parent
9d12a94a36
commit
3b062b90b6
@ -75,7 +75,7 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
namespace Firebird {
|
||||
const AbstractString::size_type AbstractString::npos = ~0;
|
||||
const AbstractString::size_type AbstractString::npos = (AbstractString::size_type)(-1);
|
||||
|
||||
AbstractString::AbstractString(const AbstractString& v) {
|
||||
initialize(v.length());
|
||||
@ -114,8 +114,7 @@ namespace Firebird {
|
||||
}
|
||||
|
||||
AbstractString::pointer AbstractString::baseAssign(size_type n) {
|
||||
checkLength(n);
|
||||
reserveBuffer(n + 1);
|
||||
reserveBuffer(n);
|
||||
stringLength = n;
|
||||
stringBuffer[stringLength] = 0;
|
||||
shrinkBuffer(); // Shrink buffer if it is unneeded anymore
|
||||
@ -123,8 +122,7 @@ namespace Firebird {
|
||||
}
|
||||
|
||||
AbstractString::pointer AbstractString::baseAppend(size_type n) {
|
||||
checkLength(stringLength + n);
|
||||
reserveBuffer(stringLength + n + 1);
|
||||
reserveBuffer(stringLength + n);
|
||||
stringLength += n;
|
||||
stringBuffer[stringLength] = 0; // Set null terminator inside the new buffer
|
||||
return stringBuffer + stringLength - n;
|
||||
@ -134,8 +132,7 @@ namespace Firebird {
|
||||
if (p0 >= length()) {
|
||||
return baseAppend(n);
|
||||
}
|
||||
checkLength(stringLength + n);
|
||||
reserveBuffer(stringLength + n + 1);
|
||||
reserveBuffer(stringLength + n);
|
||||
memmove(stringBuffer + p0 + n, stringBuffer + p0,
|
||||
stringLength - p0 + 1); // Do not forget to move null terminator too
|
||||
stringLength += n;
|
||||
@ -151,7 +148,11 @@ namespace Firebird {
|
||||
}
|
||||
|
||||
void AbstractString::reserve(size_type n) {
|
||||
reserveBuffer(n + 1);
|
||||
// Do not allow to reserve huge buffers
|
||||
if (n > max_length())
|
||||
n = max_length();
|
||||
|
||||
reserveBuffer(n);
|
||||
}
|
||||
|
||||
void AbstractString::resize(size_type n, char_type c) {
|
||||
@ -159,8 +160,7 @@ namespace Firebird {
|
||||
return;
|
||||
}
|
||||
if (n > stringLength) {
|
||||
checkLength(n);
|
||||
reserveBuffer(n + 1);
|
||||
reserveBuffer(n);
|
||||
memset(stringBuffer + stringLength, c, n - stringLength);
|
||||
}
|
||||
stringLength = n;
|
||||
|
@ -42,8 +42,8 @@ namespace Firebird
|
||||
class AbstractString : private AutoStorage {
|
||||
public:
|
||||
typedef char char_type;
|
||||
typedef unsigned int size_type;
|
||||
typedef int difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef char* pointer;
|
||||
typedef const char* const_pointer;
|
||||
typedef char& reference;
|
||||
@ -54,9 +54,10 @@ namespace Firebird
|
||||
static const size_type npos;
|
||||
enum {INLINE_BUFFER_SIZE = 32, INIT_RESERVE = 16/*, KEEP_SIZE = 512*/};
|
||||
protected:
|
||||
typedef USHORT internal_size_type; // 16 bits!
|
||||
char_type inlineBuffer[INLINE_BUFFER_SIZE];
|
||||
char_type* stringBuffer;
|
||||
unsigned short stringLength, bufferSize;
|
||||
internal_size_type stringLength, bufferSize;
|
||||
private:
|
||||
inline void checkPos(size_type pos) const {
|
||||
if (pos >= length()) {
|
||||
@ -69,38 +70,62 @@ namespace Firebird
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we can store at least newSize characters in our buffer
|
||||
// (including null terminator). Existing contents of our string are preserved.
|
||||
void reserveBuffer(size_type newSize) {
|
||||
// Reserve buffer to allow storing at least newLen characters there
|
||||
// (not including null terminator). Existing contents of our string are preserved.
|
||||
void reserveBuffer(size_type newLen) {
|
||||
size_type newSize = newLen + 1;
|
||||
if (newSize > bufferSize) {
|
||||
// Make sure we do not exceed string length limit
|
||||
checkLength(newLen);
|
||||
|
||||
// Order of assignments below is important in case of low memory conditions
|
||||
|
||||
// Grow buffer exponentially to prevent memory fragmentation
|
||||
if (newSize < bufferSize * 2)
|
||||
newSize = bufferSize * 2;
|
||||
|
||||
// Do not grow buffer beyond string length limit
|
||||
if (newSize > max_length() + 1)
|
||||
newSize = max_length() + 1;
|
||||
|
||||
// Allocate new buffer
|
||||
char_type *newBuffer = FB_NEW(getPool()) char_type[newSize];
|
||||
|
||||
// Carefully copy string data including null terminator
|
||||
memcpy(newBuffer, stringBuffer, sizeof(char_type) * (stringLength + 1));
|
||||
|
||||
// Deallocate old buffer if needed
|
||||
if (stringBuffer != inlineBuffer)
|
||||
delete[] stringBuffer;
|
||||
|
||||
stringBuffer = newBuffer;
|
||||
bufferSize = newSize;
|
||||
bufferSize = static_cast<internal_size_type>(newSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure our buffer is large enough to store at least <length> characters in it
|
||||
// (not including null terminator). Resulting buffer is not initialized.
|
||||
// Use in constructors only when stringBuffer is not assigned yet.
|
||||
// Use it in constructors only when stringBuffer is not assigned yet.
|
||||
void initialize(size_type len) {
|
||||
size_type newSize = len + 1;
|
||||
if (newSize <= INLINE_BUFFER_SIZE) {
|
||||
if (len < INLINE_BUFFER_SIZE) {
|
||||
stringBuffer = inlineBuffer;
|
||||
bufferSize = INLINE_BUFFER_SIZE;
|
||||
} else {
|
||||
} else {
|
||||
stringBuffer = NULL; // Be safe in case of exception
|
||||
checkLength(len);
|
||||
|
||||
// Reserve a few extra bytes in the buffer
|
||||
size_type newSize = len + 1 + INIT_RESERVE;
|
||||
|
||||
// Do not grow buffer beyond string length limit
|
||||
if (newSize > max_length() + 1)
|
||||
newSize = max_length() + 1;
|
||||
|
||||
// Allocate new buffer
|
||||
stringBuffer = FB_NEW(getPool()) char_type[newSize];
|
||||
bufferSize = newSize;
|
||||
bufferSize = static_cast<internal_size_type>(newSize);
|
||||
}
|
||||
stringLength = len;
|
||||
stringLength = static_cast<internal_size_type>(len);
|
||||
stringBuffer[stringLength] = 0;
|
||||
}
|
||||
|
||||
@ -280,7 +305,7 @@ namespace Firebird
|
||||
return length();
|
||||
}
|
||||
static inline size_type max_length() {
|
||||
return 0xffff; // Max length of character field in Firebird
|
||||
return 0xfffe; // Max length of character field in Firebird
|
||||
}
|
||||
inline size_type capacity() const {
|
||||
return bufferSize - 1;
|
||||
|
Loading…
Reference in New Issue
Block a user