Subversion Repositories oidplus

Rev

Rev 748 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit OIDFILE;
  2.  
  3. (************************************************)
  4. (* OIDFILE.PAS                                  *)
  5. (* Author:   Daniel Marschall                   *)
  6. (* Revision: 2022-10-10                         *)
  7. (* License:  Apache 2.0                         *)
  8. (* This file contains:                          *)
  9. (* - Functions to handle an OID ASCII format    *)
  10. (************************************************)
  11.  
  12. interface
  13.  
  14. uses
  15.   StrList;
  16.  
  17. type
  18.   POID = ^TOID;
  19.   TOID = record
  20.     FileId: string;
  21.     DotNotation: string;
  22.     ASNIds: PStringList;
  23.     UnicodeLabels: PStringList;
  24.     Description: string;
  25.     SubIds: PStringList; (* first 8 chars are FileId, followed by DotNotation *)
  26.     ParentFileId: string;
  27.     ParentDotNotation: string;
  28.   end;
  29.  
  30. procedure CreateOidDef(var oid: POid);
  31. procedure FreeOidDef(oid: POid);
  32. procedure ClearOidDef(oid: POid);
  33. function WriteOidFile(filename: string; oid: POid): boolean;
  34. function ReadOidFile(filename: string; oid: POid): boolean;
  35.  
  36. (* For the strings in the list "SubIds": *)
  37. function FileIdPart(s: string): string;
  38. function DotNotationPart(s: string): string;
  39.  
  40. implementation
  41.  
  42. uses
  43.   VtsFuncs, OidUtils, Crt;
  44.  
  45. const
  46.   WANT_VERS = '2022';
  47.  
  48. procedure CreateOidDef(var oid: POid);
  49. begin
  50.   oid := nil;
  51.   GetMem(oid, SizeOf(TOID));
  52.  
  53.   if oid <> nil then
  54.   begin
  55.     oid^.FileId := '';
  56.     oid^.DotNotation := '';
  57.     oid^.Description := '';
  58.     oid^.ParentFileId := '';
  59.     oid^.ParentDotNotation := '';
  60.     CreateList(oid^.ASNIds);
  61.     CreateList(oid^.UnicodeLabels);
  62.     CreateList(oid^.SubIds);
  63.   end
  64.   else
  65.   begin
  66.     Beep;
  67.     WriteLn('CreateOidDef failed! (GetMem returned nil)');
  68.     ReadKey;
  69.   end;
  70. end;
  71.  
  72. procedure FreeOidDef(oid: POid);
  73. begin
  74.   if oid <> nil then
  75.   begin
  76.     FreeList(oid^.ASNIds);
  77.     FreeList(oid^.UnicodeLabels);
  78.     FreeList(oid^.SubIds);
  79.     FreeMem(oid, SizeOf(TOID));
  80.     oid := nil;
  81.   end
  82.   else
  83.   begin
  84.     Beep;
  85.     WriteLn('FreeOidDef failed! (Argument is nil)');
  86.     ReadKey;
  87.   end;
  88. end;
  89.  
  90. procedure ClearOidDef(oid: POid);
  91. begin
  92.   oid^.FileId := '';
  93.   oid^.DotNotation := '';
  94.   oid^.Description := '';
  95.   oid^.ParentFileId := '';
  96.   oid^.ParentDotNotation := '';
  97.   ListClear(oid^.ASNIds);
  98.   ListClear(oid^.UnicodeLabels);
  99.   ListClear(oid^.SubIds);
  100. end;
  101.  
  102. procedure ListBubbleSortSubIds(oid: POid);
  103. var
  104.   n, i: integer;
  105.   a, b: string;
  106.   swapped: boolean;
  107. begin
  108.   n := ListCount(oid^.SubIds);
  109.   while n>1 do
  110.   begin
  111.     i := 0;
  112.     swapped := false;
  113.     while i<n-1 do
  114.     begin
  115.       a := DotNotationPart(ListGetElement(oid^.SubIds, i));
  116.       b := DotNotationPart(ListGetElement(oid^.SubIds, i+1));
  117.       if CompareOID(a, b) > 0 then
  118.       begin
  119.         ListSwapElement(oid^.SubIds, i, i+1);
  120.         swapped := true;
  121.       end;
  122.       Inc(i);
  123.     end;
  124.     if not swapped then break;
  125.     Dec(n);
  126.   end;
  127. end;
  128.  
  129. function WriteOidFile(filename: string; oid: POid): boolean;
  130. var
  131.   f: Text;
  132.   i: integer;
  133.   lines: PStringList;
  134.   sTmp: string;
  135.   desc: string;
  136. begin
  137.   Assign(f, filename);
  138.  
  139.   {$I-}
  140.   Rewrite(f);
  141.   {$I+}
  142.   if IoResult <> 0 then
  143.   begin
  144.     WriteOidFile := false;
  145.     (* Must not call Close(f) if file was never opened *)
  146.     Exit;
  147.   end;
  148.  
  149.   WriteLn(f, 'VERS' + WANT_VERS);
  150.  
  151.   WriteLn(f, 'SELF' + oid^.FileId + oid^.DotNotation);
  152.  
  153.   WriteLn(f, 'SUPR' + oid^.ParentFileId + oid^.ParentDotNotation);
  154.  
  155.   (* Sort sub IDs *)
  156.   ListBubbleSortSubIds(oid);
  157.  
  158.   for i := 0 to ListCount(oid^.SubIds)-1 do
  159.   begin
  160.     sTmp := ListGetElement(oid^.SubIds, i);
  161.     WriteLn(f, 'CHLD' + sTmp);
  162.   end;
  163.  
  164.   for i := 0 to ListCount(oid^.AsnIds)-1 do
  165.   begin
  166.     sTmp := ListGetElement(oid^.AsnIds, i);
  167.     WriteLn(f, 'ASN1' + sTmp);
  168.   end;
  169.  
  170.   for i := 0 to ListCount(oid^.UnicodeLabels)-1 do
  171.   begin
  172.     sTmp := ListGetElement(oid^.UnicodeLabels, i);
  173.     WriteLn(f, 'UNIL' + sTmp);
  174.   end;
  175.  
  176.   desc := Trim(oid^.Description);
  177.   if desc <> '' then
  178.   begin
  179.     CreateList(lines);
  180.     SplitStrToList(desc, lines, #13#10);
  181.     for i := 0 to ListCount(lines)-1 do
  182.     begin
  183.       sTmp := ListGetElement(lines, i);
  184.       WriteLn(f, 'DESC' + sTmp);
  185.     end;
  186.     FreeList(lines);
  187.   end;
  188.  
  189.   Close(f);
  190.  
  191.   WriteOidFile := true;
  192. end;
  193.  
  194. function ReadOidFile(filename: string; oid: POid): boolean;
  195. var
  196.   f: Text;
  197.   line, cmd: string;
  198.   version: string;
  199. begin
  200.   ClearOidDef(oid);
  201.   version := '';
  202.  
  203.   Assign(f, filename);
  204.   {$I-}
  205.   Reset(f);
  206.   {$I+}
  207.   if IoResult <> 0 then
  208.   begin
  209.     ReadOidFile := false;
  210.     (* Must not call Close(f) if file was never opened *)
  211.     Exit;
  212.   end;
  213.  
  214.   while not EOF(f) do
  215.   begin
  216.     ReadLn(f, line);
  217.     cmd := Copy(line,1,4);
  218.     Delete(line,1,4);
  219.  
  220.     if cmd = 'VERS' then
  221.     begin
  222.       version := line;
  223.     end;
  224.  
  225.     if cmd = 'SELF' then
  226.     begin
  227.       oid^.FileId := Copy(line,1,8);
  228.       Delete(line,1,8);
  229.       oid^.DotNotation := line;
  230.     end;
  231.  
  232.     if cmd = 'SUPR' then
  233.     begin
  234.       oid^.ParentFileId := FileIdPart(line);
  235.       oid^.ParentDotNotation := DotNotationPart(line);
  236.     end;
  237.  
  238.     if cmd = 'CHLD' then
  239.     begin
  240.       ListAppend(oid^.SubIds, line);
  241.     end;
  242.  
  243.     if cmd = 'ASN1' then
  244.     begin
  245.       ListAppend(oid^.ASNIds, line);
  246.     end;
  247.  
  248.     if cmd = 'UNIL' then
  249.     begin
  250.       ListAppend(oid^.UnicodeLabels, line);
  251.     end;
  252.  
  253.     if cmd = 'DESC' then
  254.     begin
  255.       if Length(oid^.Description) + Length(line) + 2 <= 255 then
  256.       begin
  257.         oid^.Description := oid^.Description + line + #13#10;
  258.       end;
  259.     end;
  260.   end;
  261.  
  262.   (* Sort sub IDs *)
  263.   ListBubbleSortSubIds(oid);
  264.  
  265.   (* Remove last CRLF *)
  266.   oid^.Description := Copy(oid^.Description, 1, Length(oid^.Description)-Length(#13#10));
  267.  
  268.   (* Check if everything is correct *)
  269.   ReadOidFile := (version = WANT_VERS) and (oid^.FileId <> '');
  270.  
  271.   Close(f);
  272. end;
  273.  
  274. function FileIdPart(s: string): string;
  275. begin
  276.   FileIdPart := Copy(s,1,8);
  277. end;
  278.  
  279. function DotNotationPart(s: string): string;
  280. begin
  281.   Delete(s,1,8);
  282.   DotNotationPart := s;
  283. end;
  284.  
  285. end.
  286.