@@ -186,6 +186,79 @@ func PrevLabel(s string, n int) (i int, start bool) {
186
186
return 0 , n > 1
187
187
}
188
188
189
+ // Compare compares domains according to the canonical ordering specified in RFC4034
190
+ // returns an integer value similar to strcmp
191
+ // (0 for equal values, -1 if s1 < s2, 1 if s1 > s2)
192
+ func Compare (s1 , s2 string ) int {
193
+ s1b := []byte (s1 )
194
+ s2b := []byte (s2 )
195
+
196
+ doDDD (s1b )
197
+ doDDD (s2b )
198
+
199
+ s1lend := len (s1 )
200
+ s2lend := len (s2 )
201
+
202
+ for i := 0 ; ; i ++ {
203
+ s1lstart , end1 := PrevLabel (s1 , i )
204
+ s2lstart , end2 := PrevLabel (s2 , i )
205
+
206
+ if end1 && end2 {
207
+ return 0
208
+ }
209
+
210
+ s1l := string (s1b [s1lstart :s1lend ])
211
+ s2l := string (s2b [s2lstart :s2lend ])
212
+
213
+ if cmp := labelCompare (s1l , s2l ); cmp != 0 {
214
+ return cmp
215
+ }
216
+
217
+ s1lend = s1lstart - 1
218
+ s2lend = s2lstart - 1
219
+ if s1lend == - 1 {
220
+ s1lend = 0
221
+ }
222
+ if s2lend == - 1 {
223
+ s2lend = 0
224
+ }
225
+ }
226
+ }
227
+
228
+ // essentially strcasecmp
229
+ // (0 for equal values, -1 if s1 < s2, 1 if s1 > s2)
230
+ func labelCompare (a , b string ) int {
231
+ la := len (a )
232
+ lb := len (b )
233
+ minLen := la
234
+ if lb < la {
235
+ minLen = lb
236
+ }
237
+ for i := 0 ; i < minLen ; i ++ {
238
+ ai := a [i ]
239
+ bi := b [i ]
240
+ if ai >= 'A' && ai <= 'Z' {
241
+ ai |= 'a' - 'A'
242
+ }
243
+ if bi >= 'A' && bi <= 'Z' {
244
+ bi |= 'a' - 'A'
245
+ }
246
+ if ai != bi {
247
+ if ai > bi {
248
+ return 1
249
+ }
250
+ return - 1
251
+ }
252
+ }
253
+
254
+ if la > lb {
255
+ return 1
256
+ } else if la < lb {
257
+ return - 1
258
+ }
259
+ return 0
260
+ }
261
+
189
262
// equal compares a and b while ignoring case. It returns true when equal otherwise false.
190
263
func equal (a , b string ) bool {
191
264
// might be lifted into API function.
@@ -210,3 +283,16 @@ func equal(a, b string) bool {
210
283
}
211
284
return true
212
285
}
286
+
287
+ func doDDD (b []byte ) {
288
+ lb := len (b )
289
+ for i := 0 ; i < lb ; i ++ {
290
+ if i + 3 < lb && b [i ] == '\\' && isDigit (b [i + 1 ]) && isDigit (b [i + 2 ]) && isDigit (b [i + 3 ]) {
291
+ b [i ] = dddToByte (b [i + 1 : i + 4 ])
292
+ for j := i + 1 ; j < lb - 3 ; j ++ {
293
+ b [j ] = b [j + 3 ]
294
+ }
295
+ lb -= 3
296
+ }
297
+ }
298
+ }
0 commit comments