function _readTrackChunk(reader) { let length = reader.nextUInt32BE(); let events = []; let initialPosition = reader.tell(); let runningStatus; let chunkBuffer = reader.nextBuffer(length); let chunkReader = new BufferReader(chunkBuffer); while (chunkReader.tell() < length) { let eventChunk = _readEvent(chunkReader, runningStatus); runningStatus = eventChunk.runningStatus; delete eventChunk.runningStatus; events.push(eventChunk); } if (chunkReader.tell() < length) { // there are still bytes left unread--something has gone wrong let err = new Error('Chunk buffer was not exhausted; ' + (length - chunkReader.tell()) + ' bytes left'); err.remainingBytes = chunkReader.restAll(); throw err; } return events; }
function parse(buffer) { let reader = new BufferReader(buffer); let file = { header: undefined, tracks: [] }; let chunk = _readChunk(reader); if (chunk.isHeader) { file.header = chunk; delete chunk.isHeader; } if (_.isUndefined(file.header)) { throw new Error('MIDI file has no header data.'); } for (let i = 0, len = file.header.numberOfTracks; i < len; i++) { file.tracks.push(_readChunk(reader)); } if (reader.tell() < buffer.byteLength) { debug('File has bytes left over. This should not happen. Bytes are: ', reader.restAll()); } return new MIDIFile(file); }
handlePacket(buff, status) { var reader = new BufferReader(buff); // Get packet length... var length = Util.varintFromBufferReader(reader); // Get packet ID... var pId = Util.varintFromBufferReader(reader); if(pId == 122) { this.logger.error("Malformed JSON request? Client has requested legacy ping..."); } else { this.logger.info("Packet ID: " + pId); this.logger.info("Buffer Length: " + buff.length); this.logger.info("Buffer Contents: " + buff.inspect()); } this.logger.info("Current Connection State: " + this.connectionState); switch(this.connectionState) { case Connection.connectionState.HANDSHAKING: { switch(pId) { case 0x00: var version = Util.varintFromBufferReader(reader); var addressSize = Util.varintFromBufferReader(reader); var address = reader.nextString(addressSize); var port = reader.nextUInt16BE(); var nextState = Util.varintFromBufferReader(reader); this.logger.info("Version: " + version); this.logger.info("Address: " + address); this.logger.info("Port: " + port); this.connectionState = nextState; if(reader.tell() < buff.length) this.handlePacket(buff.slice(reader.tell()), status); break; } break; } case Connection.connectionState.STATUS: { switch(pId) { case 0x00: var resp = new Packets.PacketStatusResponse(status); this.logger.info(resp.toString()); var strLengthBuffer = Buffer.from(varint.encode(resp.toString().length)); var npLength = resp.toString().length + 1 + strLengthBuffer.length; var lengthBuffer = Buffer.from(varint.encode(npLength)); var codeBuffer = Buffer.from([0x00]); var stringBuffer = Buffer.from(resp.toString()); var finalBuffer = Buffer.concat([lengthBuffer,codeBuffer,strLengthBuffer,stringBuffer]); this.netStream.write(finalBuffer); this.logger.info(finalBuffer.inspect()); break; case 0x01: this.netStream.write(buff); break; } break; } default: { this.logger.fatal("Invalid connection state " + this.connectionState + " - closing..."); this.close(); } } }