@@ -47,118 +47,96 @@ function tagToFieldNumber(tag) {
4747}
4848
4949/**
50- * An Indexer that indexes a given binary protobuf by fieldnumber.
50+ * Creates an index of field locations in a given binary protobuf.
51+ * @param {!BufferDecoder } bufferDecoder
52+ * @param {number|undefined } pivot
53+ * @return {!Storage<!Field> }
54+ * @package
5155 */
52- class Indexer {
53- /**
54- * @param {!BufferDecoder } bufferDecoder
55- * @private
56- */
57- constructor ( bufferDecoder ) {
58- /** @private @const {!BufferDecoder} */
59- this . bufferDecoder_ = bufferDecoder ;
60- }
61-
62- /**
63- * @param {number|undefined } pivot
64- * @return {!Storage<!Field> }
65- */
66- index ( pivot ) {
67- this . bufferDecoder_ . setCursor ( this . bufferDecoder_ . startIndex ( ) ) ;
68-
69- const storage = new Storage ( pivot ) ;
70- while ( this . bufferDecoder_ . hasNext ( ) ) {
71- const tag = this . bufferDecoder_ . getUnsignedVarint32 ( ) ;
72- const wireType = tagToWireType ( tag ) ;
73- const fieldNumber = tagToFieldNumber ( tag ) ;
74- checkCriticalState (
75- fieldNumber > 0 , `Invalid field number ${ fieldNumber } ` ) ;
56+ function buildIndex ( bufferDecoder , pivot ) {
57+ bufferDecoder . setCursor ( bufferDecoder . startIndex ( ) ) ;
7658
77- addIndexEntry (
78- storage , fieldNumber , wireType , this . bufferDecoder_ . cursor ( ) ) ;
59+ const storage = new Storage ( pivot ) ;
60+ while ( bufferDecoder . hasNext ( ) ) {
61+ const tag = bufferDecoder . getUnsignedVarint32 ( ) ;
62+ const wireType = tagToWireType ( tag ) ;
63+ const fieldNumber = tagToFieldNumber ( tag ) ;
64+ checkCriticalState ( fieldNumber > 0 , `Invalid field number ${ fieldNumber } ` ) ;
7965
80- checkCriticalState (
81- ! this . skipField_ ( wireType , fieldNumber ) ,
82- 'Found unmatched stop group.' ) ;
83- }
84- return storage ;
85- }
66+ addIndexEntry ( storage , fieldNumber , wireType , bufferDecoder . cursor ( ) ) ;
8667
87- /**
88- * Skips over fields until the next field of the message.
89- * @param {!WireType } wireType
90- * @param {number } fieldNumber
91- * @return {boolean } Whether the field we skipped over was a stop group.
92- * @private
93- */
94- skipField_ ( wireType , fieldNumber ) {
95- switch ( wireType ) {
96- case WireType . VARINT :
97- checkCriticalElementIndex (
98- this . bufferDecoder_ . cursor ( ) , this . bufferDecoder_ . endIndex ( ) ) ;
99- this . bufferDecoder_ . skipVarint ( this . bufferDecoder_ . cursor ( ) ) ;
100- return false ;
101- case WireType . FIXED64 :
102- this . bufferDecoder_ . skip ( 8 ) ;
103- return false ;
104- case WireType . DELIMITED :
105- checkCriticalElementIndex (
106- this . bufferDecoder_ . cursor ( ) , this . bufferDecoder_ . endIndex ( ) ) ;
107- const length = this . bufferDecoder_ . getUnsignedVarint32 ( ) ;
108- this . bufferDecoder_ . skip ( length ) ;
109- return false ;
110- case WireType . START_GROUP :
111- checkCriticalState ( this . skipGroup_ ( fieldNumber ) , 'No end group found.' ) ;
112- return false ;
113- case WireType . END_GROUP :
114- // Signal that we found a stop group to the caller
115- return true ;
116- case WireType . FIXED32 :
117- this . bufferDecoder_ . skip ( 4 ) ;
118- return false ;
119- default :
120- throw new Error ( `Invalid wire type: ${ wireType } ` ) ;
121- }
68+ checkCriticalState (
69+ ! skipField_ ( bufferDecoder , wireType , fieldNumber ) ,
70+ 'Found unmatched stop group.' ) ;
12271 }
72+ return storage ;
73+ }
12374
124- /**
125- * Skips over fields until it finds the end of a given group.
126- * @param {number } groupFieldNumber
127- * @return {boolean } Returns true if an end was found.
128- * @private
129- */
130- skipGroup_ ( groupFieldNumber ) {
131- // On a start group we need to keep skipping fields until we find a
132- // corresponding stop group
133- // Note: Since we are calling skipField from here nested groups will be
134- // handled by recursion of this method and thus we will not see a nested
135- // STOP GROUP here unless there is something wrong with the input data.
136- while ( this . bufferDecoder_ . hasNext ( ) ) {
137- const tag = this . bufferDecoder_ . getUnsignedVarint32 ( ) ;
138- const wireType = tagToWireType ( tag ) ;
139- const fieldNumber = tagToFieldNumber ( tag ) ;
140-
141- if ( this . skipField_ ( wireType , fieldNumber ) ) {
142- checkCriticalState (
143- groupFieldNumber === fieldNumber ,
144- `Expected stop group for fieldnumber ${
145- groupFieldNumber } not found.`) ;
146- return true ;
147- }
148- }
149- return false ;
75+ /**
76+ * Skips over fields until the next field of the message.
77+ * @param {!BufferDecoder } bufferDecoder
78+ * @param {!WireType } wireType
79+ * @param {number } fieldNumber
80+ * @return {boolean } Whether the field we skipped over was a stop group.
81+ * @private
82+ */
83+ function skipField_ ( bufferDecoder , wireType , fieldNumber ) {
84+ switch ( wireType ) {
85+ case WireType . VARINT :
86+ checkCriticalElementIndex (
87+ bufferDecoder . cursor ( ) , bufferDecoder . endIndex ( ) ) ;
88+ bufferDecoder . skipVarint ( bufferDecoder . cursor ( ) ) ;
89+ return false ;
90+ case WireType . FIXED64 :
91+ bufferDecoder . skip ( 8 ) ;
92+ return false ;
93+ case WireType . DELIMITED :
94+ checkCriticalElementIndex (
95+ bufferDecoder . cursor ( ) , bufferDecoder . endIndex ( ) ) ;
96+ const length = bufferDecoder . getUnsignedVarint32 ( ) ;
97+ bufferDecoder . skip ( length ) ;
98+ return false ;
99+ case WireType . START_GROUP :
100+ checkCriticalState (
101+ skipGroup_ ( bufferDecoder , fieldNumber ) , 'No end group found.' ) ;
102+ return false ;
103+ case WireType . END_GROUP :
104+ // Signal that we found a stop group to the caller
105+ return true ;
106+ case WireType . FIXED32 :
107+ bufferDecoder . skip ( 4 ) ;
108+ return false ;
109+ default :
110+ throw new Error ( `Invalid wire type: ${ wireType } ` ) ;
150111 }
151112}
152113
153114/**
154- * Creates an index of field locations in a given binary protobuf .
115+ * Skips over fields until it finds the end of a given group .
155116 * @param {!BufferDecoder } bufferDecoder
156- * @param {number|undefined } pivot
157- * @return {!Storage<!Field> }
158- * @package
117+ * @param {number } groupFieldNumber
118+ * @return {boolean } Returns true if an end was found.
119+ * @private
159120 */
160- function buildIndex ( bufferDecoder , pivot ) {
161- return new Indexer ( bufferDecoder ) . index ( pivot ) ;
121+ function skipGroup_ ( bufferDecoder , groupFieldNumber ) {
122+ // On a start group we need to keep skipping fields until we find a
123+ // corresponding stop group
124+ // Note: Since we are calling skipField from here nested groups will be
125+ // handled by recursion of this method and thus we will not see a nested
126+ // STOP GROUP here unless there is something wrong with the input data.
127+ while ( bufferDecoder . hasNext ( ) ) {
128+ const tag = bufferDecoder . getUnsignedVarint32 ( ) ;
129+ const wireType = tagToWireType ( tag ) ;
130+ const fieldNumber = tagToFieldNumber ( tag ) ;
131+
132+ if ( skipField_ ( bufferDecoder , wireType , fieldNumber ) ) {
133+ checkCriticalState (
134+ groupFieldNumber === fieldNumber ,
135+ `Expected stop group for fieldnumber ${ groupFieldNumber } not found.` ) ;
136+ return true ;
137+ }
138+ }
139+ return false ;
162140}
163141
164142exports = {
0 commit comments