constructor TBlobStream.Create(Field: TBlobField; Mode: TBlobStreamMode);
var
OpenMode: DbiOpenMode;
begin
FField := Field;
FDataSet := Field.DataSet;
FRecord := FDataSet.ActiveBuffer;
FFieldNo := Field.FieldNo;
if FDataSet.State = dsFilter then
DBErrorFmt(SNoFieldAccess, [FField.DisplayName]);
if not FField.FModified then
begin
if Mode = bmRead then
begin
FBuffer := AllocMem(FDataSet.RecordSize);
FRecord := FBuffer;
if not FDataSet.GetCurrentRecord(FBuffer) then Exit;
OpenMode := dbiReadOnly;
end else
begin
if not (FDataSet.State in [dsEdit, dsInsert]) then DBError(SNotEditing);
OpenMode := dbiReadWrite;
end;
Check(DbiOpenBlob(FDataSet.Handle, FRecord, FFieldNo, OpenMode));
end;
FOpened := True;
if Mode = bmWrite then Truncate;
end;
destructor TBlobStream.Destroy;
begin
if FOpened then
begin
if FModified then FField.FModified := True;
if not FField.FModified then
DbiFreeBlob(FDataSet.Handle, FRecord, FFieldNo);
end;
if FBuffer <> nil then FreeMem(FBuffer, FDataSet.RecordSize);
if FModified then
try
FField.DataChanged;
except
Application.HandleException(Self);
end;
end;
function TBlobStream.Read(var Buffer; Count: Longint): Longint;
var
Status: DBIResult;
begin
Result := 0;
if FOpened then
begin
Status := DbiGetBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,
Count, @Buffer, Result);
case Status of
DBIERR_NONE, DBIERR_ENDOFBLOB:
begin
if FField.FTransliterate then
NativeToAnsiBuf(FDataSet.Locale, @Buffer, @Buffer, Result);
Inc(FPosition, Result);
end;
DBIERR_INVALIDBLOBOFFSET:
{Nothing};
else
DbiError(Status);
end;
end;
end;
function TBlobStream.Write(const Buffer; Count: Longint): Longint;
var
Temp: Pointer;
begin
Result := 0;
if FOpened then
begin
if FField.FTransliterate then
begin
GetMem(Temp, Count);
try
AnsiToNativeBuf(FDataSet.Locale, @Buffer, Temp, Count);
Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,
Count, Temp));
finally
FreeMem(Temp, Count);
end;
end else
Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,
Count, @Buffer));
Inc(FPosition, Count);
Result := Count;
FModified := True;
end;
end;
procedure TBlobStream.Truncate;
begin
if FOpened then
begin
Check(DbiTruncateBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition));
FModified := True;
end;
end;