8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-25 02:03:03 +01:00
firebird-mirror/src/remote/merge.cpp

207 lines
4.6 KiB
C++
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Remote Interface/Server
* MODULE: merge.cpp
* DESCRIPTION: Merge database/server information
2001-05-23 15:26:42 +02:00
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
2001-05-23 15:26:42 +02:00
#include <string.h>
2003-11-08 17:40:17 +01:00
#include "../jrd/ibase.h"
2001-05-23 15:26:42 +02:00
#include "../remote/remote.h"
#include "../remote/merge_proto.h"
#include "../jrd/gds_proto.h"
2009-01-16 10:55:38 +01:00
inline void PUT_WORD(UCHAR*& ptr, USHORT value)
{
*ptr++ = static_cast<UCHAR>(value);
*ptr++ = static_cast<UCHAR>(value >> 8);
}
2001-05-23 15:26:42 +02:00
#define PUT(ptr, value) *(ptr)++ = value;
#ifdef NOT_USED_OR_REPLACED
2001-05-23 15:26:42 +02:00
static SSHORT convert(ULONG, UCHAR *);
#endif
static ISC_STATUS merge_setup(const UCHAR**, UCHAR**, const UCHAR* const, USHORT);
2001-05-23 15:26:42 +02:00
USHORT MERGE_database_info(const UCHAR* in,
UCHAR* out,
USHORT out_length,
USHORT impl,
USHORT class_,
USHORT base_level,
const UCHAR* version,
2009-04-28 15:08:04 +02:00
const UCHAR* id)
//ULONG mask Was always zero
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* M E R G E _ d a t a b a s e _ i n f o
*
**************************************
*
* Functional description
* Merge server / remote interface / Y-valve information into
* database block. Return the actual length of the packet.
*
**************************************/
2007-09-11 11:31:51 +02:00
SSHORT l;
const UCHAR* p;
2001-05-23 15:26:42 +02:00
UCHAR* start = out;
const UCHAR* const end = out + out_length;
2001-05-23 15:26:42 +02:00
for (;;)
switch (*out++ = *in++)
{
2003-06-08 15:13:25 +02:00
case isc_info_end:
case isc_info_truncated:
2001-05-23 15:26:42 +02:00
return out - start;
2003-06-08 15:13:25 +02:00
case isc_info_firebird_version:
2001-05-23 15:26:42 +02:00
l = strlen((char *) (p = version));
if (l > MAX_UCHAR)
l = MAX_UCHAR;
2001-05-23 15:26:42 +02:00
if (merge_setup(&in, &out, end, l + 1))
return 0;
for (*out++ = (UCHAR) l; l; --l)
*out++ = *p++;
2001-05-23 15:26:42 +02:00
break;
2003-06-08 15:13:25 +02:00
case isc_info_db_id:
2001-05-23 15:26:42 +02:00
l = strlen((SCHAR *) (p = id));
if (l > MAX_UCHAR)
l = MAX_UCHAR;
2001-05-23 15:26:42 +02:00
if (merge_setup(&in, &out, end, l + 1))
return 0;
for (*out++ = (UCHAR) l; l; --l)
*out++ = *p++;
2001-05-23 15:26:42 +02:00
break;
2003-06-08 15:13:25 +02:00
case isc_info_implementation:
2001-05-23 15:26:42 +02:00
if (merge_setup(&in, &out, end, 2))
return 0;
PUT(out, (UCHAR) impl);
PUT(out, (UCHAR) class_);
break;
2003-06-08 15:13:25 +02:00
case isc_info_base_level:
2001-05-23 15:26:42 +02:00
if (merge_setup(&in, &out, end, 1))
return 0;
PUT(out, (UCHAR) base_level);
break;
default:
2007-09-11 11:31:51 +02:00
{
2007-11-17 11:18:10 +01:00
USHORT length = (USHORT) gds__vax_integer(in, 2);
2007-09-11 11:31:51 +02:00
in += 2;
2009-06-28 12:26:25 +02:00
if (out + length + 2 >= end)
{
2007-09-11 11:31:51 +02:00
out[-1] = isc_info_truncated;
return 0;
}
PUT_WORD(out, length);
while (length--)
*out++ = *in++;
2001-05-23 15:26:42 +02:00
}
break;
}
}
#ifdef NOT_USED_OR_REPLACED
2001-05-23 15:26:42 +02:00
static SSHORT convert( ULONG number, UCHAR * buffer)
{
/**************************************
*
* c o n v e r t
*
**************************************
*
* Functional description
* Convert a number to VAX form -- least significant bytes first.
* Return the length.
*
**************************************/
2004-12-09 03:53:19 +01:00
const UCHAR *p;
2001-05-23 15:26:42 +02:00
#ifndef WORDS_BIGENDIAN
2007-09-12 04:31:28 +02:00
p = (UCHAR *) &number;
2001-05-23 15:26:42 +02:00
*buffer++ = *p++;
*buffer++ = *p++;
*buffer++ = *p++;
*buffer++ = *p++;
#else
2007-09-12 04:31:28 +02:00
p = (UCHAR *) &number;
2001-05-23 15:26:42 +02:00
p += 3;
*buffer++ = *p--;
*buffer++ = *p--;
*buffer++ = *p--;
*buffer++ = *p;
#endif
return 4;
}
#endif
2001-05-23 15:26:42 +02:00
2009-01-16 10:55:38 +01:00
static ISC_STATUS merge_setup(const UCHAR** in, UCHAR** out, const UCHAR* const end,
USHORT delta_length)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* m e r g e _ s e t u p
*
**************************************
*
* Functional description
* Get ready to toss new stuff onto an info packet. This involves
* picking up and bumping the "count" field and copying what is
* already there.
*
**************************************/
USHORT length = (USHORT) gds__vax_integer(*in, 2);
const USHORT new_length = length + delta_length;
2001-05-23 15:26:42 +02:00
2009-06-28 12:26:25 +02:00
if (*out + new_length + 2 >= end)
{
2003-11-08 17:40:17 +01:00
(*out)[-1] = isc_info_truncated;
return FB_FAILURE;
2001-05-23 15:26:42 +02:00
}
*in += 2;
const USHORT count = 1 + *(*in)++;
2005-12-29 09:06:11 +01:00
PUT_WORD(*out, new_length);
2001-05-23 15:26:42 +02:00
PUT(*out, (UCHAR) count);
2009-04-16 08:52:08 +02:00
// Copy data portion of information sans original count
2001-05-23 15:26:42 +02:00
if (--length)
2007-09-11 11:31:51 +02:00
{
memcpy(*out, *in, length);
*out += length;
*in += length;
}
2001-05-23 15:26:42 +02:00
return FB_SUCCESS;
2001-05-23 15:26:42 +02:00
}