8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 18:43:03 +01:00
This commit is contained in:
asfernandes 2008-07-16 01:39:12 +00:00
parent b96703e879
commit 7f4f7b06d6
10 changed files with 116 additions and 77 deletions

View File

@ -70,13 +70,15 @@ template <typename T, typename Storage = EmptyStorage<T> >
class Array : protected Storage
{
public:
explicit Array(MemoryPool& p) :
Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage()) { }
Array(MemoryPool& p, const size_t InitialCapacity) :
Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage())
explicit Array(MemoryPool& p)
: Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage()) { }
Array(MemoryPool& p, const size_t InitialCapacity)
: Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage())
{
ensureCapacity(InitialCapacity);
}
Array() : count(0),
capacity(this->getStorageSize()), data(this->getStorage()) { }
explicit Array(const size_t InitialCapacity)
@ -84,15 +86,18 @@ public:
{
ensureCapacity(InitialCapacity);
}
Array(const Array<T, Storage>& L)
Array(const Array<T, Storage>& source)
: count(0), capacity(this->getStorageSize()), data(this->getStorage())
{
copyFrom(L);
copyFrom(source);
}
~Array()
{
freeData();
}
void clear() { count = 0; }
protected:
@ -101,63 +106,78 @@ protected:
fb_assert(index < count);
return data[index];
}
T& getElement(size_t index)
{
fb_assert(index < count);
return data[index];
}
void freeData()
{
if (data != this->getStorage())
this->getPool().deallocate(data);
}
void copyFrom(const Array<T, Storage>& L)
void copyFrom(const Array<T, Storage>& source)
{
ensureCapacity(L.count, false);
memcpy(data, L.data, sizeof(T) * L.count);
count = L.count;
ensureCapacity(source.count, false);
memcpy(data, source.data, sizeof(T) * source.count);
count = source.count;
}
public:
typedef T* iterator;
typedef const T* const_iterator;
Array<T, Storage>& operator =(const Array<T, Storage>& L)
Array<T, Storage>& operator =(const Array<T, Storage>& source)
{
copyFrom(L);
copyFrom(source);
return *this;
}
const T& operator[](size_t index) const
{
return getElement(index);
}
T& operator[](size_t index)
{
return getElement(index);
}
const T& front() const
{
fb_assert(count > 0);
return *data;
}
const T& back() const
{
fb_assert(count > 0);
return *(data + count - 1);
}
const T* begin() const { return data; }
const T* end() const { return data + count; }
T& front()
{
fb_assert(count > 0);
return *data;
}
T& back()
{
fb_assert(count > 0);
return *(data + count - 1);
}
T* begin() { return data; }
T* end() { return data + count; }
void insert(const size_t index, const T& item)
{
fb_assert(index <= count);
@ -165,14 +185,16 @@ public:
memmove(data + index + 1, data + index, sizeof(T) * (count++ - index));
data[index] = item;
}
void insert(const size_t index, const Array<T, Storage>& L)
void insert(const size_t index, const Array<T, Storage>& items)
{
fb_assert(index <= count);
ensureCapacity(count + L.count);
memmove(data + index + L.count, data + index, sizeof(T) * (count - index));
memcpy(data + index, L.data, L.count);
count += L.count;
ensureCapacity(count + items.count);
memmove(data + index + items.count, data + index, sizeof(T) * (count - index));
memcpy(data + index, items.data, items.count);
count += items.count;
}
void insert(const size_t index, const T* items, const size_t itemsSize)
{
fb_assert(index <= count);
@ -181,18 +203,21 @@ public:
memcpy(data + index, items, sizeof(T) * itemsSize);
count += itemsSize;
}
size_t add(const T& item)
{
ensureCapacity(count + 1);
data[count] = item;
return ++count;
}
void add(const T* items, const size_t itemsSize)
{
ensureCapacity(count + itemsSize);
memcpy(data + count, items, sizeof(T) * itemsSize);
count += itemsSize;
}
// NOTE: remove method must be signal safe
// This function may be called in AST. The function doesn't wait.
T* remove(const size_t index)
@ -201,6 +226,7 @@ public:
memmove(data + index, data + index + 1, sizeof(T) * (--count - index));
return &data[index];
}
T* removeRange(const size_t from, const size_t to)
{
fb_assert(from <= to);
@ -209,6 +235,7 @@ public:
count -= (to - from);
return &data[from];
}
T* removeCount(const size_t index, const size_t n)
{
fb_assert(index + n <= count);
@ -216,6 +243,7 @@ public:
count -= n;
return &data[index];
}
T* remove(T* itr)
{
const size_t index = itr - begin();
@ -223,15 +251,18 @@ public:
memmove(data + index, data + index + 1, sizeof(T) * (--count - index));
return &data[index];
}
T* remove(T* itrFrom, T* itrTo)
{
return removeRange(itrFrom - begin(), itrTo - begin());
}
void shrink(size_t newCount)
{
fb_assert(newCount <= count);
count = newCount;
}
// Grow size of our array and zero-initialize new items
void grow(const size_t newCount)
{
@ -240,6 +271,7 @@ public:
memset(data + count, 0, sizeof(T) * (newCount - count));
count = newCount;
}
// Resize array according to STL's vector::resize() rules
void resize(const size_t newCount, const T& val)
{
@ -253,6 +285,7 @@ public:
count = newCount;
}
}
// Resize array according to STL's vector::resize() rules
void resize(const size_t newCount)
{
@ -263,24 +296,30 @@ public:
count = newCount;
}
}
void join(const Array<T, Storage>& L)
{
ensureCapacity(count + L.count);
memcpy(data + count, L.data, sizeof(T) * L.count);
count += L.count;
}
void assign(const Array<T, Storage>& L)
void assign(const Array<T, Storage>& source)
{
copyFrom(L);
copyFrom(source);
}
// NOTE: getCount method must be signal safe
// Used as such in GlobalRWLock::blockingAstHandler
size_t getCount() const { return count; }
size_t getCapacity() const { return capacity; }
void push(const T& item)
{
add(item);
}
void push(const T* items, const size_t itemsSize)
{
ensureCapacity(count + itemsSize);
@ -293,6 +332,7 @@ public:
count--;
return data[count];
}
// prepare array to be used as a buffer of capacity items
T* getBuffer(const size_t capacityL)
{
@ -300,6 +340,7 @@ public:
count = capacityL;
return data;
}
// clear array and release dinamically allocated memory
void free()
{
@ -343,6 +384,7 @@ public:
protected:
size_t count, capacity;
T* data;
void ensureCapacity(size_t newcapacity, bool preserve = true)
{
if (newcapacity > capacity) {

View File

@ -138,7 +138,6 @@ static void integer_to_text(const dsc*, dsc*, Callbacks*);
static void string_to_datetime(const dsc*, GDS_TIMESTAMP*, const EXPECT_DATETIME, ErrorFunction);
static SINT64 hex_to_value(const char*& string, const char* end);
static bool transliterate(const dsc* from, dsc* to, CHARSET_ID& charset2, ErrorFunction err);
static Jrd::CharSet* getToCharset(CHARSET_ID charset2);
static void validateData(Jrd::CharSet* toCharSet, SLONG length, const UCHAR* q, ErrorFunction err);

View File

@ -87,8 +87,7 @@ ULONG CVJIS_eucj_to_unicode(csconvert* obj,
/* Step 2: Convert from JIS to UNICODE */
ch = ((const USHORT*) impl->csconvert_datatable)
[((const USHORT*) impl->csconvert_misc)
[(USHORT)wide / 256]
+ (wide % 256)];
[(USHORT)wide / 256] + (wide % 256)];
}
@ -210,8 +209,7 @@ ULONG CVJIS_sjis_to_unicode(csconvert* obj,
if (table == 1)
ch = ((const USHORT*) impl->csconvert_datatable)
[((const USHORT*) impl->csconvert_misc)
[(USHORT)wide / 256]
+ (wide % 256)];
[(USHORT)wide / 256] + (wide % 256)];
else {
fb_assert(table == 2);
fb_assert(wide <= 255);
@ -513,8 +511,7 @@ ULONG CVJIS_unicode_to_eucj(csconvert* obj, ULONG unicode_len, const UCHAR* p_un
else
jis_ch = ((const USHORT*) impl->csconvert_datatable)
[((const USHORT*) impl->csconvert_misc)
[(USHORT)wide / 256]
+ (wide % 256)];
[(USHORT)wide / 256] + (wide % 256)];
if ((jis_ch == CS_CANT_MAP) && !(wide == CS_CANT_MAP)) {
*err_code = CS_CONVERT_ERROR;
break;

View File

@ -92,8 +92,7 @@ ULONG CVKSC_ksc_to_unicode(csconvert* obj,
}
const USHORT ch = ((const USHORT*) impl->csconvert_datatable)
[((const USHORT*) impl->csconvert_misc)[(USHORT) wide / 256] +
(wide % 256)];
[((const USHORT*) impl->csconvert_misc)[(USHORT) wide / 256] + (wide % 256)];
if ((ch == CS_CANT_MAP) && !(wide == CS_CANT_MAP)) {
*err_code = CS_CONVERT_ERROR;

View File

@ -143,8 +143,7 @@ USHORT LC_NARROW_key_length(texttype* obj, USHORT inLen)
USHORT len = impl->texttype_bytes_per_key * MAX(inLen, 2);
if (impl->texttype_expand_table &&
((const ExpandChar*) impl->texttype_expand_table)[0].Ch)
if (impl->texttype_expand_table && ((const ExpandChar*) impl->texttype_expand_table)[0].Ch)
{
len += (USHORT) log10(inLen + 1.0) * 4 * impl->texttype_bytes_per_key;
}
@ -258,9 +257,7 @@ USHORT LC_NARROW_string_to_key(texttype* obj, USHORT iInLen, const BYTE* pInChar
fb_assert(exp->Ch == *pInChar);
for (int j = 0; j < 2; j++) {
if (j)
coll =
&((const SortOrderTblEntry*) impl->
texttype_collation_table)[exp->ExpCh2];
coll = &((const SortOrderTblEntry*) impl->texttype_collation_table)[exp->ExpCh2];
if (coll->Primary != NULL_WEIGHT && lprimary < iOutLen)
outbuff[lprimary++] = coll->Primary + impl->primary_sum;
if (coll->Secondary != NULL_SECONDARY && lsecondary < sizeof(secondary))

View File

@ -655,17 +655,19 @@ static void unicodeDestroy(texttype* tt)
static USHORT unicodeKeyLength(texttype* tt, USHORT len)
{
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->keyLength(
len / static_cast<TextTypeImpl*>(tt->texttype_impl)->cs->charset_max_bytes_per_char * 4);
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
return impl->collation->keyLength(len / impl->cs->charset_max_bytes_per_char * 4);
}
static USHORT unicodeStrToKey(texttype* tt, USHORT srcLen, const UCHAR* src,
USHORT dstLen, UCHAR* dst, USHORT keyType)
{
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
try
{
charset* cs = static_cast<TextTypeImpl*>(tt->texttype_impl)->cs;
charset* cs = impl->cs;
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str;
USHORT errorCode;
@ -690,8 +692,7 @@ static USHORT unicodeStrToKey(texttype* tt, USHORT srcLen, const UCHAR* src,
&errorCode,
&offendingPos);
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->stringToKey(
utf16Len, (USHORT*)utf16Str.begin(), dstLen, dst, keyType);
return impl->collation->stringToKey(utf16Len, (USHORT*)utf16Str.begin(), dstLen, dst, keyType);
}
catch (BadAlloc)
{
@ -704,11 +705,13 @@ static USHORT unicodeStrToKey(texttype* tt, USHORT srcLen, const UCHAR* src,
static SSHORT unicodeCompare(texttype* tt, ULONG len1, const UCHAR* str1,
ULONG len2, const UCHAR* str2, INTL_BOOL* errorFlag)
{
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
try
{
*errorFlag = false;
charset* cs = static_cast<TextTypeImpl*>(tt->texttype_impl)->cs;
charset* cs = impl->cs;
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str1;
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str2;
@ -753,8 +756,7 @@ static SSHORT unicodeCompare(texttype* tt, ULONG len1, const UCHAR* str1,
&errorCode,
&offendingPos);
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->compare(
utf16Len1, (USHORT*)utf16Str1.begin(),
return impl->collation->compare(utf16Len1, (USHORT*)utf16Str1.begin(),
utf16Len2, (USHORT*)utf16Str2.begin(), errorFlag);
}
catch (BadAlloc)
@ -767,9 +769,11 @@ static SSHORT unicodeCompare(texttype* tt, ULONG len1, const UCHAR* str1,
static ULONG unicodeCanonical(texttype* tt, ULONG srcLen, const UCHAR* src, ULONG dstLen, UCHAR* dst)
{
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
try
{
charset* cs = static_cast<TextTypeImpl*>(tt->texttype_impl)->cs;
charset* cs = impl->cs;
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str;
USHORT errorCode;
@ -794,7 +798,7 @@ static ULONG unicodeCanonical(texttype* tt, ULONG srcLen, const UCHAR* src, ULON
&errorCode,
&offendingPos);
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->canonical(
return impl->collation->canonical(
utf16Len, Firebird::Aligner<USHORT>(utf16Str.begin(), utf16Len),
dstLen, Firebird::OutAligner<ULONG>(dst, dstLen), NULL);
}

View File

@ -118,9 +118,9 @@ void IbUtil::initialize()
{
#ifndef BOOT_BUILD
#ifdef WIN_NT
Firebird::PathName path = "ib_util";
PathName path = "ib_util";
#else
Firebird::PathName path = "libib_util";
PathName path = "libib_util";
#endif
ModuleLoader::Module* module = ModuleLoader::loadModule(libUtilPath);

View File

@ -95,8 +95,8 @@ static SecurityClass::flags_t squeeze_acl(Acl&, const Firebird::MetaName&, SSHOR
static bool check_string(const UCHAR*, const Firebird::MetaName&);
bool GRANT_privileges( thread_db* tdbb, SSHORT phase, DeferredWork* work,
jrd_tra*) // unused param, makes dfw.epp happy
bool GRANT_privileges(thread_db* tdbb, SSHORT phase, DeferredWork* work,
jrd_tra*) // unused param, makes dfw.epp happy
{
/**************************************
*
@ -201,8 +201,7 @@ bool GRANT_privileges( thread_db* tdbb, SSHORT phase, DeferredWork* work,
}
static void define_default_class(
thread_db* tdbb,
static void define_default_class(thread_db* tdbb,
const TEXT* relation_name,
Firebird::MetaName& default_class,
const Acl& acl)
@ -491,10 +490,10 @@ static void get_user_privs(thread_db* tdbb,
}
static void grant_user(Acl& acl,
const Firebird::MetaName& user,
SSHORT user_type,
SecurityClass::flags_t privs)
static void grant_user(Acl& acl,
const Firebird::MetaName& user,
SSHORT user_type,
SecurityClass::flags_t privs)
{
/**************************************
*
@ -547,8 +546,7 @@ static void grant_user(Acl& acl,
}
#ifdef NOT_USED_OR_REPLACED
static void grant_views(
Acl& acl,
static void grant_views(Acl& acl,
SecurityClass::flags_t privs)
{
/**************************************
@ -618,11 +616,11 @@ static void purge_default_class( TEXT* object_name, SSHORT obj_type)
#endif // NOT_USED_OR_REPLACED
static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
Acl& relation_acl,
const TEXT* relation_name,
const Firebird::MetaName& owner,
SecurityClass::flags_t public_priv)
static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
Acl& relation_acl,
const TEXT* relation_name,
const Firebird::MetaName& owner,
SecurityClass::flags_t public_priv)
{
/**************************************
*
@ -681,6 +679,7 @@ static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
const SecurityClass::flags_t field_priv =
public_priv | priv | squeeze_acl(field_acl, user, user_type);
grant_user(field_acl, user, user_type, field_priv);
const SecurityClass::flags_t relation_priv =
public_priv | priv | squeeze_acl(relation_acl, user, user_type);
grant_user(relation_acl, user, user_type, relation_priv);
@ -771,6 +770,7 @@ static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
const SecurityClass::flags_t field_priv =
public_priv | priv | squeeze_acl(field_acl, user, user_type);
grant_user(field_acl, user, user_type, field_priv);
const SecurityClass::flags_t relation_priv =
public_priv | priv | squeeze_acl(relation_acl, user, user_type);
grant_user(relation_acl, user, user_type, relation_priv);
@ -803,9 +803,9 @@ static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
}
static void save_security_class(thread_db* tdbb,
const Firebird::MetaName& s_class,
const Acl& acl)
static void save_security_class(thread_db* tdbb,
const Firebird::MetaName& s_class,
const Acl& acl)
{
/**************************************
*
@ -905,9 +905,9 @@ static SecurityClass::flags_t trans_sql_priv(const TEXT* privileges)
}
static SecurityClass::flags_t squeeze_acl(Acl& acl,
const Firebird::MetaName& user,
SSHORT user_type)
static SecurityClass::flags_t squeeze_acl(Acl& acl,
const Firebird::MetaName& user,
SSHORT user_type)
{
/**************************************
*

View File

@ -49,8 +49,8 @@ struct texttype; /* forward decl for the fc signatures before the struct itself.
struct csconvert;
struct charset;
#define INTL_BAD_KEY_LENGTH ((USHORT)(-1))
#define INTL_BAD_STR_LENGTH ((ULONG)(-1))
#define INTL_BAD_KEY_LENGTH ((USHORT) -1)
#define INTL_BAD_STR_LENGTH ((ULONG) -1)
/* Returned value of INTL_BAD_KEY_LENGTH means that proposed key is too long */
typedef USHORT (*pfn_INTL_keylength) (
@ -137,7 +137,7 @@ typedef void (*pfn_INTL_tt_destroy) (
struct texttype {
/* Data which needs to be initialized by collation driver */
USHORT texttype_version; /* version ID of object */
void* texttype_impl; /* collation object implemented in driver */
void* texttype_impl; /* collation object implemented in driver */
/* Used only for debugging purposes. Should contain string in form
<charset>.<collation>. For example "WIN1251.PXW_CYRL"

View File

@ -1055,13 +1055,10 @@ static SecurityClass::flags_t compute_access(thread_db* tdbb,
BLB_close(tdbb, blob);
blob = NULL;
acl.shrink(end - buffer);
if (acl.getCount() > 0)
{
privileges |= walk_acl( tdbb,
acl,
view,
trg_name,
prc_name);
privileges |= walk_acl(tdbb, acl, view, trg_name, prc_name);
}
END_FOR;
@ -1242,9 +1239,12 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
break;
case ACL_priv_list:
if (hit) {
if (hit)
{
while ( (c = *a++) )
switch (c) {
{
switch (c)
{
case priv_control:
privilege |= SCL_control;
break;
@ -1253,7 +1253,6 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
// Note that READ access must imply REFERENCES
// access for upward compatibility of existing
// security classes
privilege |= SCL_read | SCL_sql_references;
break;
@ -1298,6 +1297,8 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
default:
return SCL_corrupt;
}
}
// For a relation the first hit does not give the privilege.
// Because, there could be some permissions for the table
// (for user1) and some permissions for a column on that