예제 #1
0
// Transform strings (or substrings) prefixed with introducer (_charset) to ASCII equivalent.
void Parser::transformString(const char* start, unsigned length, string& dest)
{
    const static char HEX_DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                                      'A', 'B', 'C', 'D', 'E', 'F'
                                     };

    const unsigned fromBegin = start - lex.start;
    HalfStaticArray<char, 256> buffer;
    const char* pos = start;

    // We need only the "introduced" strings, in the bounds of "start" and "length" and in "pos"
    // order. Let collect them.

    SortedArray<StrMark> introducedMarks;

    GenericMap<NonPooled<IntlString*, StrMark> >::ConstAccessor accessor(&strMarks);
    for (bool found = accessor.getFirst(); found; found = accessor.getNext())
    {
        const StrMark& mark = accessor.current()->second;
        if (mark.introduced && mark.pos >= fromBegin && mark.pos < fromBegin + length)
            introducedMarks.add(mark);
    }

    for (size_t i = 0; i < introducedMarks.getCount(); ++i)
    {
        const StrMark& mark = introducedMarks[i];

        const char* s = lex.start + mark.pos;
        buffer.add(pos, s - pos);

        if (!isspace(UCHAR(pos[s - pos - 1])))
            buffer.add(' ');	// fix _charset'' becoming invalid syntax _charsetX''

        const size_t count = buffer.getCount();
        const size_t newSize = count + 2 + mark.str->getString().length() * 2 + 1;
        buffer.grow(newSize);
        char* p = buffer.begin() + count;

        *p++ = 'X';
        *p++ = '\'';

        const char* s2 = mark.str->getString().c_str();

        for (const char* end = s2 + mark.str->getString().length(); s2 < end; ++s2)
        {
            *p++ = HEX_DIGITS[UCHAR(*s2) >> 4];
            *p++ = HEX_DIGITS[UCHAR(*s2) & 0xF];
        }

        *p = '\'';
        fb_assert(p < buffer.begin() + newSize);

        pos = s + mark.length;
    }

    fb_assert(start + length - pos >= 0);
    buffer.add(pos, start + length - pos);

    dest.assign(buffer.begin(), MIN(string::max_length(), buffer.getCount()));
}
void releaseUpgradeTabs(IPluginModule* module)
{
	HalfStaticArray<UpgradeKey, 16> removeList;

	WriteLockGuard sync(mapLock, FB_FUNCTION);

	GenericMap<FunctionPair>::Accessor scan(&functionMap);

	if (scan.getFirst())
	{
		do
		{
			UpgradeKey& cur(scan.current()->first);

			if (cur.contains(module))
				removeList.add(cur);
		} while (scan.getNext());
	}

	for(unsigned int i = 0; i < removeList.getCount(); ++i)
		functionMap->remove(removeList[i]);
}
예제 #3
0
int INTL_compare(thread_db* tdbb, const dsc* pText1, const dsc* pText2, ErrorFunction err)
{
/**************************************
 *
 *      I N T L _ c o m p a r e
 *
 **************************************
 *
 * Functional description
 *      Compare two pieces of international text.
 *
 **************************************/
	SET_TDBB(tdbb);

	fb_assert(pText1 != NULL);
	fb_assert(pText2 != NULL);
	fb_assert(IS_TEXT(pText1) && IS_TEXT(pText2));
	fb_assert(INTL_data_or_binary(pText1) || INTL_data_or_binary(pText2));
	fb_assert(err);

	// normal compare routine from CVT_compare
	// trailing spaces in strings are ignored for comparision

	UCHAR* p1;
	USHORT t1;
	ULONG length1 = CVT_get_string_ptr(pText1, &t1, &p1, NULL, 0, err);

	UCHAR* p2;
	USHORT t2;
	ULONG length2 = CVT_get_string_ptr(pText2, &t2, &p2, NULL, 0, err);

	// YYY - by SQL II compare_type must be explicit in the
	// SQL statement if there is any doubt

	USHORT compare_type = MAX(t1, t2);	// YYY
	HalfStaticArray<UCHAR, BUFFER_XLARGE> buffer;

	if (t1 != t2)
	{
		CHARSET_ID cs1 = INTL_charset(tdbb, t1);
		CHARSET_ID cs2 = INTL_charset(tdbb, t2);
		if (cs1 != cs2)
		{
			if (compare_type != t2)
			{
				// convert pText2 to pText1's type, if possible
				/* YYY - should failure to convert really return
				   an error here?
				   Support joining a 437 & Latin1 Column, and we
				   pick the compare_type as 437, still only want the
				   equal values....
				   But then, what about < operations, which make no
				   sense if the string cannot be expressed...
				 */

				UCHAR* p = buffer.getBuffer(INTL_convert_bytes(tdbb, cs1, NULL, 0,
					cs2, p2, length2, err));
				length2 = INTL_convert_bytes(tdbb, cs1, p, (ULONG) buffer.getCount(),
					cs2, p2, length2, err);
				p2 = p;
			}
			else
			{
				// convert pText1 to pText2's type, if possible

				UCHAR* p = buffer.getBuffer(INTL_convert_bytes(tdbb, cs2, NULL, 0,
					cs1, p1, length1, err));
				length1 = INTL_convert_bytes(tdbb, cs2, p, (ULONG) buffer.getCount(),
					cs1, p1, length1, err);
				p1 = p;
			}
		}
	}

	TextType* obj = INTL_texttype_lookup(tdbb, compare_type);

	return obj->compare(length1, p1, length2, p2);
}