//02.03.2022 663-CSdemoR Демо работы с CS_DLL.DLL - чтение.
//Параметр: имяФайлаЦХ
//Требуется доступ к CS_DLL.DLL
//
//05.03.2022 663-CSdemoR2 Демо работы с CS_DLL.DLL - чтение 2: .Read2()
//  Частичное чтение из буфера
//21.03.2022 663-CSdemoR2
//1) Добавил второе ЦХ для картинок.
//

unit UnitCSdemoR2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, TeeProcs, TeEngine, Chart, Series, StdCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Chart1: TChart;
    Panel1: TPanel;
    ComboBox1: TComboBox;
    Label1: TLabel;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Jpeg;

{$R *.dfm}

type
  ICyclickStorage=interface(IInterface)
    function ConnectToCS(sFile:PChar;sMutex:PChar;TimeOut:integer;bWrite:Boolean):integer;stdcall;
    function DisconnectCS:integer;stdcall;
    function GetCSHead:pointer;stdcall;
    function GetHeadTail(var iHead:integer;var iTail:integer):integer;stdcall;
    function NormalizeIndex(i:integer):integer;stdcall;
    function BeginWrite:integer;stdcall;
    function EndWrite(t:TDateTime;nLen:integer):integer;stdcall;
    function Write(var buf;nBufSize:integer):integer;stdcall;
    function WriteFile(t:TDateTime;sFile:PChar):integer;stdcall;
    function Read(i:integer;var buf):integer;stdcall;
    function Read2(i:integer;var buf;ofs,len:integer):integer;stdcall;
    function GetRHead(i:integer;var t:TDateTime;var n:integer):Boolean;stdcall;
    function GetT(i:integer):TDateTime;stdcall;
    function Dicho(t:TDateTime;iHead,iTail,iMode:integer):integer;stdcall;
  end;  //ICyclickStorage

  TCS_Head=packed record      //"Head" of Cyclic storage (CS)
    quantSize:Cardinal;       //size of quant (max record)
    recordsNum:Cardinal;      //Total records in CS
    head:Cardinal;            //index of the newest record
    tail:Cardinal;            //index of the latest record
    comment:array[1..36] of AnsiChar;  //comments
  end;  //TCS_Head

function CreateCSobj:ICyclickStorage;stdcall; external 'CySt_DLL.dll';

var
  cs:ICyclickStorage;
  iCsHead:integer;
  cs2:ICyclickStorage;
  iCsHead2:integer;
  i:integer;
  t:array[0..999]of double;
  Y:array[0..999]of double;
  Coll: array[0..9] of TColor;
  buf:array of byte;

procedure TForm1.FormCreate(Sender: TObject);
begin
  if not (FileExists(ParamStr(1)) and FileExists(ParamStr(2))) then
    begin
    Application.Terminate;
    exit;
    end;
  cs:=CreateCSobj;
  cs.ConnectToCS(PChar(ParamStr(1)),'CSdemoMutex',10000,false);
  cs.GetHeadTail(iCsHead,i);
  cs2:=CreateCSobj;
  cs2.ConnectToCS(PChar(ParamStr(2)),'CSdemoMutex2',10000,false);
  cs2.GetHeadTail(iCsHead2,i);
  SetLength(buf,TCS_Head(cs2.GetCSHead^).quantSize);

  chart1.BottomAxis.DateTimeFormat:='hh:mm:ss';

  Coll[0]:=$A26480;
  Coll[1]:=clGreen;
  Coll[2]:=clBlue;
  Coll[3]:=clPurple;
  Coll[4]:=clFuchsia;
  Coll[5]:=clNavy;
  Coll[6]:=clGray;
  Coll[7]:=clMaroon;
  Coll[8]:=clOlive;
  Coll[9]:=clTeal;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var ai:array of integer; i,j,m,n,h:integer; iCh,ofs:integer;
  jp:TJpegImage; bmpSrc:TBitmap;
begin
  cs.GetHeadTail(i,j);
  if i <> iCsHead then
    begin
    while chart1.SeriesCount > 0 do
      chart1.Series[chart1.SeriesCount-1].Destroy;
    iCsHead:=i;
    cs.Read2(iCsHead,m,0,sizeof(integer));
    SetLength(ai,m);
    cs.Read2(iCsHead,ai[0],sizeof(integer),m*sizeof(integer));
    iCh:=ComboBox1.ItemIndex;
    ofs:=(1+m)*sizeof(integer);
    if iCh > 0 then
      for i:=0 to iCh-1 do
        ofs:=ofs+2*ai[i]*sizeof(double);
    n:=ai[iCh];
    cs.Read2(iCsHead,t[0],ofs,n*sizeof(double));
    cs.Read2(iCsHead,Y[0],ofs+n*sizeof(double),n*sizeof(double));
    Chart1.AddSeries(TFastLineSeries.Create(Self));
    TFastLineSeries(Chart1.Series[0]).LinePen.Width:=2;
    TFastLineSeries(Chart1.Series[0]).LinePen.Color:=Coll[0];
    Chart1.Series[0].XValues.DateTime:=true;
    for i:=0 to n-1 do
        Chart1.Series[0].AddXY(t[i],Y[i]);
    ai:=nil;
    end;  //cs
  cs2.GetHeadTail(i,j);
  if i <> iCsHead2 then
    begin
    iCsHead2:=i;
    n:=cs2.Read(iCsHead2,buf[0]);
    h:=FileCreate('tmp.jpg');
    FileWrite(h,buf[0],n);
    FileClose(h);
    jp:=TJpegImage.Create;
    jp.LoadFromFile('tmp.jpg');
    Image1.Picture.Bitmap.Assign(jp);
    jp.Free;
    DeleteFile('tmp.jpg');
    end;  //cs2
end;

end.
