Beispiel #1
0
// converts bytes to BASE64 representation
void base64(Firebird::string& b64, const Firebird::UCharBuffer& bin)
{
	b64.erase();
	const unsigned char* f = bin.begin();
	for (int i = bin.getCount(); i > 0; i -= 3, f += 3)
	{
		if (i >= 3)
		{
			const ULONG l = (ULONG(f[0]) << 16) | (ULONG(f[1]) <<  8) | f[2];
			b64 += conv_bin2ascii(l >> 18);
			b64 += conv_bin2ascii(l >> 12);
			b64 += conv_bin2ascii(l >> 6);
			b64 += conv_bin2ascii(l);
		}
		else
		{
			ULONG l = ULONG(f[0]) << 16;
			if (i == 2)
				l |= (ULONG(f[1]) << 8);
			b64 += conv_bin2ascii(l >> 18);
			b64 += conv_bin2ascii(l >> 12);
			b64 += (i == 1 ? '=' : conv_bin2ascii(l >> 6));
			b64 += '=';
		}
	}
Beispiel #2
0
void PIO_get_unique_file_id(const Jrd::jrd_file* file, Firebird::UCharBuffer& id)
{
/**************************************
 *
 *	P I O _ g e t _ u n i q u e _ f i l e _ i d
 *
 **************************************
 *
 * Functional description
 *	Return a binary string that uniquely identifies the file.
 *
 **************************************/
	BY_HANDLE_FILE_INFORMATION file_info;
	GetFileInformationByHandle(file->fil_desc, &file_info);

	// The identifier is [nFileIndexHigh, nFileIndexLow]
	// MSDN says: After a process opens a file, the identifier is constant until
	// the file is closed. An application can use this identifier and the
	// volume serial number to determine whether two handles refer to the same file.
	const size_t len1 = sizeof(file_info.dwVolumeSerialNumber);
	const size_t len2 = sizeof(file_info.nFileIndexHigh);
	const size_t len3 = sizeof(file_info.nFileIndexLow);

	UCHAR* p = id.getBuffer(len1 + len2 + len3);

	memcpy(p, &file_info.dwVolumeSerialNumber, len1);
	p += len1;
	memcpy(p, &file_info.nFileIndexHigh, len2);
	p += len2;
	memcpy(p, &file_info.nFileIndexLow, len3);
}
Beispiel #3
0
	Firebird::string Database::getUniqueFileId() const
	{
		const PageSpace* const pageSpace = dbb_page_manager.findPageSpace(DB_PAGE_SPACE);

		Firebird::UCharBuffer buffer;
		PIO_get_unique_file_id(pageSpace->file, buffer);

		Firebird::string file_id;
		char* s = file_id.getBuffer(2 * buffer.getCount());
		for (size_t i = 0; i < buffer.getCount(); i++)
		{
			sprintf(s, "%02x", (int) buffer[i]);
			s += 2;
		}

		return file_id;
	}
Beispiel #4
0
void getUniqueFileId(HANDLE fd, Firebird::UCharBuffer& id)
{
	BY_HANDLE_FILE_INFORMATION file_info;
	GetFileInformationByHandle(fd, &file_info);

	// The identifier is [nFileIndexHigh, nFileIndexLow]
	// MSDN says: After a process opens a file, the identifier is constant until
	// the file is closed. An application can use this identifier and the
	// volume serial number to determine whether two handles refer to the same file.
	const size_t len1 = sizeof(file_info.dwVolumeSerialNumber);
	const size_t len2 = sizeof(file_info.nFileIndexHigh);
	const size_t len3 = sizeof(file_info.nFileIndexLow);

	UCHAR* p = id.getBuffer(len1 + len2 + len3);

	memcpy(p, &file_info.dwVolumeSerialNumber, len1);
	p += len1;
	memcpy(p, &file_info.nFileIndexHigh, len2);
	p += len2;
	memcpy(p, &file_info.nFileIndexLow, len3);
}
Beispiel #5
0
	void BigInteger::random(int numBytes)
	{
		Firebird::UCharBuffer b;
		Firebird::GenerateRandomBytes(b.getBuffer(numBytes), numBytes);
		assign(numBytes, b.begin());
	}
Beispiel #6
0
	BigInteger::BigInteger(const Firebird::UCharBuffer& val)
	{
		CHECK_MP(mp_init(&t));
		assign(val.getCount(), val.begin());
	}
Beispiel #7
0
	void BigInteger::getBytes(Firebird::UCharBuffer& bytes) const
	{
		CHECK_MP(mp_to_unsigned_bin(const_cast<mp_int*>(&t), bytes.getBuffer(length())));
	}
Beispiel #8
0
Collation* CharSetContainer::lookupCollation(thread_db* tdbb, USHORT tt_id)
{
	const USHORT id = TTYPE_TO_COLLATION(tt_id);

	if (id < charset_collations.getCount() && charset_collations[id] != NULL)
	{
		if (!charset_collations[id]->obsolete)
			return charset_collations[id];
	}

	Jrd::Attachment* att = tdbb->getAttachment();
	Jrd::Attachment::CheckoutLockGuard guard(att, createCollationMtx, FB_FUNCTION); // do we need it ?

	Collation* to_delete = NULL;

	if (id < charset_collations.getCount() && charset_collations[id] != NULL)
	{
		if (charset_collations[id]->obsolete)
		{
			// if obsolete collation is not used delete it immediately,
			// else wait until all references are released
			if (charset_collations[id]->useCount == 0)
			{
				charset_collations[id]->destroy(tdbb);
				delete charset_collations[id];
			}
			else
				to_delete = charset_collations[id];

			charset_collations[id] = NULL;
		}
		else
			return charset_collations[id];
	}

	SubtypeInfo info;
	if (MET_get_char_coll_subtype_info(tdbb, tt_id, &info))
	{
		CharSet* charset = INTL_charset_lookup(tdbb, TTYPE_TO_CHARSET(tt_id));

		if (TTYPE_TO_CHARSET(tt_id) != CS_METADATA)
		{
			Firebird::UCharBuffer specificAttributes;
			ULONG size = info.specificAttributes.getCount() * charset->maxBytesPerChar();

			size = INTL_convert_bytes(tdbb, TTYPE_TO_CHARSET(tt_id),
									  specificAttributes.getBuffer(size), size,
									  CS_METADATA, info.specificAttributes.begin(),
									  info.specificAttributes.getCount(), ERR_post);
			specificAttributes.shrink(size);
			info.specificAttributes = specificAttributes;
		}

		texttype* tt = FB_NEW_POOL(*att->att_pool) texttype;
		memset(tt, 0, sizeof(texttype));

		if (!lookup_texttype(tt, &info))
		{
			delete tt;
			ERR_post(Arg::Gds(isc_collation_not_installed) << Arg::Str(info.collationName) <<
															  Arg::Str(info.charsetName));
		}

		if (charset_collations.getCount() <= id)
			charset_collations.grow(id + 1);

		fb_assert((tt->texttype_canonical_width == 0 && tt->texttype_fn_canonical == NULL) ||
				  (tt->texttype_canonical_width != 0 && tt->texttype_fn_canonical != NULL));

		if (tt->texttype_canonical_width == 0)
		{
			if (charset->isMultiByte())
				tt->texttype_canonical_width = sizeof(ULONG);	// UTF-32
			else
			{
				tt->texttype_canonical_width = charset->minBytesPerChar();
				// canonical is equal to string, then TEXTTYPE_DIRECT_MATCH can be turned on
				tt->texttype_flags |= TEXTTYPE_DIRECT_MATCH;
			}
		}

		charset_collations[id] = Collation::createInstance(*att->att_pool, tt_id, tt, charset);
		charset_collations[id]->name = info.collationName;

		// we don't need a lock in the charset
		if (id != 0)
		{
			Lock* lock = charset_collations[id]->existenceLock =
				CharSetContainer::createCollationLock(tdbb, tt_id, charset_collations[id]);

			fb_assert(charset_collations[id]->useCount == 0);
			fb_assert(!charset_collations[id]->obsolete);

			LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT);

			// as we just obtained SR lock for new collation instance
			// we could safely delete obsolete instance
			if (to_delete)
			{
				to_delete->destroy(tdbb);
				delete to_delete;
			}
		}
	}
	else
	{
		if (to_delete)
		{
			LCK_lock(tdbb, to_delete->existenceLock, LCK_SR, LCK_WAIT);
			to_delete->destroy(tdbb);
			delete to_delete;
		}

		ERR_post(Arg::Gds(isc_text_subtype) << Arg::Num(tt_id));
	}

	return charset_collations[id];
}