1 // Copyright 2009 The Archiveopteryx Developers <info@aox.org>
2 
3 #include "ascii-numeric.h"
4 
5 
number(const UString & a)6 static uint number( const UString & a )
7 {
8     uint i = 0;
9     while ( a[i] == '0' )
10         i++;
11 
12     uint start = i;
13     while ( a[i] >= '0' && a[i] <= '9' )
14         i++;
15 
16     UString n( a.mid( start, i-start ) );
17 
18     if ( n.isEmpty() ) {
19         if ( start != 0 )
20             return 0;
21         else
22             return UINT_MAX;
23     }
24     return n.number( 0 );
25 }
26 
27 
28 /*! \class AsciiNumeric ascii-numeric.h
29     Implements the "i;ascii-numeric" collation from RFC 4790.
30 
31     The "i;ascii-numeric" collation is a simple collation intended for
32     use with arbitrarily-sized, unsigned decimal integer numbers stored
33     as octet strings. US-ASCII digits (0x30 to 0x39) represent digits of
34     the numbers. Before converting from string to integer, the input
35     string is truncated at the first non-digit character. All input is
36     valid; strings that do not start with a digit represent positive
37     infinity.
38 */
39 
AsciiNumeric()40 AsciiNumeric::AsciiNumeric()
41     : Collation()
42 {
43 }
44 
45 
46 /*! Returns true (all input strings are valid). */
47 
valid(const UString &) const48 bool AsciiNumeric::valid( const UString & ) const
49 {
50     return true;
51 }
52 
53 
54 /*! Returns true if \a a is equal to \a b, and false otherwise. */
55 
equals(const UString & a,const UString & b) const56 bool AsciiNumeric::equals( const UString & a, const UString & b ) const
57 {
58     if ( number( a ) == number( b ) )
59         return true;
60     return false;
61 }
62 
63 
64 /*! Returns false (this collation doesn't support substring operations).
65 */
66 
contains(const UString &,const UString &) const67 bool AsciiNumeric::contains( const UString &, const UString & ) const
68 {
69     return false;
70 }
71 
72 
73 /*! Returns -1, 0, or 1 if \a a is smaller than, equal to, or greater
74     than \a b, respectively.
75 */
76 
compare(const UString & a,const UString & b) const77 int AsciiNumeric::compare( const UString & a, const UString & b ) const
78 {
79     uint na = number( a );
80     uint nb = number( b );
81 
82     if ( na < nb )
83         return -1;
84     else if ( nb < na )
85         return 1;
86     return 0;
87 }
88