Files
lazarus-ccr/components/flashfiler/sourcelaz/ffsrblob.pas
2016-12-07 13:31:59 +00:00

224 lines
8.8 KiB
ObjectPascal

{*********************************************************}
{* FlashFiler: BLOB retrieval & verification routines *}
{*********************************************************}
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* 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 is TurboPower FlashFiler
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1996-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{$I ffdefine.inc}
unit ffsrblob;
interface
uses
ffllbase,
ffsrbase,
ffsrlock;
{---Blob retrieval & verification routines---}
function ReadBLOBBlock(FI : PffFileInfo;
TI : PffTransInfo;
const anOffset : TffInt64;
var aOffsetInBlock : TffWord32; {!!.11}
var aReleaseMethod : TffReleaseMethod)
: PffBlock;
{ Reads the BLOB block containing the specified offset. This method does
not perform any locking so use it only when the block has previously
been locked and the lock is still in effect. }
function ReadVfyBlobBlock(FI : PffFileInfo;
TI : PffTransInfo;
const aMarkDirty : Boolean;
const anOffset : TffInt64;
var aOffsetInBlock : TffWord32; {!!.11}
var aReleaseMethod : TffReleaseMethod)
: PffBlock;
function ReadVfyBlobBlock2(FI : PffFileInfo;
TI : PffTransInfo;
const aMarkDirty : Boolean;
const anOffset : TffInt64;
var aBlockNum : TffWord32;
var aOffsetInBlock : TffWord32; {!!.11}
var aReleaseMethod : TffReleaseMethod)
: PffBlock;
function ReadVfyBlobBlock3(FI : PffFileInfo;
TI : PffTransInfo;
const aMarkDirty : Boolean;
const anOffset : TffInt64;
var aReleaseMethod : TffReleaseMethod)
: PffBlock;
implementation
uses
ffconst,
ffllexcp,
fftbbase;
{== Block verification routines ======================================}
function ReadBLOBBlock(FI : PffFileInfo;
TI : PffTransInfo;
const anOffset : TffInt64;
var aOffsetInBlock : TffWord32; {!!.11}
var aReleaseMethod : TffReleaseMethod)
: PffBlock;
var
BlockNumber : TffWord32;
BLOBBlock : PffBlock;
BLOBBlockHdr: PffBlockHeaderBLOB absolute BLOBBlock;
TempI64 : TffInt64;
begin
{ Assumptions: The block was previously read and successfully verified.
The block was previously locked and the lock is still in
effect. }
with FI^ do begin
{ Get the BLOB block. }
ffShiftI64R(anOffset, fiLog2BlockSize, TempI64);
BlockNumber := TempI64.iLow;
ffI64MinusInt(anOffset, (BlockNumber shl fiLog2BlockSize), TempI64);
aOffsetInBlock := TempI64.iLow;
BLOBBlock := FI^.fiBufMgr.GetBlock(FI, BlockNumber, TI, false, aReleaseMethod);
end;
Result := BLOBBlock;
end;
{--------}
function ReadVfyBlobBlock(FI : PffFileInfo;
TI : PffTransInfo;
const aMarkDirty : boolean;
const anOffset : TffInt64;
var aOffsetInBlock : TffWord32; {!!.11}
var aReleaseMethod : TffReleaseMethod)
: PffBlock;
var
BlockNumber : TffWord32;
BLOBBlock : PffBlock;
BLOBBlockHdr: PffBlockHeaderBLOB absolute BLOBBlock;
TempI64 : TffInt64;
begin
with FI^ do begin
{verify the BLOB number}
if not FFVerifyBLOBNr(anOffset, fiLog2BlockSize) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBLOBNr, [FI^.fiName^, anOffset.iLow,
anOffset.iHigh]);
{now get the BLOB block}
ffShiftI64R(anOffset, fiLog2BlockSize, TempI64);
BlockNumber := TempI64.iLow;
if (BlockNumber <= 0) or (BlockNumber >= fiUsedBlocks) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBlockNr, [FI^.fiName^, BlockNumber]);
ffI64MinusInt(anOffset, (BlockNumber shl fiLog2BlockSize), TempI64);
aOffsetInBlock := TempI64.iLow;
BLOBBlock := FFBMGetBlock(FI, TI, BlockNumber, aMarkDirty, aReleaseMethod);
{ Verify that it's a BLOB header block. }
with BLOBBlockHdr^ do
if (bhbSignature <> ffc_SigBLOBBlock) or
(bhbThisBlock <> BlockNumber) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBLOBBlock, [FI^.fiName^, BlockNumber]);
end;
Result := BLOBBlock;
end;
{--------}
function ReadVfyBlobBlock2(FI : PffFileInfo;
TI : PffTransInfo;
const aMarkDirty : boolean;
const anOffset : TffInt64;
var aBlockNum : TffWord32;
var aOffsetInBlock : TffWord32; {!!.11}
var aReleaseMethod : TffReleaseMethod)
: PffBlock;
var
BLOBBlock : PffBlock;
BLOBBlockHdr: PffBlockHeaderBLOB absolute BLOBBlock;
TempI64 : TffInt64;
begin
with FI^ do begin
{verify the BLOB number}
if not FFVerifyBLOBNr(anOffset, fiLog2BlockSize) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBLOBNr, [FI^.fiName^, anOffset.iLow,
anOffset.iHigh]);
{now get the BLOB block}
ffShiftI64R(anOffset, fiLog2BlockSize, TempI64);
aBlockNum := TempI64.iLow;
if (aBlockNum <= 0) or (aBlockNum >= fiUsedBlocks) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBlockNr, [FI^.fiName^, aBlockNum]);
ffI64MinusInt(anOffset, (aBlockNum shl fiLog2BlockSize), TempI64);
aOffsetInBlock := TempI64.iLow;
BLOBBlock := FFBMGetBlock(FI, TI, aBlockNum, aMarkDirty, aReleaseMethod);
{verify that it's a BLOB header block}
with BLOBBlockHdr^ do
if (bhbSignature <> ffc_SigBLOBBlock) or
(bhbThisBlock <> aBlockNum) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBLOBBlock, [FI^.fiName^, aBlockNum]);
end;
Result := BLOBBlock;
end;
{--------}
function ReadVfyBlobBlock3(FI : PffFileInfo;
TI : PffTransInfo;
const aMarkDirty : boolean;
const anOffset : TffInt64;
var aReleaseMethod : TffReleaseMethod) : PffBlock;
var
BlockNumber : TffWord32;
BLOBBlock : PffBlock;
BLOBBlockHdr: PffBlockHeaderBLOB absolute BLOBBlock;
TempI64 : TffInt64;
begin
with FI^ do begin
{verify the segment number}
if not FFVerifyBLOBNr(anOffset, fiLog2BlockSize) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBLOBSeg, [FI^.fiName^, anOffset.iLow,
anOffset.iHigh, '']);
{get the BLOB block}
ffShiftI64R(anOffset, fiLog2BlockSize, TempI64);
BlockNumber := TempI64.iLow;
if (BlockNumber <= 0) or (BlockNumber >= fiUsedBlocks) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBlockNr, [FI^.fiName^, BlockNumber]);
BLOBBlock := FFBMGetBlock(FI, TI, BlockNumber, aMarkDirty, aReleaseMethod);
{verify that it's a BLOB block}
with BLOBBlockHdr^ do
if (bhbSignature <> ffc_SigBLOBBlock) or
(bhbThisBlock <> BlockNumber) then
FFRaiseException(EffServerException, ffStrResServer,
fferrBadBLOBBlock, [FI^.fiName^, BlockNumber]);
end;
Result := BLOBBlock;
end;
{====================================================================}
end.