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. |