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

1. Frontported fix for CORE-1944: Monitoring tables contain wrong data

2. Added new methods to Clumplet classes - date, time and floating point support.

3. Avoid endianess #ifdef's in Clumplet classes.
This commit is contained in:
alexpeshkoff 2008-06-24 13:07:12 +00:00
parent b8be425321
commit 99f17b4d00
8 changed files with 173 additions and 150 deletions

View File

@ -484,18 +484,10 @@ const UCHAR* ClumpletReader::getBytes() const
return getBuffer() + cur_offset + getClumpletSize(true, true, false); return getBuffer() + cur_offset + getClumpletSize(true, true, false);
} }
SLONG ClumpletReader::getInt() const SINT64 ClumpletReader::fromVaxInteger(const UCHAR* ptr, size_t length)
{ {
const UCHAR* ptr = getBytes();
size_t length = getClumpLength();
if (length > 4) {
invalid_structure("length of integer exceeds 4 bytes");
return 0;
}
// This code is taken from gds__vax_integer // This code is taken from gds__vax_integer
SLONG value = 0; SINT64 value = 0;
int shift = 0; int shift = 0;
while (length > 0) { while (length > 0) {
--length; --length;
@ -506,9 +498,60 @@ SLONG ClumpletReader::getInt() const
return value; return value;
} }
SLONG ClumpletReader::getInt() const
{
size_t length = getClumpLength();
if (length > 4) {
invalid_structure("length of integer exceeds 4 bytes");
return 0;
}
return fromVaxInteger(getBytes(), length);
}
double ClumpletReader::getDouble() const
{
if (getClumpLength() != sizeof(double)) {
invalid_structure("length of double must be equal 8 bytes");
return 0;
}
// based on XDR code
union {
double temp_double;
SLONG temp_long[2];
} temp;
fb_assert(sizeof(double) == sizeof(temp));
const UCHAR* ptr = getBytes();
temp.temp_long[FB_LONG_DOUBLE_FIRST] = fromVaxInteger(ptr, sizeof(SLONG));
temp.temp_long[FB_LONG_DOUBLE_SECOND] = fromVaxInteger(ptr + sizeof(SLONG), sizeof(SLONG));
return temp.temp_double;
}
ISC_TIMESTAMP ClumpletReader::getTimeStamp() const
{
ISC_TIMESTAMP value;
if (getClumpLength() != sizeof(ISC_TIMESTAMP)) {
invalid_structure("length of ISC_TIMESTAMP must be equal 8 bytes");
value.timestamp_date = 0;
value.timestamp_time = 0;
return value;
}
const UCHAR* ptr = getBytes();
value.timestamp_date = fromVaxInteger(ptr, sizeof(SLONG));
value.timestamp_time = fromVaxInteger(ptr + sizeof(SLONG), sizeof(SLONG));
return value;
}
SINT64 ClumpletReader::getBigInt() const SINT64 ClumpletReader::getBigInt() const
{ {
const UCHAR* ptr = getBytes();
size_t length = getClumpLength(); size_t length = getClumpLength();
if (length > 8) { if (length > 8) {
@ -516,16 +559,7 @@ SINT64 ClumpletReader::getBigInt() const
return 0; return 0;
} }
// This code is taken from isc_portable_integer return fromVaxInteger(getBytes(), length);
SINT64 value = 0;
int shift = 0;
while (length > 0) {
--length;
value += ((SINT64) *ptr++) << shift;
shift += 8;
}
return value;
} }
string& ClumpletReader::getString(string& str) const string& ClumpletReader::getString(string& str) const

View File

@ -68,6 +68,10 @@ public:
string& getString(string& str) const; string& getString(string& str) const;
PathName& getPath(PathName& str) const; PathName& getPath(PathName& str) const;
const UCHAR* getBytes() const; const UCHAR* getBytes() const;
double getDouble() const;
ISC_TIMESTAMP getTimeStamp() const;
ISC_TIME getTime() const { return getInt(); }
ISC_DATE getDate() const { return getInt(); }
// Return the tag for buffer (usually structure version) // Return the tag for buffer (usually structure version)
UCHAR getBufferTag() const; UCHAR getBufferTag() const;
@ -129,6 +133,8 @@ private:
const UCHAR* static_buffer; const UCHAR* static_buffer;
const UCHAR* static_buffer_end; const UCHAR* static_buffer_end;
static SINT64 ClumpletReader::fromVaxInteger(const UCHAR* ptr, size_t length);
}; };
} // namespace Firebird } // namespace Firebird

View File

@ -121,38 +121,53 @@ void ClumpletWriter::size_overflow()
fatal_exception::raise("Clumplet buffer size limit reached"); fatal_exception::raise("Clumplet buffer size limit reached");
} }
void ClumpletWriter::toVaxInteger(UCHAR* ptr, size_t length, SINT64 value)
{
int shift = 0;
while (length--) {
*ptr++ = (UCHAR)(value >> shift);
shift += 8;
}
}
void ClumpletWriter::insertInt(UCHAR tag, SLONG value) void ClumpletWriter::insertInt(UCHAR tag, SLONG value)
{ {
#if defined(WORDS_BIGENDIAN)
UCHAR bytes[4]; UCHAR bytes[4];
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
bytes[0] = ptr[3]; toVaxInteger(bytes, sizeof(bytes), value);
bytes[1] = ptr[2];
bytes[2] = ptr[1];
bytes[3] = ptr[0];
insertBytesLengthCheck(tag, bytes, sizeof(bytes)); insertBytesLengthCheck(tag, bytes, sizeof(bytes));
#else
insertBytesLengthCheck(tag, reinterpret_cast<UCHAR*>(&value), sizeof(value));
#endif
} }
void ClumpletWriter::insertBigInt(UCHAR tag, SINT64 value) void ClumpletWriter::insertBigInt(UCHAR tag, SINT64 value)
{ {
#if defined(WORDS_BIGENDIAN)
UCHAR bytes[8]; UCHAR bytes[8];
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
bytes[0] = ptr[7]; toVaxInteger(bytes, sizeof(bytes), value);
bytes[1] = ptr[6]; insertBytesLengthCheck(tag, bytes, sizeof(bytes));
bytes[2] = ptr[5]; }
bytes[3] = ptr[4];
bytes[4] = ptr[3]; void ClumpletWriter::insertDouble(UCHAR tag, double value)
bytes[5] = ptr[2]; {
bytes[6] = ptr[1]; union {
bytes[7] = ptr[0]; double temp_double;
SLONG temp_long[2];
} temp;
fb_assert(sizeof(double) == sizeof(temp));
temp.temp_double = value;
UCHAR bytes[8];
toVaxInteger(bytes, sizeof(SLONG), temp.temp_long[FB_LONG_DOUBLE_FIRST]);
toVaxInteger(bytes + sizeof(SLONG), sizeof(SLONG), temp.temp_long[FB_LONG_DOUBLE_SECOND]);
insertBytesLengthCheck(tag, bytes, sizeof(bytes));
}
void ClumpletWriter::insertTimeStamp(UCHAR tag, ISC_TIMESTAMP value)
{
UCHAR bytes[8];
toVaxInteger(bytes, sizeof(SLONG), value.timestamp_date);
toVaxInteger(bytes + sizeof(SLONG), sizeof(SLONG), value.timestamp_time);
insertBytesLengthCheck(tag, bytes, sizeof(bytes)); insertBytesLengthCheck(tag, bytes, sizeof(bytes));
#else
insertBytesLengthCheck(tag, reinterpret_cast<UCHAR*>(&value), sizeof(value));
#endif
} }
void ClumpletWriter::insertString(UCHAR tag, const string& str) void ClumpletWriter::insertString(UCHAR tag, const string& str)
@ -266,35 +281,17 @@ void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const UCHAR* bytes, size_
break; break;
case 2: case 2:
{ {
USHORT value = static_cast<USHORT>(length);
fb_assert(sizeof(USHORT) == 2);
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
#if defined(WORDS_BIGENDIAN)
UCHAR b[2]; UCHAR b[2];
b[0] = ptr[1]; toVaxInteger(b, sizeof(b), length);
b[1] = ptr[0];
dynamic_buffer.insert(cur_offset, b, sizeof(b)); dynamic_buffer.insert(cur_offset, b, sizeof(b));
#else
dynamic_buffer.insert(cur_offset, ptr, sizeof(value));
#endif
cur_offset += 2; cur_offset += 2;
} }
break; break;
case 4: case 4:
{ {
ULONG value = static_cast<ULONG>(length);
fb_assert(sizeof(ULONG) == 4);
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
#if defined(WORDS_BIGENDIAN)
UCHAR b[4]; UCHAR b[4];
b[0] = ptr[3]; toVaxInteger(b, sizeof(b), length);
b[1] = ptr[2];
b[2] = ptr[1];
b[3] = ptr[0];
dynamic_buffer.insert(cur_offset, b, sizeof(b)); dynamic_buffer.insert(cur_offset, b, sizeof(b));
#else
dynamic_buffer.insert(cur_offset, ptr, sizeof(value));
#endif
cur_offset += 4; cur_offset += 4;
} }
break; break;

View File

@ -63,6 +63,10 @@ public:
void insertString(UCHAR tag, const char* str, size_t length); void insertString(UCHAR tag, const char* str, size_t length);
void insertByte(UCHAR tag, const UCHAR byte); void insertByte(UCHAR tag, const UCHAR byte);
void insertTag(UCHAR tag); void insertTag(UCHAR tag);
void insertDouble(UCHAR tag, double value);
void insertTimeStamp(UCHAR tag, ISC_TIMESTAMP value);
void insertTime(UCHAR tag, ISC_TIME value) { insertInt(tag, value); }
void insertDate(UCHAR tag, ISC_DATE value) { insertInt(tag, value); }
void insertEndMarker(UCHAR tag); void insertEndMarker(UCHAR tag);
// Delete currently selected clumplet from buffer // Delete currently selected clumplet from buffer
@ -87,6 +91,7 @@ private:
HalfStaticArray<UCHAR, 128> dynamic_buffer; HalfStaticArray<UCHAR, 128> dynamic_buffer;
void initNewBuffer(UCHAR tag); void initNewBuffer(UCHAR tag);
static void toVaxInteger(UCHAR* ptr, size_t length, SINT64 value);
}; };
} // namespace Firebird } // namespace Firebird

View File

@ -472,8 +472,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
reader = dumpData(tdbb, false); reader = dumpData(tdbb, false);
} }
reader->rewind();
// Parse the dump // Parse the dump
RecordBuffer* buffer = NULL; RecordBuffer* buffer = NULL;
Record* record = NULL; Record* record = NULL;
@ -481,7 +479,7 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
int rid = 0; int rid = 0;
bool fields_processed = false, allowed = false, our_dbb = false; bool fields_processed = false, allowed = false, our_dbb = false;
while (!reader->isEof()) for (reader->rewind(); !reader->isEof(); reader->moveNext())
{ {
if (reader->getClumpTag() == TAG_DBB) if (reader->getClumpTag() == TAG_DBB)
{ {
@ -491,8 +489,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
our_dbb = !memcmp(&guid, &dbb->dbb_guid, sizeof(FB_GUID)); our_dbb = !memcmp(&guid, &dbb->dbb_guid, sizeof(FB_GUID));
reader->moveNext();
if (fields_processed) if (fields_processed)
{ {
buffer->store(record); buffer->store(record);
@ -502,7 +498,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
else if (reader->getClumpTag() == TAG_RECORD) else if (reader->getClumpTag() == TAG_RECORD)
{ {
rid = reader->getInt(); rid = reader->getInt();
reader->moveNext();
if (fields_processed) if (fields_processed)
{ {
@ -560,8 +555,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
const char* source = checkNull(rid, fid, (char*) reader->getBytes(), length); const char* source = checkNull(rid, fid, (char*) reader->getBytes(), length);
reader->moveNext();
if (rid == rel_mon_database) // special case for MON$DATABASE if (rid == rel_mon_database) // special case for MON$DATABASE
{ {
if (fid == f_mon_db_name) if (fid == f_mon_db_name)
@ -571,13 +564,13 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
if (record && allowed && our_dbb) if (record && allowed && our_dbb)
{ {
putField(record, fid, source, length); putField(record, fid, reader, source == NULL);
fields_processed = true; fields_processed = true;
} }
} }
else if (record && allowed) // generic logic that covers all other relations else if (record && allowed) // generic logic that covers all other relations
{ {
putField(record, fid, source, length); putField(record, fid, reader, source == NULL);
fields_processed = true; fields_processed = true;
} }
} }
@ -644,26 +637,26 @@ void DatabaseSnapshot::clearRecord(Record* record)
} }
void DatabaseSnapshot::putField(Record* record, int id, const void* source, size_t length) void DatabaseSnapshot::putField(Record* record, int id, const Firebird::ClumpletReader* reader, bool makeNull)
{ {
fb_assert(record); fb_assert(record);
const Format* const format = record->rec_format; const Format* const format = record->rec_format;
fb_assert(format && id < format->fmt_count); fb_assert(format && id < format->fmt_count);
const dsc desc = format->fmt_desc[id]; if (makeNull)
UCHAR* const address = record->rec_data + (IPTR) desc.dsc_address;
if (!source)
{ {
SET_NULL(record, id); SET_NULL(record, id);
return; return;
} }
if (length == sizeof(SINT64) && desc.dsc_dtype == dtype_long) const dsc desc = format->fmt_desc[id];
UCHAR* const address = record->rec_data + (IPTR) desc.dsc_address;
if (reader->getClumpLength() == sizeof(SINT64) && desc.dsc_dtype == dtype_long)
{ {
// special case: translate 64-bit global ID into 32-bit local ID // special case: translate 64-bit global ID into 32-bit local ID
const SINT64 global_id = *(SINT64*) source; const SINT64 global_id = reader->getBigInt();
SLONG local_id = 0; SLONG local_id = 0;
if (!idMap.get(global_id, local_id)) if (!idMap.get(global_id, local_id))
{ {
@ -678,18 +671,18 @@ void DatabaseSnapshot::putField(Record* record, int id, const void* source, size
switch (desc.dsc_dtype) { switch (desc.dsc_dtype) {
case dtype_text: case dtype_text:
{ {
const char* const string = (char*) source; const char* const string = (char*) reader->getBytes();
const size_t max_length = desc.dsc_length; const size_t max_length = desc.dsc_length;
length = MIN(length, max_length); const size_t length = MIN(reader->getClumpLength(), max_length);
memcpy(address, string, length); memcpy(address, string, length);
memset(address + length, ' ', max_length - length); memset(address + length, ' ', max_length - length);
} }
break; break;
case dtype_varying: case dtype_varying:
{ {
const char* const string = (char*) source; const char* const string = (char*) reader->getBytes();
const size_t max_length = desc.dsc_length - sizeof(USHORT); const size_t max_length = desc.dsc_length - sizeof(USHORT);
length = MIN(length, max_length); const size_t length = MIN(reader->getClumpLength(), max_length);
vary* varying = (vary*) address; vary* varying = (vary*) address;
varying->vary_length = length; varying->vary_length = length;
memcpy(varying->vary_string, string, length); memcpy(varying->vary_string, string, length);
@ -697,30 +690,30 @@ void DatabaseSnapshot::putField(Record* record, int id, const void* source, size
break; break;
case dtype_short: case dtype_short:
*(SSHORT*) address = *(SSHORT*) source; *(SSHORT*) address = reader->getBigInt();
break; break;
case dtype_long: case dtype_long:
*(SLONG*) address = *(SLONG*) source; *(SLONG*) address = reader->getBigInt();
break; break;
case dtype_int64: case dtype_int64:
*(SINT64*) address = *(SINT64*) source; *(SINT64*) address = reader->getBigInt();
break; break;
case dtype_real: case dtype_real:
*(float*) address = *(float*) source; *(float*) address = reader->getDouble();
break; break;
case dtype_double: case dtype_double:
*(double*) address = *(double*) source; *(double*) address = reader->getDouble();
break; break;
case dtype_sql_date: case dtype_sql_date:
*(ISC_DATE*) address = *(ISC_DATE*) source; *(ISC_DATE*) address = reader->getDate();
break; break;
case dtype_sql_time: case dtype_sql_time:
*(ISC_TIME*) address = *(ISC_TIME*) source; *(ISC_TIME*) address = reader->getTime();
break; break;
case dtype_timestamp: case dtype_timestamp:
*(ISC_TIMESTAMP*) address = *(ISC_TIMESTAMP*) source; *(ISC_TIMESTAMP*) address = reader->getTimeStamp();
break; break;
case dtype_blob: case dtype_blob:
@ -755,9 +748,9 @@ void DatabaseSnapshot::putField(Record* record, int id, const void* source, size
blb* blob = BLB_create2(tdbb, tdbb->getTransaction(), &blob_id, blb* blob = BLB_create2(tdbb, tdbb->getTransaction(), &blob_id,
bpb.getCount(), bpb.begin()); bpb.getCount(), bpb.begin());
length = MIN(length, MAX_USHORT); const size_t length = MIN(reader->getClumpLength(), MAX_USHORT);
BLB_put_segment(tdbb, blob, (const UCHAR*) source, length); BLB_put_segment(tdbb, blob, reader->getBytes(), length);
BLB_close(tdbb, blob); BLB_close(tdbb, blob);
*(bid*) address = blob_id; *(bid*) address = blob_id;
@ -996,9 +989,7 @@ void DatabaseSnapshot::putDatabase(const Database* database,
temp = (database->dbb_flags & DBB_no_reserve) ? 0 : 1; temp = (database->dbb_flags & DBB_no_reserve) ? 0 : 1;
writer.insertInt(f_mon_db_res_space, temp); writer.insertInt(f_mon_db_res_space, temp);
// creation date // creation date
writer.insertBytes(f_mon_db_created, writer.insertTimeStamp(f_mon_db_created, database->dbb_creation_date.value());
(UCHAR*) &database->dbb_creation_date.value(),
sizeof(ISC_TIMESTAMP));
// database size // database size
writer.insertBigInt(f_mon_db_pages, PageSpace::actAlloc(database)); writer.insertBigInt(f_mon_db_pages, PageSpace::actAlloc(database));
@ -1078,9 +1069,7 @@ void DatabaseSnapshot::putAttachment(const Attachment* attachment,
// charset // charset
writer.insertInt(f_mon_att_charset_id, attachment->att_charset); writer.insertInt(f_mon_att_charset_id, attachment->att_charset);
// timestamp // timestamp
writer.insertBytes(f_mon_att_timestamp, writer.insertTimeStamp(f_mon_att_timestamp, attachment->att_timestamp.value());
(UCHAR*) &attachment->att_timestamp.value(),
sizeof(ISC_TIMESTAMP));
// garbage collection flag // garbage collection flag
temp = (attachment->att_flags & ATT_no_cleanup) ? 0 : 1; temp = (attachment->att_flags & ATT_no_cleanup) ? 0 : 1;
writer.insertInt(f_mon_att_gc, temp); writer.insertInt(f_mon_att_gc, temp);
@ -1110,9 +1099,7 @@ void DatabaseSnapshot::putTransaction(const jrd_tra* transaction,
temp = transaction->tra_requests ? mon_state_active : mon_state_idle; temp = transaction->tra_requests ? mon_state_active : mon_state_idle;
writer.insertInt(f_mon_tra_state, temp); writer.insertInt(f_mon_tra_state, temp);
// timestamp // timestamp
writer.insertBytes(f_mon_tra_timestamp, writer.insertTimeStamp(f_mon_tra_timestamp, transaction->tra_timestamp.value());
(UCHAR*) &transaction->tra_timestamp.value(),
sizeof(ISC_TIMESTAMP));
// top transaction // top transaction
writer.insertInt(f_mon_tra_top, transaction->tra_top); writer.insertInt(f_mon_tra_top, transaction->tra_top);
// oldest transaction // oldest transaction
@ -1173,17 +1160,13 @@ void DatabaseSnapshot::putRequest(const jrd_req* request,
const int tra_id = request->req_transaction ? const int tra_id = request->req_transaction ?
request->req_transaction->tra_number : 0; request->req_transaction->tra_number : 0;
writer.insertInt(f_mon_stmt_tra_id, tra_id); writer.insertInt(f_mon_stmt_tra_id, tra_id);
writer.insertBytes(f_mon_stmt_timestamp, writer.insertTimeStamp(f_mon_stmt_timestamp, request->req_timestamp.value());
(UCHAR*) &request->req_timestamp.value(),
sizeof(ISC_TIMESTAMP));
} }
else { else {
writer.insertInt(f_mon_stmt_state, mon_state_idle); writer.insertInt(f_mon_stmt_state, mon_state_idle);
writer.insertInt(f_mon_stmt_tra_id, 0); writer.insertInt(f_mon_stmt_tra_id, 0);
ISC_TIMESTAMP empty = {0, 0}; ISC_TIMESTAMP empty = {0, 0};
writer.insertBytes(f_mon_stmt_timestamp, writer.insertTimeStamp(f_mon_stmt_timestamp, empty);
(UCHAR*) &empty,
sizeof(ISC_TIMESTAMP));
} }
// sql text // sql text
writer.insertString(f_mon_stmt_sql_text, request->req_sql_text); writer.insertString(f_mon_stmt_sql_text, request->req_sql_text);
@ -1238,9 +1221,7 @@ void DatabaseSnapshot::putCall(const jrd_req* request,
writer.insertInt(f_mon_call_type, 0); writer.insertInt(f_mon_call_type, 0);
} }
// timestamp // timestamp
writer.insertBytes(f_mon_call_timestamp, writer.insertTimeStamp(f_mon_call_timestamp, request->req_timestamp.value());
(const UCHAR*) &request->req_timestamp.value(),
sizeof(ISC_TIMESTAMP));
// source line/column // source line/column
writer.insertInt(f_mon_call_src_line, request->req_src_line); writer.insertInt(f_mon_call_src_line, request->req_src_line);
writer.insertInt(f_mon_call_src_column, request->req_src_column); writer.insertInt(f_mon_call_src_column, request->req_src_column);

View File

@ -115,7 +115,7 @@ protected:
private: private:
RecordBuffer* allocBuffer(thread_db*, MemoryPool&, int); RecordBuffer* allocBuffer(thread_db*, MemoryPool&, int);
void clearRecord(Record*); void clearRecord(Record*);
void putField(Record*, int, const void*, size_t); void putField(Record*, int, const Firebird::ClumpletReader*, bool);
static Firebird::ClumpletReader* dumpData(thread_db*, bool); static Firebird::ClumpletReader* dumpData(thread_db*, bool);
static const char* checkNull(int, int, const char*, size_t); static const char* checkNull(int, int, const char*, size_t);

View File

@ -805,6 +805,43 @@ void GDS_breakpoint(int);
#define CONST64(a) (a##LL) #define CONST64(a) (a##LL)
#endif #endif
// 30 Dec 2002. Nickolay Samofatov
// This needs to be checked for all supported platforms
// The simpliest way to check it is to issue from correct client:
// declare external function abs2 double precision
// returns double precision by value
// entry_point 'IB_UDF_abs' module_name 'ib_udf';
// select abs2(2.0 / 3.0) from rdb$database;
// It will return big strange value in case of invalid define
// ASF: Currently, all little-endian are FB_SWAP_DOUBLE and big-endian aren't.
// AP: Define it for your hardware correctly in case your CPU do not follow mentioned rule.
// The follwoing lines are kept for reference only.
//#if defined(i386) || defined(I386) || defined(_M_IX86) || defined(AMD64) || defined(ARM) || defined(MIPSEL) || defined(DARWIN64) || defined(IA64)
//#define FB_SWAP_DOUBLE 1
//#elif defined(sparc) || defined(PowerPC) || defined(PPC) || defined(__ppc__) || defined(HPUX) || defined(MIPS) || defined(__ppc64__)
//#define FB_SWAP_DOUBLE 0
//#else
//#error "Define FB_SWAP_DOUBLE for your platform correctly !"
//#endif
#ifndef FB_SWAP_DOUBLE
#ifdef WORDS_BIGENDIAN
#define FB_SWAP_DOUBLE 0
#else
#define FB_SWAP_DOUBLE 1
#endif
#endif
// Commonly used indices to access parts of double in correct order.
#if FB_SWAP_DOUBLE
#define FB_LONG_DOUBLE_FIRST 1
#define FB_LONG_DOUBLE_SECOND 0
#else
#define FB_LONG_DOUBLE_FIRST 0
#define FB_LONG_DOUBLE_SECOND 1
#endif
/* switch name and state table. This structure should be used in all /* switch name and state table. This structure should be used in all
* command line tools to facilitate parsing options.*/ * command line tools to facilitate parsing options.*/

View File

@ -33,43 +33,6 @@
#include "../remote/xdr_proto.h" #include "../remote/xdr_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
// 30 Dec 2002. Nickolay Samofatov
// This needs to be checked for all supported platforms
// The simpliest way to check it is to issue from correct client:
// declare external function abs2 double precision
// returns double precision by value
// entry_point 'IB_UDF_abs' module_name 'ib_udf';
// select abs2(2.0 / 3.0) from rdb$database;
// It will return big strange value in case of invalid define
/*
// ASF: Currently, all little-endian are FB_SWAP_DOUBLE and big-endian aren't.
// AP: Left this lines as a reference in case some CPU in the future do not follow mentioned rule.
#if defined(i386) || defined(I386) || defined(_M_IX86) || defined(AMD64) || defined(ARM) || defined(MIPSEL) || defined(DARWIN64) || defined(IA64)
#define FB_SWAP_DOUBLE 1
#elif defined(sparc) || defined(PowerPC) || defined(PPC) || defined(__ppc__) || defined(HPUX) || defined(MIPS) || defined(__ppc64__)
#define FB_SWAP_DOUBLE 0
#else
#error "Define FB_SWAP_DOUBLE for your platform correctly !"
#endif
*/
#ifndef FB_SWAP_DOUBLE
#ifdef WORDS_BIGENDIAN
#define FB_SWAP_DOUBLE 0
#else
#define FB_SWAP_DOUBLE 1
#endif
#endif
#if FB_SWAP_DOUBLE
#define FB_LONG_DOUBLE_FIRST 1
#define FB_LONG_DOUBLE_SECOND 0
#else
#define FB_LONG_DOUBLE_FIRST 0
#define FB_LONG_DOUBLE_SECOND 1
#endif
#ifdef BURP #ifdef BURP
#include "../burp/misc_proto.h" /* Was "../burp/misc_pro.h" -Jeevan */ #include "../burp/misc_proto.h" /* Was "../burp/misc_pro.h" -Jeevan */
inline UCHAR* XDR_ALLOC(ULONG size) { inline UCHAR* XDR_ALLOC(ULONG size) {