diff --git a/components/tparadoxdataset/lazparadoxpkg.lpk b/components/tparadoxdataset/lazparadoxpkg.lpk index e745273a8..0b3e230a5 100644 --- a/components/tparadoxdataset/lazparadoxpkg.lpk +++ b/components/tparadoxdataset/lazparadoxpkg.lpk @@ -16,6 +16,11 @@ + + + + + = 1) and (FHeader^.maxTableSize <= 4)) then - DatabaseError('No valid Paradox file !'); - } if not ((FHeader^.maxTableSize >= 1) and (FHeader^.maxTableSize <= 32)) then DatabaseError('No valid Paradox file !'); - if (FHeader^.fileVersionID = 12) then + if (FHeader^.fileVersionID >= 12) then FTableNameLen := 261 else FTableNameLen := 79; @@ -332,7 +346,18 @@ begin else FFieldInfoPtr := @FHeader^.FieldInfo; - if Encrypted then exit; + if Encrypted then + exit; + + FBlobStream := nil; + blobfn := ChangeFileExt(FFileName, '.mb'); + if FileExists(blobfn) then + FBlobStream := TFileStream.Create(blobfn, fmOpenRead + fmShareDenyNone) + else begin + blobfn := ChangeFileExt(FFileName, '.MB'); + if FileExists(blobfn) then + FBlobStream := TFileStream.Create(blobfn, fmOpenRead + fmShareDenyNone); + end; FaBlock := AllocMem(FHeader^.maxTableSize * $0400); BookmarkSize := SizeOf(longword); @@ -350,6 +375,7 @@ begin DestroyFields; FreeMem(FHeader); FreeMem(FaBlock); + FreeAndNil(FBlobStream); FreeAndNil(FStream); FHeader := nil; FActive := False; @@ -384,7 +410,7 @@ begin pxfBLOb: FieldDefs.Add(fname, ftBlob, F^.fSize); pxfFmtMemoBLOb: FieldDefs.Add(fname, ftMemo, F^.fSize); pxfOLE: FieldDefs.Add(fname, ftBlob, F^.fSize); - pxfGraphic: FieldDefs.Add(fname, ftBlob, F^.fSize); + pxfGraphic: FieldDefs.Add(fname, ftGraphic, F^.fSize); // was: ftBlob pxfTime: FieldDefs.Add(fname, ftTime, 0); //F^.fSize); pxfTimestamp: FieldDefs.Add(fname, ftDateTime, 0); pxfAutoInc: FieldDefs.Add(fname, ftAutoInc, F^.fSize); @@ -607,10 +633,12 @@ begin Inc(p, F^.fSize); Inc(F); end; + if F^.fType = pxfBCD then { BCD field size value not used for field size } size := 17 else size := F^.fSize; + if F^.fType in [pxfDate..pxfNumber, pxfTime..pxfAutoInc] then begin for i := 0 to pred(size) do @@ -621,7 +649,7 @@ begin end; case F^.fType of - pxfAlpha,pxfMemoBLOb,pxfFmtMemoBLOb: + pxfAlpha: //, pxfMemoBLOb, pxfFmtMemoBLOb: begin if (Buffer <> nil) then StrLCopy(Buffer, p, Field.Size) @@ -641,13 +669,13 @@ begin Move(i,Buffer^,sizeof(Integer)); Result := True; end; - pxfLong,pxfAutoInc: + pxfLong, pxfAutoInc: begin i := int; Move(i,Buffer^,sizeof(Integer)); Result := True; end; - pxfCurrency,pxfNumber: + pxfCurrency, pxfNumber: begin Move(d,Buffer^,sizeof(d)); Result := True; @@ -670,6 +698,10 @@ begin Move(s[0], Buffer^, 8); Result := true; end; + pxfGraphic: + begin + Result := ActiveBuffer <> nil; + end; end; end; @@ -684,5 +716,91 @@ begin inherited Destroy; end; +function TParadoxDataset.CreateBlobStream(Field: TField; + Mode: TBlobStreamMode): TStream; +var + memStream: TMemoryStream; + F: PFldInfoRec; + p: PChar; + header: PAnsiChar; + idx: Byte; + loc: Integer; + s: String; + blobInfo: TPxBlobInfo; + blobIndex: TPxBlobIndex; + i: Integer; +begin + memStream := TMemoryStream.Create; + Result := memStream; + + if (Mode <> bmRead) then + exit; + + F := FFieldInfoPtr; { begin with the first field identifier } + p := ActiveBuffer; + for i := 1 to FHeader^.numFields do + begin + if i = Field.FieldNo then + break; + if F^.fType = pxfBCD then { BCD field size value not used for field size } + Inc(p, 17) + else + Inc(p, F^.fSize); + Inc(F); + end; + + header := p + Field.Size - SizeOf(TPxBlobInfo); + Move(header^, blobInfo{%H-}, SizeOf(blobInfo)); + if blobInfo.Length = 0 then + exit; + + if blobInfo.Length > Field.Size - SizeOf(TPxBlobInfo) then + begin + if Assigned(FBlobStream) then begin + idx := blobInfo.FileLoc and $FF; + loc := blobInfo.FileLoc and $FFFFFF00; + if idx = $FF then begin + // Read from a single blob block + FBlobStream.Seek(loc + 9, soFromBeginning); + if Field.DataType = ftMemo then begin + SetLength(s, blobInfo.Length); + FBlobStream.Read(s[1], blobInfo.Length); + // if EncodingMemo then s := EncodingField(s, field); + memStream.Write(s[1], Length(s)); + end else + begin + if Field.DataType = ftGraphic then begin + memstream.WriteAnsiString('bmp'); + FBlobStream.Position := FBlobStream.Position + 8; + end; + memStream.CopyFrom(FBlobStream, blobInfo.Length); + end; + end else begin + // Read from a suballocated block + FBlobStream.Seek(loc + 12 + 5*idx, soFromBeginning); + FBlobStream.Read(blobIndex{%H-}, SizeOf(TPxBlobIndex)); + FBlobStream.Seek(loc + 16*blobIndex.Offset, soFromBeginning); + if Field.DataType = ftMemo then begin + SetLength(s, blobInfo.Length); + FBlobStream.Read(s[1], blobInfo.Length); + //if EncodingMemo then s := EncodingField(s, Field); + memStream.Write(s[1], Length(s)); + end else + memStream.CopyFrom(FBlobStream, blobInfo.Length); + end; + end; + end else + if Field.DataType = ftMemo then begin + SetLength(s, blobInfo.Length); + Move(p^, s[1], blobInfo.Length); + //if EncodingMemo then s := EncodingField(s, Field); + memStream.Write(s[1], Length(s)); + end else + memStream.Write(p, blobInfo.Length); + + memStream.Position := 0; +end; + + end.