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:
parent
3c4a864677
commit
db866e3a45
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user