1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91:
| uses Windows, SysUtils, Variants, Classes, Graphics, IBHeader, IBBlob, IBIntf, IB, IBErrorcodes;
type TCBBlobCallBackMode = (bcbmStart, bcbmProgress, bcbmEnd); TCBBlobCallBack = procedure (ATotal, AReceived: Integer; AMode: TCBBlobCallBackMode) of Object;
function cbGetBlobWithCallBack(ABlobID: TISC_Quad; ADBHandle: PISC_DB_Handle; ATRHandle: PISC_TR_Handle; AFileName: String; ACallBack: TCBBlobCallBack): Boolean;
...
interface
function cbGetBlobWithCallBack(ABlobID: TISC_Quad; ADBHandle: PISC_DB_Handle; ATRHandle: PISC_TR_Handle; AFileName: String; ACallBack: TCBBlobCallBack): Boolean; var LBlobHandle: TISC_BLOB_HANDLE; LSeg, LSize, LTotal: LongInt; LType: Short; LBuffer: PChar; LCurPos: LongInt; LBytesRead, LSegLen: Word; LLocalBuffer: PChar; LStream: TMemoryStream; begin result := false; LBlobHandle := nil;
GetGDSLibrary.isc_open_blob2(StatusVector, ADBHandle, ATRHandle, @LBlobHandle, @ABlobID, 0, nil);
try IBBlob.GetBlobInfo(@LBlobHandle, LSeg, LSize, LTotal, LType);
if assigned(ACallBack) then ACallBack(LTotal, 0, bcbmStart);
LBuffer := nil; ReallocMem(LBuffer, LTotal); LLocalBuffer := LBuffer; LCurPos := 0; LSegLen := Word(DefaultBlobSegmentSize); while (LCurPos < LTotal) do begin if (LCurPos + LSegLen > LTotal) then LSegLen := LTotal - LCurPos; if not ((GetGDSLibrary.isc_get_segment(StatusVector, @LBlobHandle, @LBytesRead, LSegLen, LLocalBuffer) = 0) or (StatusVectorArray[1] = isc_segment)) then IBDatabaseError; Inc(LLocalBuffer, LBytesRead); Inc(LCurPos, LBytesRead); if assigned(ACallBack) then ACallBack(LTotal, LBytesRead, bcbmProgress); LBytesRead := 0; end;
if assigned(ACallBack) then ACallBack(LTotal, LBytesRead, bcbmEnd);
LStream := TMemoryStream.Create; try LStream.WriteBuffer(LBuffer^, LTotal); LStream.SaveToFile(AFileName); finally FreeAndNil(LStream); end; finally GetGDSLibrary.isc_close_blob(StatusVector, @LBlobHandle); result := true; end; end; |