⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kbmmembinarystreamformat.pas

📁 kbmMemTable v5.50 (Dec. 12 2005)内存表控件
💻 PAS
📖 第 1 页 / 共 3 页
字号:
             while not(Reader.EndofList) do
             begin
                  // Clear previous setup if not cleared yet.
                  if not InitIndexDef then
                  begin
                       if ld and ldidx then
                       begin
                            ADataSet.DestroyIndexes;
                            ADataSet.IndexDefs.Clear;
                       end;
                       InitIndexDef:=true;
                  end;

                  // read index definition.
                  FName := Reader.ReadString;
                  FFields := Reader.ReadString;
                  DName := Reader.ReadString;

                  ioptions:=[];
                  if Reader.ReadBoolean then ioptions:=ioptions+[ixDescending];
                  if Reader.ReadBoolean then ioptions:=ioptions+[ixCaseInSensitive];

{$IFNDEF LEVEL3}
                  if Reader.ReadBoolean then ioptions:=ioptions+[ixNonMaintained];
{$ELSE}
                  Reader.ReadBoolean;     // Skip ixNonMaintained info since not supported for D3/BCB3.
{$ENDIF}
                  if Reader.ReadBoolean then ioptions:=ioptions+[ixUnique];

                  // Add index definition.
                  if ld and ldidx then
                  begin
{$IFNDEF LEVEL3}
                       aIndexDef := ADataSet.IndexDefs.AddIndexDef;
                       aIndexDef.Name:=FName;
                       aIndexDef.Fields:=FFields;
                       aIndexDef.Options:=ioptions;
                       aIndexDef.DisplayName:=DName;
{$ELSE}
                       IndexDefs.Add(FName,FFields,ioptions);
{$ENDIF}
                  end;
             end;
             Reader.ReadListEnd;
        end;
     finally
        if InitTableDef then ADataSet.Open;
     end;
     if not (ld and ldidx) then InitIndexDef:=false;
end;

procedure TkbmCustomBinaryStreamFormat.LoadData(ADataset:TkbmCustomMemTable);
   procedure SkipField(AFieldType:TFieldType);
   begin
        case AFieldType of
          ftBoolean :   Reader.ReadBoolean;

{$IFNDEF LEVEL3}
          ftLargeInt:   Reader.ReadFloat;
          ftWideString: Reader.ReadString;
{$ENDIF}

          ftSmallInt,
          ftInteger,
          ftWord :      Reader.ReadInteger;

          ftAutoInc :   Reader.ReadInteger;

          ftFloat :     Reader.ReadFloat;

          ftBCD,
          ftCurrency :  Reader.ReadFloat;

          ftDate,
          ftTime,
          ftDateTime : Reader.ReadFloat;
        else
          Reader.ReadString;
        end;
   end;
var
   i,j:integer;
   nf:integer;
   Accept:boolean;
   bNull:boolean;
   Date:double;
   NewestVersion:boolean;
   pRec:PkbmRecord;
   ApproxRecs:integer;
   fc,fno:integer;
   ftypes:array of TFieldType;
{$IFDEF DOTNET}
   ARec,Rec:TKbmRecord;
{$ENDIF}
begin
     if (StreamSize = 0) then exit;

     ADataSet.__SetTempState(dsinsert);
     try
        ADataSet.ResetAutoInc;

        // Try to determine approx how many records in stream + add some slack.
        if ADataSet.RecordSize>0 then
        begin
             ApproxRecs:=StreamSize div ADataSet.Common.DataRecordSize;
             ApproxRecs:=ApproxRecs + (ApproxRecs div 50) + ADataSet.RecordCount;
        end
        else
            ApproxRecs:=0;

{$IFDEF LEVEL4}
        nf:=length(LoadFields);
{$ELSE}
        nf:=LoadFieldsCount;
{$ENDIF}

        // Load datatypes from header.
        fc:=0;
        if sfLoadDataTypeHeader in sfDataTypeHeader then
        begin
             Reader.ReadListBegin;
             fc:=Reader.ReadInteger;
             SetLength(ftypes,fc);
             for i:=0 to fc-1 do
                 ftypes[i]:=TFieldType(Reader.ReadInteger);
             Reader.ReadListEnd;
        end;

        // Read all records.
        ADataSet.LoadCount:=0;
        ADataSet.LoadedCompletely:=true;

        if ApproxRecs>0 then ADataSet.Common.Records.Capacity:=ApproxRecs; // For speed reason try to preallocate room for all records.

        Reader.ReadListBegin;
        while not(Reader.EndofList) do
        begin
             // Show progress.
             inc(ProgressCnt);
             ProgressCnt:=ProgressCnt mod 100;
             if (ProgressCnt=0) then
                ADataSet.Progress(trunc((WorkStream.Position / StreamSize) * 100),mtpcLoad);

             if (ADataSet.LoadLimit>0) and (ADataSet.LoadCount>=ADataSet.LoadLimit) then
             begin
                  ADataSet.LoadedCompletely:=false;
                  break;
             end;

             pRec:=ADataSet.Common._InternalAllocRecord;
             ADataSet.OverrideActiveRecordBuffer:=pRec;

             NewestVersion:=true;
{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
 {$IFNDEF BINARY_FILE_200_COMPATIBILITY}                         // New for v. 2.24.

             // Loop for all versions of record if versioning is used (2.30 and forth).
             if FileVersion>=230 then Reader.ReadListBegin;
             while true do
             begin
  {$IFDEF DOTNET}
                  ARec := TKbmRecord (Marshal.PtrToStructure(ADataSet.OverrideActiveRecordBuffer,TypeOf(TKbmRecord)));
                  if FileVersion>=230 then ARec.UpdateStatus:=TUpdateStatus(Reader.ReadInteger);
                  Marshal.StructureToPtr(ARec,ADataSet.OverrideActiveRecordBuffer,False);
  {$ELSE}
                  if FileVersion>=230 then ADataSet.OverrideActiveRecordBuffer^.UpdateStatus:=TUpdateStatus(Reader.ReadInteger);
  {$ENDIF}
 {$ENDIF}
{$ENDIF}

                  // Read fields for current record version.
                  fno:=0;
                  for i:=0 to nf-1 do
                  begin
                       if LoadFields[i]<0 then
                       begin
                            // Check if to skip.
                            if fc>0 then SkipField(ftypes[fno]);
                            continue;
                       end;
                       j:=LoadFields[i];

                       //2.50i                          if Fields[i].FieldKind<>fkData then continue;

{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
 {$IFNDEF BINARY_FILE_200_COMPATIBILITY}
  {$IFNDEF BINARY_FILE_230_COMPATIBILITY}                     // New for v. 2.49.
                       // Check if null values saved in binary file.
                       if (FileVersion>=249) then
                          bNull:=Reader.ReadBoolean
                       else
  {$ENDIF}
 {$ENDIF}
{$ENDIF}
                          bNull:=false;

                       // Check if null field.
                       if bNull then
                          ADataSet.Fields[j].Clear
                       else
                       begin
                            // Not null, load data.
                            case ADataSet.Fields[j].DataType of
                                 ftBoolean : ADataSet.Fields[j].AsBoolean := Reader.ReadBoolean;

{$IFNDEF LEVEL3}
                                 ftLargeInt: ADataSet.Fields[j].AsFloat:=Reader.ReadFloat;
 {$IFDEF DOTNET}
                                 ftWideString: ADataSet.Fields[j].AsString:=Reader.ReadString;
 {$ELSE}
                                 ftWideString: ADataSet.Fields[j].Value:={$IFDEF LEVEL6}UTF8Decode(Reader.ReadString){$ELSE}Reader.ReadString{$ENDIF};
 {$ENDIF}
{$ENDIF}

                                 ftSmallInt,
                                 ftInteger,
                                 ftWord : ADataSet.Fields[j].AsInteger := Reader.ReadInteger;

                                 ftAutoInc :begin
                                                 ADataSet.Fields[j].AsInteger:=Reader.ReadInteger;
                                                 if ADataSet.Common.AutoIncMax<ADataSet.Fields[j].AsInteger then
                                                    ADataSet.Common.AutoIncMax:=ADataSet.Fields[j].AsInteger;
                                            end;

                                 ftFloat : ADataSet.Fields[j].AsFloat := Reader.ReadFloat;

                                 ftBCD,
                                 ftCurrency : ADataSet.Fields[j].AsCurrency := Reader.ReadFloat;

                                 ftDate,
                                 ftTime,
                                 ftDateTime : begin
                                                   Date:=Reader.ReadFloat;
                                                   if Date=0 then ADataSet.Fields[j].Clear
                                                   else ADataSet.Fields[j].AsFloat:=Date;
                                              end;
                            else
                                ADataSet.Fields[j].AsString := Reader.ReadString;
                            end;
                       end;

                       if NewestVersion and Assigned(ADataSet.OnLoad) then ADataSet.OnLoadField(ADataset,i,ADataSet.Fields[i]);
{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
 {$IFNDEF BINARY_FILE_200_COMPATIBILITY}                         // New for v. 2.24.
                  end;

                  // Previous file versions didnt contain versions, so just break loop.
                  if FileVersion<230 then break;

                  // Prepare for reading next version if any. (introduced in v. 2.30)
                  if Reader.EndOfList then break;

                  // Prepare next version.
                  NewestVersion:=false;
  {$IFDEF DOTNET}
                  ARec := TKbmRecord (Marshal.PtrToStructure(ADataSet.OverrideActiveRecordBuffer,TypeOf(TKbmRecord) ));
                  ARec.PrevRecordVersion:=ADataSet.Common._InternalAllocRecord;
                  Marshal.StructureToPtr(ARec,ADataSet.OverrideActiveRecordBuffer,False);
                  ADataSet.OverrideActiveRecordBuffer:=ARec.PrevRecordVersion;
  {$ELSE}
                  ADataSet.OverrideActiveRecordBuffer^.PrevRecordVersion:=ADataSet.Common._InternalAllocRecord;
                  ADataSet.OverrideActiveRecordBuffer:=ADataSet.OverrideActiveRecordBuffer^.PrevRecordVersion;
  {$ENDIF}

             end;
             if FileVersion>=230 then Reader.ReadListEnd;
 {$ENDIF}
{$ENDIF}

             Accept:=true;
             if Assigned(ADataSet.OnLoadRecord) then ADataSet.OnLoadRecord(ADataset,Accept);
             if Accept then
             begin
{$IFDEF DOTNET}
                  Rec:=TKbmRecord(Marshal.PtrToStructure(pRec,TypeOf(TKbmRecord)));
                  Rec.RecordID:=ADataSet.Common.RecordID;
                  ADataSet.Common.RecordID:=ADataSet.Common.RecordID+1;
                  Rec.UniqueRecordID:=ADataSet.Common.UniqueRecordID;
                  ADataSet.Common.UniqueRecordID:=ADataSet.Common.UniqueRecordID+1;
                  Rec.Flag:=kbmrfInTable;
                  if Rec.UpdateStatus=usDeleted then
                     ADataSet.Common.deletedCount:=ADataSet.Common.DeletedCount+1;
                  Marshal.StructureToPtr(Rec,pRec,False);
                  ADataSet.Common.Records.Add(pRec);
{$ELSE}
                  pRec^.RecordID:=ADataset.Common.RecordID;
                  ADataSet.Common.RecordID:=ADataSet.Common.RecordID+1;
                  pRec^.UniqueRecordID:=ADataSet.Common.UniqueRecordID;
                  ADataSet.Common.UniqueRecordID:=ADataSet.Common.UniqueRecordID+1;
                  pRec^.Flag:=kbmrfInTable;
                  ADataSet.Common.Records.Add(pRec);
                  if pRec^.UpdateStatus=usDeleted then
                     ADataSet.Common.deletedCount:=ADataSet.Common.DeletedCount+1;
{$ENDIF}
                  ADataSet.LoadCount:=ADataSet.LoadCount+1;
             end
             else
                 ADataSet.Common._InternalFreeRecord(pRec,true,true);
        end;
        Reader.ReadListEnd;
     finally
        ADataSet.__RestoreState(dsBrowse);
     end;
end;

// -----------------------------------------------------------------------------------
// Registration for Delphi 3 / C++ Builder 3
// -----------------------------------------------------------------------------------

{$ifdef LEVEL3}
procedure Register;
begin
     RegisterComponents('kbmMemTable', [TkbmBinaryStreamFormat]);
end;
{$endif}

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -