UNPKG

@sap/odata-v4

Version:

OData V4.0 server library

108 lines (85 loc) 3.22 kB
'use strict'; const HeaderReader = require('./HeaderReader'); const Reader = require('./Reader'); const STATES = { RUN_HEADER_READER: 'RUN_HEADER_READER', RUN_HEADER_READER_RETURN: 'RUN_HEADER_READER_RETURN', RUN_READER: 'RUN_READER', RUN_READER_RETURN: 'RUN_READER_RETURN', FINISHED: 'finished' }; /** * Events * @enum {{DATA: string, END: string}} */ const EVENTS = { START: 'part.start', HEADERS: 'part.headers', END: 'part.end' }; /** * Reads a part of a multipart request from the Cache. * * @extends Reader */ class PartReader extends Reader { /** * @param {string} crlfBoundary - The boundary determining the end of the multipart reader */ constructor(crlfBoundary) { super(); this._crlfBoundary = crlfBoundary; this._headerReader = null; this._bodyReader = null; this._state = STATES.RUN_HEADER_READER; this._partHeaderInfos = null; } /** * Read data from cache until the boundary is reached or the cache is empty. If the cache is empty and more data * is required, this is signaled and readCach is called again. The state is preserved. * * @param {ContentDeserializer} reader * @returns {boolean} * this: this reader needs more data and caller should call this method again with more data in cache * false: this reader is finished caller should pop this reader from stack * null: new sub reader is on stack, call this method again after the sub reader is finished */ readCache(reader) { // let done = false; let needMoreData = false; while (needMoreData === false && this._state !== STATES.FINISHED) { switch (this._state) { case STATES.RUN_HEADER_READER: this.emit(EVENTS.START); this._headerReader = new HeaderReader().setEmitter(this._emitter); reader.pushReader(this._headerReader); this._state = STATES.RUN_HEADER_READER_RETURN; needMoreData = null; break; case STATES.RUN_HEADER_READER_RETURN: this._partHeaderInfos = this._headerReader.getHeaderInfos(); this.emit(EVENTS.HEADERS, this._partHeaderInfos); this._state = STATES.RUN_READER; break; case STATES.RUN_READER: this._bodyReader = reader.getNextReader(this._partHeaderInfos).setEmitter(this._emitter); this._bodyReader.setStopPattern(this._crlfBoundary); reader.pushReader(this._bodyReader); this._state = STATES.RUN_READER_RETURN; needMoreData = null; break; case STATES.RUN_READER_RETURN: this._state = STATES.FINISHED; break; default: break; } } if (this._state === STATES.FINISHED) { this.emit(EVENTS.END); } return needMoreData; } } PartReader.EVENTS = EVENTS; module.exports = PartReader;