Subject | Re: [ib-support] UDF with BLOB... |
---|---|
Author | Ann W. Harrison |
Post date | 2001-10-11T18:31:38Z |
At 01:48 AM 10/11/2001 -0400, Claudio Valderrama C. wrote:
at the time you define the column, but when you actually create the
blob itself. A single column can include both types of blob.
The second create blob call (isc_create_blob2) accepts a blob parameter
block which works like other parameter blocks. One of the items stuffed
there is isc_bpb_type which has values of isc_bpb_type_segmented or
isc_bpb_type_stream.
So, it's pretty low level, but completely available - are you reading
tool makers?
Relevant code follows.
Regards,
Ann
www.ibphoenix.com
We have answers.
From blb.c/create_blob2
/* Create a blob large enough to hold a single data page */
type = gds__parse_bpb2 (bpb_length, bpb, &from, &to, &from_charset,
&to_charset);
blob = allocate_blob (tdbb, transaction);
if (type)
blob->blb_flags |= BLB_stream;
from ibase.h
************************/
/* Blob Parameter Block */
/************************/
#define isc_bpb_version1 1
#define isc_bpb_source_type 1
#define isc_bpb_target_type 2
#define isc_bpb_type 3
#define isc_bpb_source_interp 4
#define isc_bpb_target_interp 5
#define isc_bpb_filter_parameter 6
#define isc_bpb_type_segmented 0
#define isc_bpb_type_stream 1
from gds.c/gds__parse_bpb2
USHORT API_ROUTINE gds__parse_bpb2 (
USHORT bpb_length,
UCHAR *bpb,
USHORT *source,
USHORT *target,
USHORT *source_interp,
USHORT *target_interp)
{
/**************************************
*
* g d s _ p a r s e _ b p b 2
*
**************************************
*
* Functional description
* Get blob type, source sub_type and target sub-type
* from a blob parameter block.
* Basically gds__parse_bpb() with additional:
* source_interp and target_interp.
*
**************************************/
UCHAR *p, *end, op;
USHORT type, length;
type = *source = *target = 0;
if (source_interp)
*source_interp = 0;
if (target_interp)
*target_interp = 0;
if (!bpb_length)
return type;
p = bpb;
end = p + bpb_length;
if (*p++ != gds__bpb_version1)
return type;
while (p < end)
{
op = *p++;
length = *p++;
switch (op)
{
case gds__bpb_source_type:
*source = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_target_type:
*target = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_type:
type = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_source_interp:
if (source_interp)
*source_interp = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_target_interp:
if (target_interp)
*target_interp = (USHORT)gds__vax_integer (p, length);
break;
default:
break;
}
p += length;
}
return type;
}
>In theory: create a stream blob (as opposed to typical segmented blobs) andYes. As it turns out, the segmented/stream difference happens not
>use the blobcallback structure definition that's in FB's ibase.h, then
>you'll have a function to seek...
>
>Now, the problem is whether you can create such stream blobs. I know they
>are used internally for arrays.
>
>Ann, are you reading?
at the time you define the column, but when you actually create the
blob itself. A single column can include both types of blob.
The second create blob call (isc_create_blob2) accepts a blob parameter
block which works like other parameter blocks. One of the items stuffed
there is isc_bpb_type which has values of isc_bpb_type_segmented or
isc_bpb_type_stream.
So, it's pretty low level, but completely available - are you reading
tool makers?
Relevant code follows.
Regards,
Ann
www.ibphoenix.com
We have answers.
From blb.c/create_blob2
/* Create a blob large enough to hold a single data page */
type = gds__parse_bpb2 (bpb_length, bpb, &from, &to, &from_charset,
&to_charset);
blob = allocate_blob (tdbb, transaction);
if (type)
blob->blb_flags |= BLB_stream;
from ibase.h
************************/
/* Blob Parameter Block */
/************************/
#define isc_bpb_version1 1
#define isc_bpb_source_type 1
#define isc_bpb_target_type 2
#define isc_bpb_type 3
#define isc_bpb_source_interp 4
#define isc_bpb_target_interp 5
#define isc_bpb_filter_parameter 6
#define isc_bpb_type_segmented 0
#define isc_bpb_type_stream 1
from gds.c/gds__parse_bpb2
USHORT API_ROUTINE gds__parse_bpb2 (
USHORT bpb_length,
UCHAR *bpb,
USHORT *source,
USHORT *target,
USHORT *source_interp,
USHORT *target_interp)
{
/**************************************
*
* g d s _ p a r s e _ b p b 2
*
**************************************
*
* Functional description
* Get blob type, source sub_type and target sub-type
* from a blob parameter block.
* Basically gds__parse_bpb() with additional:
* source_interp and target_interp.
*
**************************************/
UCHAR *p, *end, op;
USHORT type, length;
type = *source = *target = 0;
if (source_interp)
*source_interp = 0;
if (target_interp)
*target_interp = 0;
if (!bpb_length)
return type;
p = bpb;
end = p + bpb_length;
if (*p++ != gds__bpb_version1)
return type;
while (p < end)
{
op = *p++;
length = *p++;
switch (op)
{
case gds__bpb_source_type:
*source = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_target_type:
*target = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_type:
type = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_source_interp:
if (source_interp)
*source_interp = (USHORT)gds__vax_integer (p, length);
break;
case gds__bpb_target_interp:
if (target_interp)
*target_interp = (USHORT)gds__vax_integer (p, length);
break;
default:
break;
}
p += length;
}
return type;
}