unit DalUtl;{utility methods for dallas chips (touch rams)}
interface
uses
  SysUtils,
  BinHex, Compareu, Msgu, UtlType,
  DalType, DalTxt;

procedure TouchIDInc(var ATouchID: TTouchID);

function IsMemTouchID(var ATouchID: TTouchID): boolean;

function GetTouchIDStr(const ATouchID: TTouchID): TTouchIDStr;

procedure SetTouchIDStr(ATouchIDStr: TTouchIDStr; var ATouchID: TTouchID);
  { expects ATouchIDStr returned by FixTouchIDStr function (i.e. checked for
    validity) }

{function ReadCHTable(fn: string; var ATable: TCHTable):integer;

function WriteCHTable(fn: string; var ATable:TCHTable):integer;

function GetDifTouchTableSize(var T1:TCHTable; var T2:TCHTable):integer;}
{ Returns the number of bytes that are different in touchtable part
  of the TCHTables (i.e. the number of bytes from the start of the table,
  that MUST be sent }

function IsValidTouchIDStr(const ATouchIDStr: string;
  ReportError: boolean): boolean;

function FixTouchIDStr(const ASrcTouchIDStr: string; var ADestTouchIDStr: TTouchIDStr; ReportError: boolean): boolean;
  { get normalized string representation of TouchID from user entered string; returns false
    if contains non allowed chars }

function TouchIDCmp(const ATouchID1: TTouchID; const ATouchID2: TTouchID): integer;

function IsEmptyTouchID(const ATouchID:TTouchID):boolean;
procedure TouchIDSwap(var t1: TTouchID; var t2: TTouchID);
const
  EmptyTouchID: TTouchID = (0,0,0,0,0,0,0);
implementation

function IsMemTouchID(var ATouchID:TTouchID):boolean;
begin
  IsMemTouchid := ATouchID[0] = $c;
end;

function GetTouchIDStr(const ATouchID: TTouchID): TTouchIDStr;
var
  i: byte;
  s: TTouchIDStr;
begin
  s := '';
  for i := 0 to pred(TouchIDLen) do begin
     s := s + bytetohex(ATouchID[TouchIDLen - i - 1]);
  end;
  GetTouchIDStr := s;
end;

procedure SetTouchIDStr(ATouchIDStr:TTouchIDStr; var ATouchID:TTouchID);
var i:integer;
begin
  FillChar(ATouchID, sizeof(ATouchID), 0);
  if length(ATouchIDStr) <> TouchIDStrLen then begin
    if length(ATouchIDStr) > TouchIDStrLen then begin
      ATouchIDStr := copy(ATouchIDStr,
       length(ATouchIDStr) - TouchIDStrLen + 1, TouchIDStrLen);
    end else begin
      while length(ATouchIDStr) < TouchIDStrLen do
        ATouchIDStr := '0' + ATouchIDStr;
    end;
  end;
  for i := 0 to (length(ATouchIDStr) div 2) - 1 do begin
    ATouchID[TouchIDLen - 1 - i] := HexToByte(copy(ATouchIDStr, i * 2 + 1, 2));
  end;
end;

{
function ReadCHTable(fn:string; var ATable:TCHTable):integer;
var
  f: file of TCHTable;
  res: integer;
label er;
begin
  assign(f, fn);
  reset(f);
  res := ioresult;
  if res <> 0 then
    goto er;
  read(f, ATable);
  res := ioresult;
  close(f);
  if ioresult <> 0 then begin
    ShowMessage('Chyba při uzavírání souboru ' + fn, smError,0);
  end;
er:
  ReadChTable := res;
end;

function WriteCHTable(fn:string; var ATable:TCHTable):integer;
var
  f:file of TCHTable;
  res:integer;
label ex;
begin
  assign(f, fn);
  rewrite(f);
  res := ioresult;
  if res <> 0 then
    goto ex;
  write(f, ATable);
  res := ioresult;
  close(f);
  if ioresult <> 0 then begin
    ShowMessage('Chyba při uzavírání souboru ' + fn, smError,0);
  end;
ex:
  if res <> 0 then
    ShowMessage(IntToStr(res) + ': Chyba při zápisu do souboru ' + fn, smError, 0);
  WriteChTable := res;
end;

function GetDifTouchTableSize(var T1:TCHTable; var T2:TCHTable):integer;
var res:integer;
begin
  res := CHTouchTableSize - 3;
  while res >= 0 do begin
    if CompareRec(T1.TouchTable[res], T2.TouchTable[res],sizeof(T2.TouchTable[res])) <> 0 then
      break;
    dec(res);
  end;
  if res >= 0 then
    GetDifTouchTableSize := res * sizeof(T2.TouchTable[res])
  else
    GetDifTouchTableSize := 0;
end;
}

function IsValidTouchIDStr(const ATouchIDStr:string;
  ReportError:boolean):boolean;
var
  i:integer;
  lzeros:integer;
label er;
begin
  IsValidTouchIDStr := false;
  if ATouchIDStr = '' then
    goto er;
  lzeros := 0;
  for i := 1 to length(ATouchIDStr) do begin
    if not IsHexChar(ATouchIDStr[i]) then
      goto er;
    if ATouchIDStr[i] = '0' then
      inc(lzeros);
  end;
  if (length(ATouchIDStr) - lzeros) > TouchIDStrLen then
    goto er;
  IsValidTouchIDStr := true;
  exit;
er:
  if ReportError then
    ShowMessage(SNonsenseTouchID + ' ' + ATouchIDStr, smError, 0);
end;

function IsEmptyTouchID(const ATouchID: TTouchID): boolean;
var i: byte;
begin
  IsEmptyTouchID := false;
  for i := 0 to (sizeof(ATouchID) - 1) do begin
    if ATouchID[i] <> 0 then
      exit;
  end;
  IsEmptyTouchID := true;
end;

function TouchIDCmp(const ATouchID1: TTouchID; const ATouchID2: TTouchID): integer;
begin
  Result := CompareRec(ATouchID1, ATouchID2, sizeof(TTouchID));;
end;

procedure TouchIDInc(var ATouchID: TTouchID);
var
  i: integer;
{  b: byte;}
begin
  i := 1;{byte at 0 is type of touchid, not incrementing}
  repeat
    inc(ATouchID[i]);
    if ATouchID[i] <> 0 then
      break;
    inc(i);
  until i >= TouchIDLen;
end;

function FixTouchIDStr(const ASrcTouchIDStr: string; var ADestTouchIDStr: TTouchIDStr; ReportError: boolean): boolean;
var
  t: TTouchID;
  s: string;
begin
  Result := false;
  s := trim(ASrcTouchIDStr);
  if not IsValidTouchIDStr(s, ReportError) then
    exit;
  SetTouchIDStr(s, t);
  ADestTouchIDStr := GetTouchIDStr(t);
  Result := true;
end;

procedure TouchIDSwap(var t1: TTouchID; var t2: TTouchID);
var t: TTouchID;
begin
  t := t1;
  t1 := t2;
  t2 := t;
end;

end.