Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
733 daniel-mar 1
unit OIDFILE;
2
 
3
(************************************************)
4
(* OIDFILE.PAS                                  *)
5
(* Author:   Daniel Marschall                   *)
992 daniel-mar 6
(* Revision: 2022-10-10                         *)
733 daniel-mar 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;
748 daniel-mar 23
    UnicodeLabels: PStringList;
733 daniel-mar 24
    Description: string;
745 daniel-mar 25
    SubIds: PStringList; (* first 8 chars are FileId, followed by DotNotation *)
26
    ParentFileId: string;
27
    ParentDotNotation: string;
733 daniel-mar 28
  end;
29
 
735 daniel-mar 30
procedure CreateOidDef(var oid: POid);
733 daniel-mar 31
procedure FreeOidDef(oid: POid);
734 daniel-mar 32
procedure ClearOidDef(oid: POid);
743 daniel-mar 33
function WriteOidFile(filename: string; oid: POid): boolean;
34
function ReadOidFile(filename: string; oid: POid): boolean;
733 daniel-mar 35
 
745 daniel-mar 36
(* For the strings in the list "SubIds": *)
735 daniel-mar 37
function FileIdPart(s: string): string;
38
function DotNotationPart(s: string): string;
39
 
733 daniel-mar 40
implementation
41
 
42
uses
748 daniel-mar 43
  VtsFuncs, OidUtils, Crt;
733 daniel-mar 44
 
45
const
46
  WANT_VERS = '2022';
47
 
735 daniel-mar 48
procedure CreateOidDef(var oid: POid);
734 daniel-mar 49
begin
748 daniel-mar 50
  oid := nil;
735 daniel-mar 51
  GetMem(oid, SizeOf(TOID));
748 daniel-mar 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;
734 daniel-mar 70
end;
71
 
733 daniel-mar 72
procedure FreeOidDef(oid: POid);
73
begin
748 daniel-mar 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;
733 daniel-mar 88
end;
89
 
734 daniel-mar 90
procedure ClearOidDef(oid: POid);
91
begin
745 daniel-mar 92
  oid^.FileId := '';
93
  oid^.DotNotation := '';
94
  oid^.Description := '';
95
  oid^.ParentFileId := '';
96
  oid^.ParentDotNotation := '';
97
  ListClear(oid^.ASNIds);
748 daniel-mar 98
  ListClear(oid^.UnicodeLabels);
745 daniel-mar 99
  ListClear(oid^.SubIds);
734 daniel-mar 100
end;
101
 
740 daniel-mar 102
procedure ListBubbleSortSubIds(oid: POid);
739 daniel-mar 103
var
104
  n, i: integer;
105
  a, b: string;
740 daniel-mar 106
  swapped: boolean;
739 daniel-mar 107
begin
108
  n := ListCount(oid^.SubIds);
109
  while n>1 do
110
  begin
111
    i := 0;
740 daniel-mar 112
    swapped := false;
739 daniel-mar 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);
740 daniel-mar 120
        swapped := true;
739 daniel-mar 121
      end;
122
      Inc(i);
123
    end;
740 daniel-mar 124
    if not swapped then break;
739 daniel-mar 125
    Dec(n);
126
  end;
127
end;
128
 
743 daniel-mar 129
function WriteOidFile(filename: string; oid: POid): boolean;
733 daniel-mar 130
var
131
  f: Text;
132
  i: integer;
133
  lines: PStringList;
134
  sTmp: string;
135
  desc: string;
136
begin
137
  Assign(f, filename);
743 daniel-mar 138
 
139
  {$I-}
733 daniel-mar 140
  Rewrite(f);
743 daniel-mar 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;
733 daniel-mar 148
 
740 daniel-mar 149
  WriteLn(f, 'VERS' + WANT_VERS);
733 daniel-mar 150
 
740 daniel-mar 151
  WriteLn(f, 'SELF' + oid^.FileId + oid^.DotNotation);
733 daniel-mar 152
 
745 daniel-mar 153
  WriteLn(f, 'SUPR' + oid^.ParentFileId + oid^.ParentDotNotation);
733 daniel-mar 154
 
739 daniel-mar 155
  (* Sort sub IDs *)
740 daniel-mar 156
  ListBubbleSortSubIds(oid);
157
 
733 daniel-mar 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
 
748 daniel-mar 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
 
733 daniel-mar 176
  desc := Trim(oid^.Description);
177
  if desc <> '' then
178
  begin
735 daniel-mar 179
    CreateList(lines);
733 daniel-mar 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);
743 daniel-mar 190
 
191
  WriteOidFile := true;
733 daniel-mar 192
end;
193
 
743 daniel-mar 194
function ReadOidFile(filename: string; oid: POid): boolean;
733 daniel-mar 195
var
196
  f: Text;
197
  line, cmd: string;
198
  version: string;
199
begin
734 daniel-mar 200
  ClearOidDef(oid);
733 daniel-mar 201
  version := '';
202
 
203
  Assign(f, filename);
743 daniel-mar 204
  {$I-}
733 daniel-mar 205
  Reset(f);
743 daniel-mar 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
 
733 daniel-mar 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
745 daniel-mar 234
      oid^.ParentFileId := FileIdPart(line);
235
      oid^.ParentDotNotation := DotNotationPart(line);
733 daniel-mar 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
 
748 daniel-mar 248
    if cmd = 'UNIL' then
249
    begin
250
      ListAppend(oid^.UnicodeLabels, line);
251
    end;
252
 
733 daniel-mar 253
    if cmd = 'DESC' then
254
    begin
992 daniel-mar 255
      if Length(oid^.Description) + Length(line) + 2 <= 255 then
256
      begin
257
        oid^.Description := oid^.Description + line + #13#10;
258
      end;
733 daniel-mar 259
    end;
260
  end;
740 daniel-mar 261
 
739 daniel-mar 262
  (* Sort sub IDs *)
740 daniel-mar 263
  ListBubbleSortSubIds(oid);
733 daniel-mar 264
 
265
  (* Remove last CRLF *)
266
  oid^.Description := Copy(oid^.Description, 1, Length(oid^.Description)-Length(#13#10));
267
 
747 daniel-mar 268
  (* Check if everything is correct *)
744 daniel-mar 269
  ReadOidFile := (version = WANT_VERS) and (oid^.FileId <> '');
733 daniel-mar 270
 
271
  Close(f);
272
end;
273
 
735 daniel-mar 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
 
733 daniel-mar 285
end.