unit main_stream; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls, Spin, Blowfish, demo_stream; const savedFileName: TFileName = 'stream.dat'; type { TForm1 } TForm1 = class(TForm) btnDecrypt: TButton; btnEncrypt: TButton; btnGenerateStream: TButton; btnLoadStream: TButton; btnSaveStream: TButton; edtRecord: TEdit; lblAdjustPosition: TLabel; lblNumRecords: TLabel; lblPositionDesc: TLabel; lblOrigin: TLabel; lblRecordNo: TLabel; lblSavedFileSize: TLabel; lblStreamSize: TLabel; memoDecrypted: TMemo; memoDisplay: TMemo; memoEncrypted: TMemo; seCurrentRecNo: TSpinEdit; seNoOfRecords: TSpinEdit; tbPosition: TTrackBar; udMover: TUpDown; procedure btnDecryptClick(Sender: TObject); procedure btnEncryptClick(Sender: TObject); procedure btnGenerateStreamClick(Sender: TObject); procedure btnLoadStreamClick(Sender: TObject); procedure btnSaveStreamClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure seCurrentRecNoChange(Sender: TObject); procedure udMoverClick(Sender: TObject; Button: TUDBtnType); private ds: TdemoStream; sOriginal, sEncrypted: TStringStream; key: string; public procedure DisplayStream; end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.udMoverClick(Sender: TObject; Button: TUDBtnType); begin if not Assigned(ds) then Exit; case Button of btPrev: if (ds.Position >= SizeOf(ds.rec)) then begin ds.Seek(- 2*SizeOf(ds.rec), sofromCurrent); if (ds.Position < 0) then ds.Position := 0; edtRecord.Text := ds.RecAsString; seCurrentRecNo.Value := seCurrentRecNo.Value-1; end; btNext: if (ds.Position < ds.Size) then begin edtRecord.Text := ds.RecAsString; seCurrentRecNo.Value := seCurrentRecNo.Value+1; end; end; seCurrentRecNoChange(nil); end; procedure TForm1.btnEncryptClick(Sender: TObject); var be: TBlowFishEncryptStream; begin if memoDisplay.Lines.Count = 0 then Exit; key := 'example cipher key for Blowfish'; sOriginal := TStringStream.Create(EmptyStr); be := TBlowFishEncryptStream.Create(key, sOriginal); be.WriteAnsiString(memoDisplay.Text); be.Free; memoEncrypted.Text := sOriginal.DataString; end; procedure TForm1.btnGenerateStreamClick(Sender: TObject); begin ds.Free; ds := TdemoStream.Create(seNoOfRecords.Value); seCurrentRecNo.MaxValue := seNoOfRecords.Value -1; DisplayStream; seCurrentRecNoChange(nil); btnSaveStream.Enabled := True; lblSavedfileSize.Caption := EmptyStr; memoEncrypted.Lines.Clear; memoDecrypted.Lines.Clear; end; procedure TForm1.btnLoadStreamClick(Sender: TObject); begin FreeAndNil(ds); ds := TdemoStream.Create(0); ds.LoadFromFile(savedFileName); seNoOfRecords.Value := ds.Size div SizeOf(ds.rec); seCurrentRecNo.MaxValue := seNoOfRecords.Value -1; DisplayStream; btnLoadStream.Enabled := False; seCurrentRecNoChange(nil); memoEncrypted.Lines.Clear; memoDecrypted.Lines.Clear; end; procedure TForm1.btnSaveStreamClick(Sender: TObject); begin if Assigned(ds) then begin memoDisplay.Lines.Clear; edtRecord.Text := EmptyStr; ds.SaveToFile(savedFileName); // lblSavedFileSize.Caption := Format('Saved file size is: %d bytes', [FileSize(savedFileName)]); btnLoadStream.Enabled := True; btnSaveStream.Enabled := False; FreeAndNil(ds); end; end; procedure TForm1.FormDestroy(Sender: TObject); begin ds.Free; end; procedure TForm1.seCurrentRecNoChange(Sender: TObject); var L: integer; begin if not Assigned(ds) then Exit; ds.Seek(seCurrentRecNo.Value * SizeOf(ds.rec), soFromBeginning); edtRecord.Text := ds.RecAsString; L := Length(edtRecord.Text) + Length(LineEnding); tbPosition.Position := tbPosition.Max * ds.Position div ds.Size; memoDisplay.SelStart := (tbPosition.Position) * L; memoDisplay.SelLength := L; end; procedure TForm1.btnDecryptClick(Sender: TObject); var bd: TBlowFishDeCryptStream; begin sEncrypted := TStringStream.Create(sOriginal.DataString); bd := TBlowFishDeCryptStream.Create(key, sEncrypted); memoDecrypted.Text := bd.ReadAnsiString; bd.Free; sEncrypted.Free; sOriginal.Free; end; procedure TForm1.DisplayStream; begin lblStreamSize.Caption := Format('%d ', [ds.Size]); tbPosition.Max := ds.Size div SizeOf(ds.rec) -1; memoDisplay.Lines.BeginUpdate; memoDisplay.Clear; ds.Position := 0; while (ds.Position < ds.Size) do begin memoDisplay.Lines.Add(ds.RecAsString); tbPosition.Position := (ds.Size * tbPosition.Max) div ds.Position; end; memoDisplay.Lines.EndUpdate; seCurrentRecNo.MaxValue := seNoOfRecords.Value; ds.Seek(seCurrentRecNo.Value * SizeOf(ds.rec), soFromBeginning); edtRecord.Text := ds.RecAsString; tbPosition.Position := (ds.Size * tbPosition.Max) div ds.Position; end; end.