Subversion Repositories oidplus

Rev

Rev 740 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 740 Rev 748
1
unit OIDUTILS;
1
unit OIDUTILS;
2
 
2
 
3
(************************************************)
3
(************************************************)
4
(* OIDUTILS.PAS                                 *)
4
(* OIDUTILS.PAS                                 *)
5
(* Author:   Daniel Marschall                   *)
5
(* Author:   Daniel Marschall                   *)
6
(* Revision: 2022-02-14                         *)
6
(* Revision: 2022-02-19                         *)
7
(* License:  Apache 2.0                         *)
7
(* License:  Apache 2.0                         *)
8
(* This file contains:                          *)
8
(* This file contains:                          *)
9
(* - Various OID functions                      *)
9
(* - Various OID functions                      *)
10
(************************************************)
10
(************************************************)
11
 
11
 
12
interface
12
interface
13
 
13
 
14
uses
14
uses
15
  StrList;
15
  StrList;
16
 
16
 
17
function CompareOIDArcList(a, b: PStringList): integer;
17
function CompareOIDArcList(a, b: PStringList): integer;
18
function CompareOID(a, b: string): integer;
18
function CompareOID(a, b: string): integer;
19
procedure ListBubbleSortOID(list: PStringList);
19
procedure ListBubbleSortOID(list: PStringList);
20
function ASN1IDValid(asn1id: string): boolean;
20
function ASN1IDValid(asn1id: string): boolean;
-
 
21
function UnicodeLabelValid(unicodeLabel: string): boolean;
21
 
22
 
22
implementation
23
implementation
23
 
24
 
24
uses
25
uses
25
  VtsFuncs;
26
  VtsFuncs;
26
 
27
 
27
function CompareOIDArcList(a, b: PStringList): integer;
28
function CompareOIDArcList(a, b: PStringList): integer;
28
var
29
var
29
  x, y: PStringList;
30
  x, y: PStringList;
30
  tmp: integer;
31
  tmp: integer;
31
begin
32
begin
32
  x := a;
33
  x := a;
33
  y := b;
34
  y := b;
34
 
35
 
35
  repeat
36
  repeat
36
    if (x = nil) and (y <> nil) then
37
    if (x = nil) and (y <> nil) then
37
    begin
38
    begin
38
      CompareOIDArcList := -1;
39
      CompareOIDArcList := -1;
39
      exit;
40
      exit;
40
    end;
41
    end;
41
 
42
 
42
    if (x <> nil) and (y = nil) then
43
    if (x <> nil) and (y = nil) then
43
    begin
44
    begin
44
      CompareOIDArcList := 1;
45
      CompareOIDArcList := 1;
45
      exit;
46
      exit;
46
    end;
47
    end;
47
 
48
 
48
    if (x = nil) and (y = nil) then
49
    if (x = nil) and (y = nil) then
49
    begin
50
    begin
50
      CompareOIDArcList := 0;
51
      CompareOIDArcList := 0;
51
      exit;
52
      exit;
52
    end;
53
    end;
53
 
54
 
54
    tmp := CompareNumericString(x^.element, y^.element);
55
    tmp := CompareNumericString(x^.element, y^.element);
55
 
56
 
56
    if tmp <> 0 then
57
    if tmp <> 0 then
57
    begin
58
    begin
58
      CompareOIDArcList := tmp;
59
      CompareOIDArcList := tmp;
59
      exit;
60
      exit;
60
    end;
61
    end;
61
 
62
 
62
    x := x^.next;
63
    x := x^.next;
63
    y := y^.next;
64
    y := y^.next;
64
  until false;
65
  until false;
65
end;
66
end;
66
 
67
 
67
function CompareOID(a, b: string): integer;
68
function CompareOID(a, b: string): integer;
68
var
69
var
69
  la, lb: PStringList;
70
  la, lb: PStringList;
70
begin
71
begin
71
  CreateList(la);
72
  CreateList(la);
72
  CreateList(lb);
73
  CreateList(lb);
73
  OIDtoArcList(a, la);
74
  OIDtoArcList(a, la);
74
  OIDtoArcList(b, lb);
75
  OIDtoArcList(b, lb);
75
  CompareOID := CompareOIDArcList(la, lb);
76
  CompareOID := CompareOIDArcList(la, lb);
-
 
77
  FreeList(la);
-
 
78
  FreeList(lb);
76
end;
79
end;
77
 
80
 
78
procedure ListBubbleSortOID(list: PStringList);
81
procedure ListBubbleSortOID(list: PStringList);
79
var
82
var
80
  n, i: integer;
83
  n, i: integer;
81
  a, b: string;
84
  a, b: string;
82
  swapped: boolean;
85
  swapped: boolean;
83
begin
86
begin
84
  n := ListCount(list);
87
  n := ListCount(list);
85
  while n>1 do
88
  while n>1 do
86
  begin
89
  begin
87
    i := 0;
90
    i := 0;
88
    swapped := false;
91
    swapped := false;
89
    while i<n-1 do
92
    while i<n-1 do
90
    begin
93
    begin
91
      a := ListGetElement(list, i);
94
      a := ListGetElement(list, i);
92
      b := ListGetElement(list, i+1);
95
      b := ListGetElement(list, i+1);
93
      if CompareOID(a, b) > 0 then
96
      if CompareOID(a, b) > 0 then
94
      begin
97
      begin
95
        ListSwapElement(list, i, i+1);
98
        ListSwapElement(list, i, i+1);
96
        swapped := true;
99
        swapped := true;
97
      end;
100
      end;
98
      Inc(i);
101
      Inc(i);
99
    end;
102
    end;
100
    if not swapped then break;
103
    if not swapped then break;
101
    Dec(n);
104
    Dec(n);
102
  end;
105
  end;
103
end;
106
end;
104
 
107
 
105
function ASN1IDValid(asn1id: string): boolean;
108
function ASN1IDValid(asn1id: string): boolean;
106
var
109
var
107
  i: integer;
110
  i: integer;
108
  lastChar: char;
111
  lastChar: char;
109
begin
112
begin
110
  (* see Rec. ITU-T X.660 | ISO/IEC 9834-1, clause 7.7  *)
113
  (* see Rec. ITU-T X.660 | ISO/IEC 9834-1, clause 7.7  *)
111
  (* and Rec. ITU-T X.680 | ISO/IEC 8824-1, clause 12.3 *)
114
  (* and Rec. ITU-T X.680 | ISO/IEC 8824-1, clause 12.3 *)
112
 
115
 
113
  ASN1IDValid := false;
116
  ASN1IDValid := false;
114
 
117
 
115
  if Length(asn1id) = 0 then exit; (* may not be empty *)
118
  if Length(asn1id) = 0 then exit; (* may not be empty *)
116
  if not (asn1id[1] in ['a'..'z']) then exit; (* first char must be lowercase *)
119
  if not (asn1id[1] in ['a'..'z']) then exit; (* first char must be lowercase *)
117
 
120
 
118
  lastChar := #0;
121
  lastChar := #0;
119
  for i := 1 to Length(asn1id) do
122
  for i := 1 to Length(asn1id) do
120
  begin
123
  begin
121
    if (lastChar = '-') and (asn1id[i] = '-') then exit; (* may not contain '--' *)
124
    if (lastChar = '-') and (asn1id[i] = '-') then exit; (* may not contain '--' *)
122
    if not (asn1id[i] in ['a'..'z', 'A'..'Z', '0'..'9', '-']) then exit;
125
    if not (asn1id[i] in ['a'..'z', 'A'..'Z', '0'..'9', '-']) then exit;
123
    lastChar := asn1id[i];
126
    lastChar := asn1id[i];
124
  end;
127
  end;
125
  if lastChar = '-' then exit; (* may not end with '-' *)
128
  if lastChar = '-' then exit; (* may not end with '-' *)
126
  ASN1IDValid := true;
129
  ASN1IDValid := true;
127
end;
130
end;
-
 
131
 
-
 
132
function UnicodeLabelValid(unicodeLabel: string): boolean;
-
 
133
begin
-
 
134
  UnicodeLabelValid := true;
-
 
135
  (* TODO: Implement *)
-
 
136
 
-
 
137
(*
-
 
138
 
-
 
139
 
-
 
140
function iri_char_valid($c, $firstchar, $lastchar) {
-
 
141
        // see Rec. ITU-T X.660, clause 7.5
-
 
142
 
-
 
143
        if (($firstchar || $lastchar) && ($c == '-')) return false;
-
 
144
 
-
 
145
        if ($c == '-') return true;
-
 
146
        if ($c == '.') return true;
-
 
147
        if ($c == '_') return true;
-
 
148
        if ($c == '~') return true;
-
 
149
        if (($c >= '0') && ($c <= '9') && (!$firstchar)) return true;
-
 
150
        if (($c >= 'A') && ($c <= 'Z')) return true;
-
 
151
        if (($c >= 'a') && ($c <= 'z')) return true;
-
 
152
 
-
 
153
        $v = mb_ord($c);
-
 
154
 
-
 
155
        if (($v >= 0x000000A0) && ($v <= 0x0000DFFE)) return true;
-
 
156
        if (($v >= 0x0000F900) && ($v <= 0x0000FDCF)) return true;
-
 
157
        if (($v >= 0x0000FDF0) && ($v <= 0x0000FFEF)) return true;
-
 
158
        if (($v >= 0x00010000) && ($v <= 0x0001FFFD)) return true;
-
 
159
        if (($v >= 0x00020000) && ($v <= 0x0002FFFD)) return true;
-
 
160
        if (($v >= 0x00030000) && ($v <= 0x0003FFFD)) return true;
-
 
161
        if (($v >= 0x00040000) && ($v <= 0x0004FFFD)) return true;
-
 
162
        if (($v >= 0x00050000) && ($v <= 0x0005FFFD)) return true;
-
 
163
        if (($v >= 0x00060000) && ($v <= 0x0006FFFD)) return true;
-
 
164
        if (($v >= 0x00070000) && ($v <= 0x0007FFFD)) return true;
-
 
165
        if (($v >= 0x00080000) && ($v <= 0x0008FFFD)) return true;
-
 
166
        if (($v >= 0x00090000) && ($v <= 0x0009FFFD)) return true;
-
 
167
        if (($v >= 0x000A0000) && ($v <= 0x000AFFFD)) return true;
-
 
168
        if (($v >= 0x000B0000) && ($v <= 0x000BFFFD)) return true;
-
 
169
        if (($v >= 0x000C0000) && ($v <= 0x000CFFFD)) return true;
-
 
170
        if (($v >= 0x000D0000) && ($v <= 0x000DFFFD)) return true;
-
 
171
        if (($v >= 0x000E1000) && ($v <= 0x000EFFFD)) return true;
-
 
172
 
-
 
173
        // Note: Rec. ITU-T X.660, clause 7.5.3 would also forbid ranges which are marked
-
 
174
        // in ISO/IEC 10646 as "(This position shall not be used)"
-
 
175
        // But tool implementers should be tolerate them, since these limitations can be removed in future.
-
 
176
 
-
 
177
        return false;
-
 
178
}
-
 
179
 
-
 
180
function iri_arc_valid($arc, $allow_numeric=true) {
-
 
181
        if ($arc == '') return false;
-
 
182
 
-
 
183
        $m = array();
-
 
184
        if ($allow_numeric && preg_match('@^(\\d+)$@', $arc, $m)) return true; # numeric arc
-
 
185
 
-
 
186
        // Question: Should we strip RTL/LTR characters?
-
 
187
 
-
 
188
        if (mb_substr($arc, 2, 2) == '--') return false; // see Rec. ITU-T X.660, clause 7.5.4
-
 
189
 
-
 
190
        $array = array();
-
 
191
        preg_match_all('/./u', $arc, $array, PREG_SET_ORDER);
-
 
192
        $len = count($array);
-
 
193
        foreach ($array as $i => $char) {
-
 
194
                if (!iri_char_valid($char[0], $i==0, $i==$len-1)) return false;
-
 
195
        }
-
 
196
 
-
 
197
        return true;
-
 
198
}
-
 
199
 
-
 
200
 
-
 
201
*)  
-
 
202
 
-
 
203
end;
128
 
204
 
129
end.
205
end.
130
 
206