8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-27 20:03:03 +01:00
firebird-mirror/src/jrd/mblr.cpp

709 lines
13 KiB
C++
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Access Method
* MODULE: MBLR.C
* DESCRIPTION: RDB DDL Call translator
* Translate MBLR byte strings to DYN byte strings.
*
* 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 "../jrd/common.h"
#include "../jrd/gds.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/mblr.h"
#include "../jrd/mblr_proto.h"
#define GET_BYTE(op) op = (*mblr->met_mblr++); mblr->met_mblr_length--
#define GET_WORD(op) op = get_word (mblr)
#define PEEK_BYTE (*mblr->met_mblr)
#define STUFF(dyn) (*mblr->met_dyn++) = (dyn)
#define STUFF_END STUFF (gds_dyn_end)
#define STUFF_LITERAL get_literal (mblr)
#define STUFF_LITERAL_W get_literal_w (mblr)
#define STUFF_WORD(dyn) STUFF (dyn); STUFF (dyn >> 8)
#define STUFF_INT(dyn) STUFF (dyn); STUFF (dyn >> 8); STUFF (dyn >> 16); STUFF (dyn >> 24)
#define IN_FIELD 1
#define IN_INDEX 2
#define IN_RELATION 3
#define IN_VIEW 4
typedef struct met {
UCHAR met_op;
UCHAR *met_mblr;
UCHAR *met_dyn;
USHORT met_mblr_length;
USHORT met_dyn_length;
} *MET;
static int area, level, duplicates;
static int field_def(MET);
static int field_descriptor(MET);
static void get_literal(MET);
static void get_literal_w(MET);
static int get_word(MET);
static int index_def(MET);
static int parse_mblr(MET);
static int relation_def(MET);
static int view_def(MET);
int MBLR_translate_to_dyn(
USHORT ddl_operation,
USHORT mblr_buffer_length,
UCHAR * mblr_buffer,
USHORT * dyn_length, UCHAR * dyn_buffer)
{
/************************************************
*
* M B L R _ t r a n s l a t e _ t o _ d y n
*
************************************************
*
* Functional description
* Translate Rdb/VMS RDB$DDL call MBLR byte-string
* to a DYN byte-string. DYN string is created in
* a buffer passed by the caller. This routine
* returns the length of the DYN string, or zero
* for any failure.
*
************************************************/
struct met mblr;
UCHAR op;
int result;
UCHAR *dyn_start;
level = FALSE;
if ((ddl_operation != mblr$k_define) &&
(ddl_operation != mblr$k_modify) && (ddl_operation != mblr$k_delete))
return FALSE;
mblr.met_op = ddl_operation;
mblr.met_mblr = mblr_buffer;
mblr.met_mblr_length = mblr_buffer_length;
mblr.met_dyn = dyn_start = dyn_buffer;
mblr.met_dyn_length = 0;
op = *mblr.met_mblr++;
mblr.met_mblr_length--;
if (op != mblr$k_version_1)
return NULL;
*mblr.met_dyn++ = (gds_dyn_version_1);
*mblr.met_dyn++ = (gds_dyn_begin);
op = *mblr.met_mblr++;
mblr.met_mblr_length--;
switch (op) {
case mblr$k_relation_def:
area = IN_RELATION;
result = relation_def(&mblr);
break;
case mblr$k_field_def:
area = IN_FIELD;
result = field_def(&mblr);
break;
case mblr$k_view_def:
area = IN_VIEW;
result = view_def(&mblr);
break;
case mblr$k_index_def:
area = IN_INDEX;
result = index_def(&mblr);
break;
default:
return FALSE;
}
*mblr.met_dyn++ = (gds_dyn_end);
*mblr.met_dyn++ = (gds_dyn_eoc);
*dyn_length = mblr.met_dyn - dyn_start;
return result;
}
static int field_def(MET mblr)
{
/**************************************
*
* f i e l d _ d e f
*
**************************************
*
* Functional description
* Translate a field modify / update / delete.
*
**************************************/
int op, result;
result = TRUE;
switch (mblr->met_op) {
case mblr$k_modify:
STUFF(gds_dyn_mod_global_fld);
STUFF_LITERAL;
while ((PEEK_BYTE != mblr$k_field_end) && result)
result = parse_mblr(mblr);
break;
case mblr$k_define:
if (level)
STUFF(gds_dyn_def_local_fld);
else
STUFF(gds_dyn_def_global_fld);
STUFF_LITERAL;
while ((PEEK_BYTE != mblr$k_field_end) && result)
result = parse_mblr(mblr);
break;
case mblr$k_delete:
if (area == IN_FIELD)
STUFF(gds_dyn_delete_global_fld);
else
STUFF(gds_dyn_delete_local_fld);
STUFF_LITERAL;
break;
}
if (level)
GET_BYTE(op);
STUFF_END;
return result;
}
static int index_def(MET mblr)
{
/**************************************
*
* i n d e x _ d e f
*
**************************************
*
* Functional description
* Translate a index modify / update / delete.
*
**************************************/
2001-12-24 03:51:06 +01:00
int result;
2001-05-23 15:26:42 +02:00
result = TRUE;
switch (mblr->met_op) {
case mblr$k_modify:
result = FALSE;
break;
case mblr$k_define:
duplicates = FALSE;
STUFF(gds_dyn_def_idx);
STUFF_LITERAL;
while ((PEEK_BYTE != mblr$k_index_end) && result)
result = parse_mblr(mblr);
STUFF(gds_dyn_idx_inactive);
STUFF(FALSE);
if (duplicates == FALSE) {
STUFF(gds_dyn_idx_unique);
STUFF_WORD(2);
STUFF_WORD(TRUE);
}
break;
case mblr$k_delete:
STUFF(gds_dyn_delete_idx);
STUFF_LITERAL;
break;
}
STUFF_END;
return result;
}
static int relation_def(MET mblr)
{
/**************************************
*
* r e l a t i o n _ d e f
*
**************************************
*
* Functional description
* Translate a relation modify / update / delete.
*
**************************************/
2001-12-24 03:51:06 +01:00
int result;
2001-05-23 15:26:42 +02:00
level = result = TRUE;
switch (mblr->met_op) {
case mblr$k_modify:
STUFF(gds_dyn_mod_rel);
break;
case mblr$k_define:
STUFF(gds_dyn_def_rel);
break;
case mblr$k_delete:
STUFF(gds_dyn_delete_rel);
break;
}
STUFF_LITERAL;
while ((PEEK_BYTE != mblr$k_relation_end) && result)
result = parse_mblr(mblr);
STUFF_END;
return result;
}
static int view_def(MET mblr)
{
/**************************************
*
* v i e w _ d e f
*
**************************************
*
* Functional description
* Translate a view modify / update / delete.
*
**************************************/
2001-12-24 03:51:06 +01:00
int result;
2001-05-23 15:26:42 +02:00
result = TRUE;
switch (mblr->met_op) {
case mblr$k_modify:
result = FALSE;
break;
case mblr$k_define:
STUFF(gds_dyn_def_view);
STUFF_LITERAL;
while ((PEEK_BYTE != mblr$k_view_end) && result)
result = parse_mblr(mblr);
break;
case mblr$k_delete:
STUFF(gds_dyn_delete_rel);
STUFF_LITERAL;
break;
}
STUFF_END;
return result;
}
static int field_descriptor(MET mblr)
{
/**************************************
*
* f i e l d _ d e s c r i p t o r
*
**************************************
*
* Functional description
* Translate an mblr field description string
* from within a define relation statement.
*
**************************************/
int op, type, result;
result = TRUE;
GET_BYTE(op);
STUFF(gds_dyn_fld_type);
GET_BYTE(type);
switch (type) {
case dsc$k_dtype_adt:
STUFF_WORD(2);
STUFF_WORD(blr_timestamp);
break;
case dsc$k_dtype_b:
STUFF_WORD(2);
STUFF_WORD(blr_text);
STUFF(gds_dyn_fld_length);
STUFF_WORD(2);
STUFF_WORD(1);
break;
case dsc$k_dtype_f:
case dsc$k_dtype_g:
STUFF_WORD(2);
STUFF_WORD(type);
break;
case dsc$k_dtype_l:
case dsc$k_dtype_q:
case dsc$k_dtype_w:
STUFF_WORD(2);
STUFF_WORD(type);
STUFF(gds_dyn_fld_scale);
STUFF_WORD(2);
GET_BYTE(type);
STUFF_WORD(type);
break;
case dsc$k_dtype_qu:
STUFF_WORD(2);
STUFF_WORD(blr_blob);
break;
case dsc$k_dtype_t:
STUFF_WORD(2);
STUFF_WORD(blr_text);
STUFF(gds_dyn_fld_length);
STUFF_WORD(2);
GET_WORD(type);
STUFF_WORD(type);
break;
case dsc$k_dtype_vt:
STUFF_WORD(2);
STUFF_WORD(blr_varying);
STUFF(gds_dyn_fld_length);
STUFF_WORD(2);
GET_WORD(type);
STUFF_WORD(type);
break;
default:
STUFF_WORD(2);
STUFF_WORD(blr_short);
break;
}
return result;
}
static void get_literal(MET mblr)
{
/**************************************
*
* g e t _ l i t e r a l
*
**************************************
*
* Functional description
* Get a length prefixed literal (byte)
* Note: most MBLR literals use a byte as a length prefix,
* DYN literals use a word.
*
**************************************/
int length, op, n;
GET_BYTE(length);
n = length;
STUFF_WORD(length);
while (--n >= 0) {
GET_BYTE(op);
STUFF(op);
}
return;
}
static void get_literal_w(MET mblr)
{
/**************************************
*
* g e t _ l i t e r a l_w
*
**************************************
*
* Functional description
* Get a length prefixed literal (word)
*
**************************************/
int length, op, n;
GET_WORD(length);
n = length;
STUFF_WORD(length);
while (--n >= 0) {
GET_BYTE(op);
STUFF(op);
}
return;
}
static int get_word(MET mblr)
{
/**************************************
*
* g e t _ w o r d
*
**************************************
*
* Functional description
* Pick up a VAX style word.
*
**************************************/
int op, i;
GET_BYTE(op);
GET_BYTE(i);
op |= i << 8;
return op;
}
static int parse_mblr(MET mblr)
{
/***************************************************
*
* p a r s e _ m b l r
*
***************************************************
*
* Functional description
* Primary recursive routine to translate mblr.
*
***************************************************/
2001-12-24 03:51:06 +01:00
int op, result, save_area;
2001-05-23 15:26:42 +02:00
UCHAR *save_dyn;
if (!mblr->met_mblr_length)
return FALSE;
op = PEEK_BYTE;
result = TRUE;
switch (op) {
case mblr$k_change_attributes:
case mblr$k_descriptor:
result = field_descriptor(mblr);
break;
case mblr$k_change_field:
case mblr$k_delete_field:
case mblr$k_define_field:
save_area = area;
area = IN_FIELD;
GET_BYTE(op);
result = field_def(mblr);
area = save_area;
break;
case mblr$k_dtr_def_val:
GET_BYTE(op);
STUFF(gds_dyn_fld_default_value);
STUFF_LITERAL;
break;
case mblr$k_dtr_edit_str:
GET_BYTE(op);
STUFF(gds_dyn_fld_edit_string);
STUFF_LITERAL;
break;
case mblr$k_dtr_qry_hdr:
GET_BYTE(op);
if (PEEK_BYTE == mblr$k_dtr_qry_hdr_line) {
GET_BYTE(op);
GET_BYTE(op);
mblr->met_mblr += op;
if (PEEK_BYTE != mblr$k_dtr_qry_hdr_end)
result = FALSE;
}
else
result = FALSE;
break;
case mblr$k_duplicates:
GET_BYTE(op);
duplicates = TRUE;
break;
case mblr$k_field_def:
GET_BYTE(op);
result = field_def(mblr);
break;
case mblr$k_field_expression:
GET_BYTE(op);
STUFF(gds_dyn_fld_computed_blr);
save_dyn = mblr->met_dyn;
STUFF_LITERAL_W;
STUFF(blr_eoc);
(*save_dyn)++;
break;
case mblr$k_field_name:
GET_BYTE(op);
if (area == IN_INDEX)
STUFF(gds_dyn_fld_name);
else
STUFF(gds_dyn_fld_source);
STUFF_LITERAL;
break;
case mblr$k_missing_value:
GET_BYTE(op);
STUFF(gds_dyn_fld_missing_value);
save_dyn = mblr->met_dyn;
STUFF_LITERAL_W;
STUFF(blr_eoc);
(*save_dyn)++;
break;
case mblr$k_relation_name:
GET_BYTE(op);
STUFF(gds_dyn_rel_name);
STUFF_LITERAL;
break;
case mblr$k_rse:
GET_BYTE(op);
STUFF(gds_dyn_view_blr);
save_dyn = mblr->met_dyn;
STUFF_LITERAL_W;
STUFF(blr_eoc);
(*save_dyn)++;
break;
case mblr$k_valid_if:
GET_BYTE(op);
STUFF(gds_dyn_fld_validation_blr);
save_dyn = mblr->met_dyn;
STUFF_LITERAL_W;
STUFF(blr_eoc);
(*save_dyn)++;
break;
case mblr$k_dtr_qry_nam:
GET_BYTE(op);
STUFF(gds_dyn_fld_query_name);
STUFF_LITERAL;
break;
case mblr$k_valid_if_source:
GET_BYTE(op);
STUFF(gds_dyn_fld_validation_source);
STUFF_LITERAL_W;
break;
case mblr$k_computed_by_source:
GET_BYTE(op);
STUFF(gds_dyn_fld_computed_source);
STUFF_LITERAL_W;
break;
case mblr$k_rse_source:
GET_BYTE(op);
STUFF(gds_dyn_view_source);
STUFF_LITERAL_W;
break;
case mblr$k_description_source:
GET_BYTE(op);
STUFF(gds_dyn_description);
STUFF_LITERAL_W;
break;
case mblr$k_sub_type:
GET_BYTE(op);
STUFF(gds_dyn_fld_sub_type);
STUFF_WORD(2);
GET_WORD(op);
STUFF_WORD(op);
break;
case mblr$k_segment_length:
GET_BYTE(op);
STUFF(gds_dyn_fld_segment_length);
STUFF_WORD(2);
GET_WORD(op);
STUFF_WORD(op);
break;
case mblr$k_field_noupdate:
case mblr$k_field_update:
GET_BYTE(op);
break;
case mblr$k_index_unknown1:
GET_BYTE(op);
break;
case mblr$k_index_unknown2:
GET_BYTE(op);
GET_BYTE(op);
GET_BYTE(op);
break;
case mblr$k_field_end:
case mblr$k_index_end:
case mblr$k_relation_end:
case mblr$k_view_end:
break;
case mblr_null:
case mblr$k_cdd_path:
case mblr$k_commit:
case mblr$k_constraint:
case mblr$k_constraint_count:
case mblr$k_constraint_def:
case mblr$k_constraint_end:
case mblr$k_delete_attributes:
case mblr$k_dtr_qry_hdr_line:
case mblr$k_dtr_qry_hdr_end:
case mblr$k_update:
default:
result = FALSE;
break;
}
return result;
}