- On in the declaration of TIbBlobInfo structure, where the NumSegments and the MaxSegmentSize are declared as SmallInt (-32K..32K), but the correct definition is Word (0..65K). This cause problem when BLOB segment sizes or segment count is greater than 32K.
- The other one is in the ReadBlobBufer procedure, where the SegmentLenght is set to DefaultBlobSegmentSize (16K), which is not the correct size. The correct size can be readed from the BlobInfo.MaxSegmentSize. This cause problem, when BLOB segment size greater than 16K.
I made some modifications in source code, and I sent it earlier, but when I download the current version, I saw, that the source code is the original (buggy) .
So I put here the source modifications...
Code: Select all
//------------------------------------------------------
// Interbase BLOB handling error modifications
// src/dbc/ZDbcInterbase6Utils.pas file
//------------------------------------------------------
//... original code
type
{ Interbase Statement Type }
TZIbSqlStatementType = (stUnknown, stSelect, stInsert, stUpdate, stDelete,
stDDL, stGetSegment, stPutSegment, stExecProc, stStartTrans, stCommit,
stRollback, stSelectForUpdate, stSetGenerator);
{ Interbase Error Class}
EZIBConvertError = class(Exception);
{ Paparameter string name and it value}
TZIbParam = record
Name: string;
Number: word;
end;
PZIbParam = ^TZIbParam;
{ Interbase blob Information structure
contain iformation about blob size in bytes,
segments count, segment size in bytes and blob type
Note: blob type can be text an binary }
//----------------------------------------------------
// PL modifications - bad type SmallInt -> Word
// We need unsigned integers here....
//----------------------------------------------------
TIbBlobInfo = record
NumSegments: Word; // was SmallInt;
MaxSegmentSize: Word; // was SmallInt;
BlobType: SmallInt;
TotalSize: LongInt;
end;
//----------------------------------------------------
// PL modifications end
//----------------------------------------------------
// ... original code
procedure ReadBlobBufer(PlainDriver: IZInterbasePlainDriver;
Handle: PISC_DB_HANDLE; TransactionHandle: PISC_TR_HANDLE;
BlobId: TISC_QUAD; var Size: Integer; var Buffer: Pointer);
var
TempBuffer: PChar;
BlobInfo: TIbBlobInfo;
BlobSize, CurPos: LongInt;
BytesRead, SegmentLenght: UShort;
BlobHandle: TISC_BLOB_HANDLE;
StatusVector: TARRAY_ISC_STATUS;
begin
BlobHandle := nil;
CurPos := 0;
//----------------------------------------------------
// PL modifications - bad segment size value,
// The default size is not good...
// This line is unneccessary, because we will set
// the segment length from the blobinfo.
//----------------------------------------------------
// SegmentLenght := UShort(DefaultBlobSegmentSize);
//----------------------------------------------------
// PL modifications end
//----------------------------------------------------
{ open blob }
PlainDriver.isc_open_blob2(@StatusVector, Handle,
TransactionHandle, @BlobHandle, @BlobId, 0 , nil);
CheckInterbase6Error(PlainDriver, StatusVector);
{ get blob info }
GetBlobInfo(PlainDriver, BlobHandle, BlobInfo);
BlobSize := BlobInfo.TotalSize;
Size := BlobSize;
//----------------------------------------------------
// PL modifications - Now, we can set the correct
// segment length. Add this line here to code.
//----------------------------------------------------
SegmentLenght := BlobInfo.MaxSegmentSize;
//----------------------------------------------------
// PL modifications end
//----------------------------------------------------
// ... original code