You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5438 8e941d3f-bd1b-0410-a28a-d453659cc2b4
224 lines
8.8 KiB
ObjectPascal
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.
|