1 module types.oidtype; 2 import asn1; 3 import codec : ASN1ValueException; 4 import std.ascii : isGraphical; 5 6 /// 7 public alias OIDNode = ObjectIdentifierNode; 8 /** 9 A struct representing a single node in an OID, which has a mandatory 10 number and an optional descriptor. 11 */ 12 public 13 struct ObjectIdentifierNode 14 { 15 /** 16 The unique unsigned integral number associated with a node in the 17 object identifier hierarchy. 18 */ 19 immutable public size_t number; 20 /** 21 The descriptor string is an ObjectDescriptor, which is defined as: 22 23 $(MONO ObjectDescriptor ::= [UNIVERSAL 7] IMPLICIT GraphicString) 24 25 GraphicString is just $(D 0x20) to $(D 0x7E), therefore 26 ObjectDescriptor is just $(D 0x20) to $(D 0x7E). 27 28 It is used to describe the object identified by this node. 29 */ 30 immutable public string descriptor; 31 32 /// Override for use of the `==` operand. 33 public @safe @nogc nothrow 34 bool opEquals(const OIDNode other) const 35 { 36 return (this.number == other.number); 37 } 38 39 /// 40 @system 41 unittest 42 { 43 immutable OIDNode a = OIDNode(1, "iso"); 44 immutable OIDNode b = OIDNode(1, "not-iso"); 45 assert(a == b); 46 } 47 48 /// Override for the use of the '>', '<', '<=', and '>=' operands. 49 public @safe @nogc nothrow 50 ptrdiff_t opCmp(ref const OIDNode other) const 51 { 52 return cast(ptrdiff_t) (this.number - other.number); 53 } 54 55 /** 56 An override so that associative arrays can use an $(D OIDNode) as a 57 key. 58 Returns: A $(D size_t) that represents a hash of the $(D OIDNode) 59 */ 60 public nothrow @trusted 61 size_t toHash() const 62 { 63 return typeid(this.number).getHash(cast(const void*) &this.number); 64 } 65 66 /// 67 @system 68 unittest 69 { 70 immutable OIDNode a = OIDNode(1, "iso"); 71 immutable OIDNode b = OIDNode(2, "even-more-iso"); 72 assert(b > a); 73 } 74 75 /// The simple numeric constructor. Does not throw exceptions. 76 public @safe @nogc nothrow 77 this(in size_t number) 78 { 79 this.number = number; 80 this.descriptor = ""; 81 } 82 83 /** 84 A constructor that accepts a descriptor string. 85 The descriptor string is an ObjectDescriptor, which is defined as: 86 87 $(MONO ObjectDescriptor ::= [UNIVERSAL 7] IMPLICIT GraphicString) 88 89 $(MONO GraphicString) is just a string containing only characters between 90 and including $(D 0x20) and $(D 0x7E), therefore ObjectDescriptor is just 91 $(D 0x20) and $(D 0x7E). 92 93 Throws: 94 $(UL 95 $(LI $(D ASN1ValueException) if the encoded value contains any bytes 96 outside of $(D 0x20) to $(D 0x7E)) 97 ) 98 */ 99 public @system 100 this(in size_t number, in string descriptor) 101 { 102 foreach (immutable character; descriptor) 103 { 104 if ((!character.isGraphical) && (character != ' ')) 105 { 106 throw new ASN1ValueException 107 ( 108 "This exception was thrown because you tried to decode " ~ 109 "a GraphicString that contained a character that " ~ 110 "is not graphical (a character whose ASCII encoding " ~ 111 "is outside of the range 0x20 to 0x7E). The offending " ~ 112 "character is '" ~ character ~ "'. " ~ 113 "For more information on Object Identifiers, read the " ~ 114 "International Telecommunications Union's X.660 specification, " ~ 115 "which can be found at " ~ 116 "http://www.itu.int/rec/T-REC-X.660-201107-I/en. " ~ 117 "If you believe that you have " ~ 118 "discovered a bug, please create an issue on the GitHub page's Issues " ~ 119 "section at: https://github.com/JonathanWilbur/asn1-d/issues. " 120 ); 121 } 122 } 123 this.number = number; 124 this.descriptor = descriptor; 125 } 126 127 @system 128 unittest 129 { 130 immutable OIDNode a = OIDNode(1, "Nitro dubs & T-Rix"); 131 assert(a.descriptor == "Nitro dubs & T-Rix"); 132 immutable OIDNode b = OIDNode(1, " "); 133 assert(b.descriptor == " "); 134 immutable OIDNode c = OIDNode(1, ""); 135 assert(c.descriptor == ""); 136 assertThrown!ASN1ValueException(OIDNode(1, "\xD7")); 137 assertThrown!ASN1ValueException(OIDNode(1, "\t")); 138 assertThrown!ASN1ValueException(OIDNode(1, "\r")); 139 assertThrown!ASN1ValueException(OIDNode(1, "\n")); 140 assertThrown!ASN1ValueException(OIDNode(1, "\b")); 141 assertThrown!ASN1ValueException(OIDNode(1, "\v")); 142 assertThrown!ASN1ValueException(OIDNode(1, "\f")); 143 assertThrown!ASN1ValueException(OIDNode(1, "\0")); 144 } 145 }