@@ -23,6 +23,91 @@ import { debugAssert } from './assert';
2323import { BundleReader , SizedBundleElement } from './bundle_reader' ;
2424import { Deferred } from './promise' ;
2525
26+ class SyncBundleReaderImpl {
27+ private metadata : BundleMetadata | null ;
28+ private elements : Array < SizedBundleElement > ;
29+ private cursor : number ;
30+ constructor (
31+ /** The reader to read from underlying binary bundle data source. */
32+ private bundleData : string ,
33+ readonly serializer : JsonProtoSerializer
34+ ) {
35+ this . metadata = null ;
36+ this . cursor = 0 ;
37+ this . elements = new Array < SizedBundleElement > ( ) ;
38+ }
39+
40+ parse ( ) : void {
41+ let element = this . nextElement ( ) ;
42+ if ( element && element . isBundleMetadata ( ) ) {
43+ this . metadata = element as BundleMetadata ;
44+ } else {
45+ throw new Error ( `The first element of the bundle is not a metadata, it is
46+ ${ JSON . stringify ( element ?. payload ) } ` ) ;
47+ }
48+ }
49+
50+ getMetadata ( ) : BundleMetadata | null {
51+ return this . metadata ;
52+ }
53+
54+ private nextElement ( ) : SizedBundleElement | null {
55+ if ( this . cursor === this . bundleData . length ) {
56+ return null ;
57+ }
58+
59+ const length = this . readLength ( ) ;
60+ const jsonString = this . readJsonString ( length ) ;
61+
62+ return new SizedBundleElement ( JSON . parse ( jsonString ) , jsonString . length ) ;
63+ }
64+
65+ /**
66+ * Reads from a specified position from the bundleData string, for a specified
67+ * number of bytes.
68+ *
69+ * Returns a string parsed from the bundle.
70+ */
71+ private readJsonString ( length : number ) : string {
72+ if ( this . cursor + length > this . bundleData . length ) {
73+ throw new Error ( 'Reached the end of bundle when more is expected.' ) ;
74+ }
75+ const result = this . bundleData . slice ( this . cursor , length ) ;
76+ this . cursor += length ;
77+ return result ;
78+ }
79+
80+ /** First index of '{' from the bundle starting at the optionally provided offset. */
81+ private indexOfOpenBracket ( offset ?: number ) : number {
82+ let buffer : string = this . bundleData ;
83+ if ( offset ) {
84+ buffer = this . bundleData . substring ( offset ) ;
85+ }
86+ return buffer . indexOf ( '{' ) ;
87+ }
88+
89+ /**
90+ * Reads from the current cursor until the first '{', returns number value
91+ *
92+ * If reached end of the stream, or the value isn't a number, then throws.
93+ */
94+ private readLength ( ) : number {
95+ const startIndex = this . cursor ;
96+ let curIndex = this . cursor ;
97+ while ( curIndex < this . bundleData . length ) {
98+ if ( this . bundleData [ curIndex ] === '{' ) {
99+ if ( curIndex === startIndex ) {
100+ throw new Error ( 'First character is a bracket and not a number' ) ;
101+ }
102+ this . cursor = curIndex ;
103+ return Number ( this . bundleData . slice ( startIndex , curIndex ) ) ;
104+ }
105+ curIndex ++ ;
106+ }
107+ throw new Error ( 'Reached the end of bundle when more is expected.' ) ;
108+ }
109+ }
110+
26111/**
27112 * A class representing a bundle.
28113 *
0 commit comments