@@ -40,7 +40,7 @@ export default class EnumType<E> extends AbstractType<E> {
4040 */
4141 readonly values : E [ ]
4242 private readonly type : Type < E >
43- private readonly valueIndices : Map < string , number >
43+ private cachedValueIndices : Map < string , number > | undefined
4444 /**
4545 * @param type The type of each element in the tuple
4646 * @param values The possible distinct values.
@@ -55,22 +55,27 @@ export default class EnumType<E> extends AbstractType<E> {
5555 try { assert . byteUnsignedInteger ( values . length ) }
5656 catch ( e ) { assert . fail ( String ( values . length ) + ' values is too many' ) }
5757
58+ this . type = type
59+ this . values = values //used when reading to get constant-time lookup of value index into value
60+ }
61+ private get valueIndices ( ) {
62+ const { type, values, cachedValueIndices} = this
63+ if ( cachedValueIndices ) return cachedValueIndices
64+
5865 const valueIndices = new Map < string , number > ( )
5966 for ( let i = 0 ; i < values . length ; i ++ ) {
6067 const value = values [ i ]
6168 const valueString = bufferString . toBinaryString ( type . valueBuffer ( value ) ) //convert value to bytes and then string for use as a map key
6269 if ( valueIndices . has ( valueString ) ) assert . fail ( 'Value is repeated: ' + inspect ( value ) )
6370 valueIndices . set ( valueString , i ) //so writing a value has constant-time lookup into the values array
6471 }
65- this . type = type
66- this . values = values //used when reading to get constant-time lookup of value index into value
67- this . valueIndices = valueIndices
72+ return this . cachedValueIndices = valueIndices
6873 }
6974 addToBuffer ( buffer : AppendableBuffer ) {
7075 /*istanbul ignore else*/
7176 if ( super . addToBuffer ( buffer ) ) {
7277 this . type . addToBuffer ( buffer )
73- buffer . add ( this . valueIndices . size )
78+ buffer . add ( this . values . length )
7479 for ( const valueBuffer of this . valueIndices . keys ( ) ) {
7580 buffer . addAll ( bufferString . fromBinaryString ( valueBuffer ) )
7681 }
@@ -100,13 +105,9 @@ export default class EnumType<E> extends AbstractType<E> {
100105 consumeValue ( buffer : ArrayBuffer , offset : number ) : ReadResult < E > {
101106 assert ( buffer . byteLength > offset , NOT_LONG_ENOUGH )
102107 const valueIndex = new Uint8Array ( buffer ) [ offset ]
103- //Can't check for value === undefined since value could be undefined with OptionalType
104- const { values} = this
105- assert ( valueIndex in values , 'Index ' + String ( valueIndex ) + ' is invalid' )
106- return {
107- value : values [ valueIndex ] ,
108- length : 1
109- }
108+ const value = this . values [ valueIndex ] as E | undefined
109+ if ( value === undefined ) throw new Error ( 'Index ' + String ( valueIndex ) + ' is invalid' )
110+ return { value, length : 1 }
110111 }
111112 equals ( otherType : any ) {
112113 if ( ! super . equals ( otherType ) ) return false
0 commit comments