@@ -29,49 +29,63 @@ export default class ResourceLocator {
29
29
static readonly LENGTH_OFFSET = 1 ;
30
30
static readonly LENGTH_LENGTH = 1 ;
31
31
static readonly BODY_OFFSET = 2 ;
32
+ static readonly IDENTIFIER_0_BYTE : number = 0 << 4 ; // 0
33
+ static readonly IDENTIFIER_2_BYTE : number = 1 << 4 ; // 16
34
+ static readonly IDENTIFIER_8_BYTE : number = 2 << 4 ; // 32
35
+ static readonly IDENTIFIER_32_BYTE : number = 3 << 4 ; // 48
32
36
33
37
static parse ( url : string , identifier : string = '' ) : ResourceLocator {
34
38
const [ protocol , body ] = url . split ( '://' ) ;
35
- const bodyLength = body . length ;
36
- const identifierLength = identifier . length ;
37
- let identifierPaddedLength = 0 ;
38
- // protocol and identifier byte
39
+
40
+ // Validate and set protocol identifier byte
39
41
const protocolIdentifierByte = new Uint8Array ( 1 ) ;
40
- if ( protocol . toLowerCase ( ) == 'http' ) {
41
- protocolIdentifierByte [ 0 ] = protocolIdentifierByte [ 0 ] & 0x0f ;
42
- } else if ( protocol . toLowerCase ( ) == 'https' ) {
43
- protocolIdentifierByte [ 0 ] = ( protocolIdentifierByte [ 0 ] & 0x0f ) | 0b0010 ;
44
- } else {
45
- throw new Error ( 'Resource locator protocol is not supported.' ) ;
46
- }
47
- if ( identifierLength === 0 ) {
48
- protocolIdentifierByte [ 0 ] = ( protocolIdentifierByte [ 0 ] & 0xf0 ) | 0b0000 ;
49
- } else if ( identifierLength <= 2 ) {
50
- protocolIdentifierByte [ 0 ] = ( protocolIdentifierByte [ 0 ] & 0xf0 ) | 0b0010 ;
51
- identifierPaddedLength = ResourceLocatorIdentifierEnum . TwoBytes . valueOf ( ) ;
52
- } else if ( identifierLength <= 8 ) {
53
- protocolIdentifierByte [ 0 ] = ( protocolIdentifierByte [ 0 ] & 0xf0 ) | 0b0100 ;
54
- identifierPaddedLength = ResourceLocatorIdentifierEnum . EightBytes . valueOf ( ) ;
55
- } else if ( identifierLength <= 32 ) {
56
- protocolIdentifierByte [ 0 ] = ( protocolIdentifierByte [ 0 ] & 0xf0 ) | 0b1000 ;
57
- identifierPaddedLength = ResourceLocatorIdentifierEnum . ThirtyTwoBytes . valueOf ( ) ;
58
- } else {
59
- throw new Error ( 'Unsupported identifier length: ' + identifierLength ) ;
42
+ switch ( protocol . toLowerCase ( ) ) {
43
+ case 'http' :
44
+ protocolIdentifierByte [ 0 ] = 0x00 ;
45
+ break ;
46
+ case 'https' :
47
+ protocolIdentifierByte [ 0 ] = 0x01 ;
48
+ break ;
49
+ default :
50
+ throw new Error ( 'Resource locator protocol is not supported.' ) ;
60
51
}
61
- // Buffer to hold the protocol, length of body, body, and identifierPadded
62
- const buffer = new Uint8Array ( 1 + 1 + bodyLength + identifierPaddedLength ) ;
52
+
53
+ // Set identifier padded length and protocol identifier byte
54
+ const identifierPaddedLength = ( ( ) => {
55
+ switch ( identifier . length ) {
56
+ case 0 :
57
+ protocolIdentifierByte [ 0 ] |= ResourceLocator . IDENTIFIER_0_BYTE ;
58
+ return ResourceLocatorIdentifierEnum . None . valueOf ( ) ;
59
+ case 2 :
60
+ protocolIdentifierByte [ 0 ] |= ResourceLocator . IDENTIFIER_2_BYTE ;
61
+ return ResourceLocatorIdentifierEnum . TwoBytes . valueOf ( ) ;
62
+ case 8 :
63
+ protocolIdentifierByte [ 0 ] |= ResourceLocator . IDENTIFIER_8_BYTE ;
64
+ return ResourceLocatorIdentifierEnum . EightBytes . valueOf ( ) ;
65
+ case 32 :
66
+ protocolIdentifierByte [ 0 ] |= ResourceLocator . IDENTIFIER_32_BYTE ;
67
+ return ResourceLocatorIdentifierEnum . ThirtyTwoBytes . valueOf ( ) ;
68
+ default :
69
+ throw new Error ( `Unsupported identifier length: ${ identifier . length } ` ) ;
70
+ }
71
+ } ) ( ) ;
72
+
73
+ // Create buffer to hold protocol, body length, body, and identifier
74
+ const bodyBytes = new TextEncoder ( ) . encode ( body ) ;
75
+ const buffer = new Uint8Array ( 1 + 1 + bodyBytes . length + identifierPaddedLength ) ;
76
+
77
+ // Set the protocol, body length, body and identifier into buffer
63
78
buffer . set ( protocolIdentifierByte , 0 ) ;
64
- buffer . set ( [ bodyLength ] , 1 ) ;
65
- buffer . set ( new TextEncoder ( ) . encode ( body ) , 2 ) ;
66
- // add padded identifier
79
+ buffer . set ( [ bodyBytes . length ] , 1 ) ;
80
+ buffer . set ( bodyBytes , 2 ) ;
81
+
67
82
if ( identifierPaddedLength > 0 ) {
68
- const identifierArray = new Uint8Array ( identifierPaddedLength ) ;
69
- const encodedIdentifier = new TextEncoder ( )
83
+ const identifierBytes = new TextEncoder ( )
70
84
. encode ( identifier )
71
85
. subarray ( 0 , identifierPaddedLength ) ;
72
- identifierArray . set ( encodedIdentifier ) ;
73
- buffer . set ( identifierArray , 2 + bodyLength ) ;
86
+ buffer . set ( identifierBytes , 2 + bodyBytes . length ) ;
74
87
}
88
+
75
89
return new ResourceLocator ( buffer ) ;
76
90
}
77
91
@@ -86,12 +100,12 @@ export default class ResourceLocator {
86
100
buff . subarray ( ResourceLocator . BODY_OFFSET , ResourceLocator . BODY_OFFSET + this . lengthOfBody )
87
101
) ;
88
102
// identifier
89
- const identifierTypeNibble = this . protocol & 0xf ;
90
- if ( ( identifierTypeNibble & 0b0010 ) !== 0 ) {
103
+ const identifierTypeNibble = this . protocol & 0xf0 ;
104
+ if ( identifierTypeNibble === ResourceLocator . IDENTIFIER_2_BYTE ) {
91
105
this . identifierType = ResourceLocatorIdentifierEnum . TwoBytes ;
92
- } else if ( ( identifierTypeNibble & 0b0100 ) !== 0 ) {
106
+ } else if ( identifierTypeNibble === ResourceLocator . IDENTIFIER_8_BYTE ) {
93
107
this . identifierType = ResourceLocatorIdentifierEnum . EightBytes ;
94
- } else if ( ( identifierTypeNibble & 0b1000 ) !== 0 ) {
108
+ } else if ( identifierTypeNibble === ResourceLocator . IDENTIFIER_32_BYTE ) {
95
109
this . identifierType = ResourceLocatorIdentifierEnum . ThirtyTwoBytes ;
96
110
}
97
111
switch ( this . identifierType ) {
0 commit comments