8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Make fb_string's length limit type-dependent

This commit is contained in:
alexpeshkoff 2010-11-04 16:22:42 +00:00
parent 3c4a864677
commit db866e3a45
2 changed files with 84 additions and 48 deletions

View File

@ -87,20 +87,23 @@ namespace Firebird
{
const AbstractString::size_type AbstractString::npos = (AbstractString::size_type)(~0);
AbstractString::AbstractString(const AbstractString& v)
AbstractString::AbstractString(const size_type limit, const AbstractString& v)
: max_length(limit)
{
initialize(v.length());
memcpy(stringBuffer, v.c_str(), v.length());
}
AbstractString::AbstractString(const size_type sizeL, const void* dataL)
AbstractString::AbstractString(const size_type limit, const size_type sizeL, const void* dataL)
: max_length(limit)
{
initialize(sizeL);
memcpy(stringBuffer, dataL, sizeL);
}
AbstractString::AbstractString(const_pointer p1, const size_type n1,
AbstractString::AbstractString(const size_type limit, const_pointer p1, const size_type n1,
const_pointer p2, const size_type n2)
: max_length(limit)
{
// CVC: npos must be maximum size_type value for all platforms.
// fb_assert(n2 < npos - n1 && n1 + n2 <= max_length());
@ -114,7 +117,8 @@ namespace Firebird
memcpy(stringBuffer + n1, p2, n2);
}
AbstractString::AbstractString(const size_type sizeL, char_type c)
AbstractString::AbstractString(const size_type limit, const size_type sizeL, char_type c)
: max_length(limit)
{
initialize(sizeL);
memset(stringBuffer, c, sizeL);
@ -175,8 +179,8 @@ namespace Firebird
void AbstractString::reserve(size_type n)
{
// Do not allow to reserve huge buffers
if (n > max_length())
n = max_length();
if (n > getMaxLength())
n = getMaxLength();
reserveBuffer(n);
}
@ -426,16 +430,16 @@ extern "C" {
while (true)
{
n *= 2;
if (n > max_length())
n = max_length();
if (n > getMaxLength())
n = getMaxLength();
FB_VA_COPY(paramsCopy, params);
l = VSNPRINTF(baseAssign(n), n + 1, format, paramsCopy);
FB_CLOSE_VACOPY(paramsCopy);
if (l >= 0)
break;
if (n >= max_length())
if (n >= getMaxLength())
{
stringBuffer[max_length()] = 0;
stringBuffer[getMaxLength()] = 0;
return;
}
}

View File

@ -58,7 +58,12 @@ namespace Firebird
enum {INLINE_BUFFER_SIZE = 32, INIT_RESERVE = 16/*, KEEP_SIZE = 512*/};
protected:
typedef USHORT internal_size_type; // 16 bits!
typedef ULONG internal_size_type; // 32 bits!
private:
const internal_size_type max_length;
protected:
char_type inlineBuffer[INLINE_BUFFER_SIZE];
char_type* stringBuffer;
internal_size_type stringLength, bufferSize;
@ -71,9 +76,9 @@ namespace Firebird
}
}
static void checkLength(size_type len)
void checkLength(size_type len)
{
if (len > max_length()) {
if (len > getMaxLength()) {
fatal_exception::raise("Firebird::string - length exceeds predefined limit");
}
}
@ -95,8 +100,9 @@ namespace Firebird
newSize = size_t(bufferSize) * 2u;
// Do not grow buffer beyond string length limit
if (newSize > max_length() + 1)
newSize = max_length() + 1;
size_type max_length = getMaxLength() + 1;
if (newSize > max_length)
newSize = max_length;
// Allocate new buffer
char_type *newBuffer = FB_NEW(getPool()) char_type[newSize];
@ -130,8 +136,9 @@ namespace Firebird
size_type newSize = len + 1 + INIT_RESERVE;
// Do not grow buffer beyond string length limit
if (newSize > max_length() + 1)
newSize = max_length() + 1;
size_type max_length = getMaxLength() + 1;
if (newSize > max_length)
newSize = max_length;
// Allocate new buffer
stringBuffer = FB_NEW(getPool()) char_type[newSize];
@ -147,36 +154,36 @@ namespace Firebird
}
protected:
AbstractString(const size_type sizeL, const void* datap);
AbstractString(const size_type limit, const size_type sizeL, const void* datap);
AbstractString(const_pointer p1, const size_type n1,
AbstractString(const size_type limit, const_pointer p1, const size_type n1,
const_pointer p2, const size_type n2);
AbstractString(const AbstractString& v);
AbstractString(const size_type limit, const AbstractString& v);
AbstractString() :
stringBuffer(inlineBuffer), stringLength(0), bufferSize(INLINE_BUFFER_SIZE)
AbstractString(const size_type limit) :
max_length(limit), stringBuffer(inlineBuffer), stringLength(0), bufferSize(INLINE_BUFFER_SIZE)
{
stringBuffer[0] = 0;
}
AbstractString(const size_type sizeL, char_type c);
AbstractString(const size_type limit, const size_type sizeL, char_type c);
explicit AbstractString(MemoryPool& p) : AutoStorage(p),
stringBuffer(inlineBuffer), stringLength(0), bufferSize(INLINE_BUFFER_SIZE)
AbstractString(const size_type limit, MemoryPool& p) : AutoStorage(p),
max_length(limit), stringBuffer(inlineBuffer), stringLength(0), bufferSize(INLINE_BUFFER_SIZE)
{
stringBuffer[0] = 0;
}
AbstractString(MemoryPool& p, const AbstractString& v)
: AutoStorage(p)
AbstractString(const size_type limit, MemoryPool& p, const AbstractString& v)
: AutoStorage(p), max_length(limit)
{
initialize(v.length());
memcpy(stringBuffer, v.c_str(), stringLength);
}
AbstractString(MemoryPool& p, const void* s, const size_type l)
: AutoStorage(p)
AbstractString(const size_type limit, MemoryPool& p, const void* s, const size_type l)
: AutoStorage(p), max_length(limit)
{
initialize(l);
memcpy(stringBuffer, s, l);
@ -202,6 +209,11 @@ namespace Firebird
void baseTrim(const TrimType whereTrim, const_pointer toTrim);
size_type getMaxLength()
{
return max_length;
}
public:
const_pointer c_str() const
{
@ -351,10 +363,6 @@ namespace Firebird
{
return length();
}
static size_type max_length()
{
return 0xfffe; // Max length of character field in Firebird
}
size_type capacity() const
{
return bufferSize - 1u;
@ -574,47 +582,71 @@ namespace Firebird
{
return memcmp(s1, s2, n);
}
static AbstractString::size_type getMaxLength()
{
return 0xFFFFFFFEu;
}
};
class PathNameComparator
{
public:
static int compare(AbstractString::const_pointer s1,
AbstractString::const_pointer s2,
const AbstractString::size_type n);
static AbstractString::size_type getMaxLength()
{
return 0xFFFEu;
}
};
class IgnoreCaseComparator
{
public:
static int compare(AbstractString::const_pointer s1,
AbstractString::const_pointer s2,
const AbstractString::size_type n);
static AbstractString::size_type getMaxLength()
{
return 0xFFFFFFFEu;
}
};
template<typename Comparator>
class StringBase : public AbstractString
{
typedef StringBase<Comparator> StringType;
typedef StringBase StringType;
protected:
StringBase<Comparator>(const_pointer p1, size_type n1,
const_pointer p2, size_type n2) :
AbstractString(p1, n1, p2, n2) {}
StringBase(const_pointer p1, size_type n1,
const_pointer p2, size_type n2) :
AbstractString(Comparator::getMaxLength(), p1, n1, p2, n2) {}
private:
StringType add(const_pointer s, size_type n) const
{
return StringBase<Comparator>(c_str(), length(), s, n);
}
public:
StringBase<Comparator>() : AbstractString() {}
StringBase<Comparator>(const StringType& v) : AbstractString(v) {}
StringBase<Comparator>(const void* s, size_type n) : AbstractString(n, s) {}
StringBase<Comparator>(const_pointer s) : AbstractString(strlen(s), s) {}
explicit StringBase<Comparator>(const unsigned char* s) : AbstractString(strlen((char*)s), (char*)s) {}
StringBase<Comparator>(size_type n, char_type c) : AbstractString(n, c) {}
//explicit StringBase<Comparator>(char_type c) : AbstractString(1, c) {}
StringBase<Comparator>(const_iterator first, const_iterator last) : AbstractString(last - first, first) {}
explicit StringBase<Comparator>(MemoryPool& p) : AbstractString(p) {}
StringBase<Comparator>(MemoryPool& p, const AbstractString& v) : AbstractString(p, v) {}
StringBase<Comparator>(MemoryPool& p, const char_type* s, size_type l) : AbstractString(p, s, l) {}
StringBase() : AbstractString(Comparator::getMaxLength()) {}
StringBase(const StringType& v) : AbstractString(Comparator::getMaxLength(), v) {}
StringBase(const void* s, size_type n) : AbstractString(Comparator::getMaxLength(), n, s) {}
StringBase(const_pointer s) : AbstractString(Comparator::getMaxLength(), strlen(s), s) {}
explicit StringBase(const unsigned char* s) :
AbstractString(Comparator::getMaxLength(), strlen((char*)s), (char*)s) {}
StringBase(size_type n, char_type c) : AbstractString(Comparator::getMaxLength(), n, c) {}
StringBase(const_iterator first, const_iterator last) :
AbstractString(Comparator::getMaxLength(), last - first, first) {}
explicit StringBase(MemoryPool& p) : AbstractString(Comparator::getMaxLength(), p) {}
StringBase(MemoryPool& p, const AbstractString& v) : AbstractString(Comparator::getMaxLength(), p, v) {}
StringBase(MemoryPool& p, const char_type* s, size_type l) :
AbstractString(Comparator::getMaxLength(), p, s, l) {}
static size_type max_length()
{
return Comparator::getMaxLength();
}
StringType& assign(const StringType& str)
{