@@ -38,7 +38,7 @@ function identifyBoundary(header) {
3838 const parts = header . split ( '\r\n' ) ;
3939
4040 for ( let i = 0 ; i < parts . length ; i ++ ) {
41- if ( parts [ i ] . substr ( 0 , 2 ) === '--' ) {
41+ if ( parts [ i ] . substring ( 0 , 2 ) === '--' ) {
4242 return parts [ i ] ;
4343 }
4444 }
@@ -179,16 +179,72 @@ function multipartEncode(
179179 } ;
180180}
181181
182+ /**
183+ * Splits the header string into parts and extracts the simple contentType
184+ * and transferSyntaxUID, assigning them, plus the headers map into the destination object.
185+ *
186+ * @param {* } destination
187+ * @param {string } headerString
188+ */
189+ function addHeaders ( destination , headerString ) {
190+ if ( ! headerString ) {
191+ return ;
192+ }
193+ const headerLines = headerString . split ( '\r\n' ) . filter ( Boolean ) ;
194+ const headers = new Map ( ) ;
195+ let transferSyntaxUID = null ,
196+ contentType = null ;
197+
198+ for ( const line of headerLines ) {
199+ const colon = line . indexOf ( ':' ) ;
200+ if ( colon === - 1 ) {
201+ continue ;
202+ }
203+ const name = line . substring ( 0 , colon ) . toLowerCase ( ) ;
204+ const value = line . substring ( colon + 1 ) . trim ( ) ;
205+ if ( headers . has ( name ) ) {
206+ headers . get ( name ) . push ( value ) ;
207+ } else {
208+ headers . set ( name , [ value ] ) ;
209+ }
210+ if ( name === 'content-type' ) {
211+ const endSimpleType = value . indexOf ( ';' ) ;
212+ contentType ||= value . substring (
213+ 0 ,
214+ endSimpleType === - 1 ? value . length : endSimpleType ,
215+ ) ;
216+ const transferSyntaxStart = value . indexOf ( 'transfer-syntax=' ) ;
217+ if ( transferSyntaxStart !== - 1 ) {
218+ const endTsuid = value . indexOf ( ';' , transferSyntaxStart ) ;
219+ transferSyntaxUID = value . substring (
220+ transferSyntaxStart + 16 ,
221+ endTsuid === - 1 ? value . length : endTsuid ,
222+ ) ;
223+ }
224+ }
225+ }
226+
227+ Object . defineProperty ( destination , 'headers' , { value : headers } ) ;
228+ Object . defineProperty ( destination , 'contentType' , { value : contentType } ) ;
229+ Object . defineProperty ( destination , 'transferSyntaxUID' , {
230+ value : transferSyntaxUID ,
231+ } ) ;
232+ }
233+
182234/**
183235 * Decode a Multipart encoded ArrayBuffer and return the components as an Array.
184236 *
185237 * @param {ArrayBuffer } response Data encoded as a 'multipart/related' message
186- * @returns {Array } The content
238+ * @returns {Uint8Array[] } The content as an array of Uint8Array
239+ * Each item shall have a contentType value, and a transferSyntaxUID if available,
240+ * as well as the headers Map. See parseHeaders for output.
241+ *
187242 */
188243function multipartDecode ( response ) {
189244 // Use the raw data if it is provided in an appropriate format
190- const message = ArrayBuffer . isView ( response ) ? response : new Uint8Array ( response ) ;
191-
245+ const message = ArrayBuffer . isView ( response )
246+ ? response
247+ : new Uint8Array ( response ) ;
192248 /* Set a maximum length to search for the header boundaries, otherwise
193249 findToken can run for a long time
194250 */
@@ -211,6 +267,8 @@ function multipartDecode(response) {
211267 const boundaryLength = boundary . length ;
212268 const components = [ ] ;
213269
270+ const headers = header . substring ( boundary . length + 2 ) ;
271+
214272 let offset = boundaryLength ;
215273
216274 // Loop until we cannot find any more boundaries
@@ -240,6 +298,8 @@ function multipartDecode(response) {
240298 // Extract data from response message, excluding "\r\n"
241299 const spacingLength = 2 ;
242300 const data = response . slice ( offset , boundaryIndex - spacingLength ) ;
301+ // TODO - extract header data on a per frame basis.
302+ addHeaders ( data , headers ) ;
243303
244304 // Add the data to the array of results
245305 components . push ( data ) ;
@@ -261,4 +321,5 @@ export {
261321 multipartEncode ,
262322 multipartDecode ,
263323 guid ,
324+ addHeaders ,
264325} ;
0 commit comments