From ae0d6f3310b528f38befd166f01aa42c795cb302 Mon Sep 17 00:00:00 2001 From: Weiwei Date: Tue, 9 Feb 2016 17:49:20 -0600 Subject: [PATCH] wwu --- Packages/dimseservice/package.js | 1 + Packages/dimseservice/server/CSocket.js | 587 +++++++++ Packages/dimseservice/server/Connection.js | 681 ++--------- Packages/dimseservice/server/DIMSE.js | 183 ++- Packages/dimseservice/server/Data.js | 1243 ++++++++++---------- Packages/dimseservice/server/Field.js | 141 +-- Packages/dimseservice/server/Message.js | 580 +++++---- Packages/dimseservice/server/PDU.js | 841 ++++++------- Packages/dimseservice/server/RWStream.js | 302 ++--- Packages/dimseservice/server/constants.js | 195 +-- Packages/dimseservice/server/methods.js | 2 +- Packages/dimseservice/server/require.js | 2 +- config/orthancDIMSE.json | 6 +- 13 files changed, 2393 insertions(+), 2371 deletions(-) create mode 100755 Packages/dimseservice/server/CSocket.js diff --git a/Packages/dimseservice/package.js b/Packages/dimseservice/package.js index 52b4125a0..73792bf6e 100755 --- a/Packages/dimseservice/package.js +++ b/Packages/dimseservice/package.js @@ -15,6 +15,7 @@ Package.onUse(function(api) { api.addFiles('server/Data.js', 'server'); api.addFiles('server/Message.js', 'server'); api.addFiles('server/PDU.js', 'server'); + api.addFiles('server/CSocket.js', 'server'); api.addFiles('server/Connection.js', 'server'); api.addFiles('server/DIMSE.js', 'server'); diff --git a/Packages/dimseservice/server/CSocket.js b/Packages/dimseservice/server/CSocket.js new file mode 100755 index 000000000..74a320edf --- /dev/null +++ b/Packages/dimseservice/server/CSocket.js @@ -0,0 +1,587 @@ +var EventEmitter = Npm.require('events').EventEmitter; + +function time() { + return Math.floor(Date.now() / 1000); +} + +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min)) + min; +} + +var Envelope = function(command, dataset) { + EventEmitter.call(this); + this.command = command; + this.dataset = dataset; +} +util.inherits(Envelope, EventEmitter); + +CSocket = function(socket, options) { + EventEmitter.call(this); + this.socket = socket; + this.negotiatedContexts = {}; + this.receiving = null; + this.receiveLength = null; + this.minRecv = null; + this.lastReceived = null; + this.presentationContexts = []; + this.associated = false; + this.pendingPDVs = null; + this.connected = false; + this.started = null; + this.intervalId = null; + this.lastCommand = null; + this.lastSent = null; + this.messages = {}; + this.messageIdCounter = 0; + this.callingAe = null; + this.calledAe = null; + this.id = getRandomInt(1000, 9999); + this.options = options; + + var o = this; + this.socket.on("connect", function(){ + o.ready(); + }); + this.socket.on("data", function(data) { + o.received(data); + }); + this.socket.on("error", function(he) { + console.log("Error: ", he); + }); + this.socket.on("close", function() { + if (o.intervalId) { + clearInterval(o.intervalId); + } + o.connected = false; + console.log("Connection closed"); + o.emit('close'); + }) + + this.on("released", function() { + this.released(); + }); + this.on('aborted', function() { + this.released(); + }) + this.on('message', function(pdvs) { + this.receivedMessage(pdvs); + }); +}; +util.inherits(CSocket, EventEmitter); + +CSocket.prototype.setCallingAE = function(ae) { + this.callingAe = ae; +}; + +CSocket.prototype.setCalledAe = function(ae) { + this.calledAe = ae; +}; + +CSocket.prototype.associate = function() { + var associateRQ = new AssociateRQ(); + associateRQ.setCalledAETitle(this.calledAe); + associateRQ.setCallingAETitle(this.callingAe); + associateRQ.setApplicationContextItem(new ApplicationContextItem()); + + var contextItems = [] + this.presentationContexts.forEach(function(context) { + var contextItem = new PresentationContextItem(), + syntaxes = []; + context.transferSyntaxes.forEach(function(transferSyntax) { + var transfer = new TransferSyntaxItem(); + transfer.setTransferSyntaxName(transferSyntax); + syntaxes.push(transfer); + }); + contextItem.setTransferSyntaxesItems(syntaxes); + contextItem.setPresentationContextID(context.id); + + var abstractItem = new AbstractSyntaxItem(); + abstractItem.setAbstractSyntaxName(context.abstractSyntax); + contextItem.setAbstractSyntaxItem(abstractItem); + contextItems.push(contextItem); + }); + associateRQ.setPresentationContextItems(contextItems); + + var maxLengthItem = new MaximumLengthItem(), + classUIDItem = new ImplementationClassUIDItem(), + versionItem = new ImplementationVersionNameItem(); + + classUIDItem.setImplementationClassUID(C.IMPLEM_UID); + versionItem.setImplementationVersionName(C.IMPLEM_VERSION); + var packageSize = this.options.maxPackageSize ? this.options.maxPackageSize : C.DEFAULT_MAX_PACKAGE_SIZE; + maxLengthItem.setMaximumLengthReceived(packageSize); + + var userInfo = new UserInformationItem(); + userInfo.setUserDataItems([maxLengthItem, classUIDItem, versionItem]); + + associateRQ.setUserInformationItem(userInfo); + + this.send(associateRQ); +}; + +CSocket.prototype.getContext = function(id) { + for (var k in this.presentationContexts) { + var ctx = this.presentationContexts[k]; + if (id == ctx.id) return ctx; + } + return null; +} + +CSocket.prototype.getSyntax = function(contextId) { + if (!this.negotiatedContexts[contextId]) return null; + + return this.negotiatedContexts[contextId].transferSyntax; +} + +CSocket.prototype.getContextByUID = function(uid) { + for (var k in this.negotiatedContexts) { + var ctx = this.negotiatedContexts[k]; + if (ctx.abstractSyntax == uid) { + return ctx; + } + } + return null; +} + +CSocket.prototype.getContextId = function(contextId) { + if (!this.negotiatedContexts[contextId]) return null; + + return this.negotiatedContexts[contextId].id; +} + +CSocket.prototype.setPresentationContexts = function(uids) { + var contexts = [], + id = 0; + uids.forEach(function(uid) { + contexts.push({ + id: ++id, + abstractSyntax: uid, + transferSyntaxes: [C.IMPLICIT_LITTLE_ENDIAN, C.EXPLICIT_LITTLE_ENDIAN, C.EXPLICIT_BIG_ENDIAN] + }); + }); + this.presentationContexts = contexts; +}; + +CSocket.prototype.newMessageId = function() { + return (++this.messageIdCounter) % 65536; +} + +CSocket.prototype.resetReceive = function() { + this.receiving = this.receiveLength = null; +}; + +CSocket.prototype.send = function(pdu, afterCbk) { + //console.log('SEND PDU-TYPE: ', pdu.type); + var toSend = pdu.buffer(); + //console.log('send buffer', toSend.toString('hex')); + this.socket.write(toSend, afterCbk ? afterCbk : function() { + //console.log('Data written'); + }); +}; + +CSocket.prototype.release = function() { + var releaseRQ = new ReleaseRQ(); + this.send(releaseRQ); +}; + +CSocket.prototype.released = function() { + this.socket.end(); +}; + +CSocket.prototype.ready = function() { + console.log("Connection established"); + this.connected = true; + this.started = time(); + + var o = this; + if (this.options.idle) { + this.intervalId = setInterval(function() { + o.checkIdle(); + }, 3000); + } +}; + +CSocket.prototype.checkIdle = function() { + var current = time(), + idl = this.options.idle; + + if (!this.lastReceived && (current - this.started >= idl)) { + this.idleClose(); + } else if (this.lastReceived && (current - this.lastReceived >= idl)) { + this.idleClose(); + } else { + //console.log('keep idling') + } +}; + +CSocket.prototype.idleClose = function() { + console.log('Exceed idle time, closing connection'); + this.release(); +}; + +CSocket.prototype.received = function(data) { + var i = 0; + do { + data = this.process(data); + } while (data !== null); + this.lastReceived = time(); +}; + +CSocket.prototype.process = function(data) { + //console.log("Data received"); + if (this.receiving === null) { + if (this.minRecv) { + data = Buffer.concat([this.minRecv, data], this.minRecv.length + data.length); + this.minRecv = null; + } + + if (data.length < 6) { + this.minRecv = data; + return null; + } + + var stream = new ReadStream(data); + var type = stream.read(C.TYPE_UINT8); + stream.increment(1); + var len = stream.read(C.TYPE_UINT32), + cmp = data.length - 6; + if (len > cmp) { + this.receiving = data; + this.receiveLength = len; + } else { + var process = data, + remaining = null; + if (len < cmp) { + process = data.slice(0, len + 6); + remaining = data.slice(len + 6, cmp + 6); + } + this.resetReceive(); + this.interpret(new ReadStream(process), this); + if (remaining) { + return remaining; + } + } + } else { + var newData = Buffer.concat([this.receiving, data], this.receiving.length + data.length), + pduLength = newData.length - 6; + + if (pduLength < this.receiveLength) { + this.receiving = newData; + } else { + var remaining = null; + if (pduLength > this.receiveLength) { + remaining = newData.slice(this.receiveLength + 6, pduLength + 6); + newData = newData.slice(0, this.receiveLength + 6); + } + this.resetReceive(); + this.interpret(new ReadStream(newData)); + if (remaining) { + return remaining; + } + } + } + return null; +}; + +CSocket.prototype.interpret = function(stream) { + var pdatas = [], + size = stream.size(), + o = this; + while (stream.offset < size) { + var pdu = PDU.createByStream(stream); + //console.log("Received PDU-TYPE " + PDU.typeToString(pdu.type)); + if (pdu.is(C.ITEM_TYPE_PDU_ASSOCIATE_AC)) { + pdu.presentationContextItems.forEach(function(ctx) { + var requested = o.getContext(ctx.presentationContextID); + if (!requested) { + throw "Accepted presentation context not found"; + } + o.negotiatedContexts[ctx.presentationContextID] = { + id: ctx.presentationContextID, + transferSyntax: ctx.transferSyntaxesItems[0].transferSyntaxName, + abstractSyntax: requested.abstractSyntax + }; + }); + + //console.log('Accepted'); + this.associated = true; + this.emit('associated', pdu); + } else if (pdu.is(C.ITEM_TYPE_PDU_ASSOCIATE_RQ)) { + var accepd = new AssociateAC(); + + pdu.presentationContextItems.forEach(function(ctx) { + + }); + } else if (pdu.is(C.ITEM_TYPE_PDU_RELEASE_RP)) { + //console.log('Released'); + this.associated = false; + this.emit('released'); + } else if (pdu.is(C.ITEM_TYPE_PDU_AABORT)) { + //console.log('Aborted'); + this.emit('aborted'); + } else if (pdu.is(C.ITEM_TYPE_PDU_PDATA)) { + pdatas.push(pdu); + } + } + + if (pdatas) { + var pdvs = this.pendingPDVs ? this.pendingPDVs : []; + pdatas.forEach(function(pdata) { + pdvs = pdvs.concat(pdata.presentationDataValueItems); + }); + this.pendingPDVs = null; + var i = 0, + count = pdvs.length; + while (i < count) { + if (!pdvs[i].isLast) { + var j = i + 1; + while (j < count) { + pdvs[i].messageStream.concat(pdvs[j].messageStream); + if (pdvs[j++].isLast) { + pdvs[i].isLast = true; + break; + } + } + if (pdvs[i].isLast) { + this.emit('message', pdvs[i]); + } else { + this.pendingPDVs = [pdvs[i]]; + } + i = j; + } else { + this.emit('message', pdvs[i++]); + } + } + } +}; + +CSocket.prototype.receivedMessage = function(pdv) { + var syntax = this.getSyntax(pdv.contextId), + msg = DicomMessage.read(pdv.messageStream, pdv.type, syntax, this.options.vr); + + if (msg.isCommand()) { + this.lastCommand = msg; + + if (msg.isResponse()) { + if (msg.is(C.COMMAND_C_GET_RSP) || msg.is(C.COMMAND_C_MOVE_RSP)) { + //console.log('remaining', msg.getNumOfRemainingSubOperations(), msg.getNumOfCompletedSubOperations()); + } + if (msg.failure()) { + //console.log("message failed with status ", msg.getStatus().toString(16)); + } + if (msg.isFinal()) { + var replyId = msg.respondedTo(); + if (this.messages[replyId].listener) { + this.messages[replyId].listener.emit('end', msg); + + if (!msg.haveData()) + delete this.messages[replyId]; + } + + if (msg.is(C.COMMAND_C_GET_RSP)) { + if (!msg.getNumOfRemainingSubOperations()) { + if (this.lastGets && this.lastGets.length > 0) this.lastGets.shift(); + } + } + } + } else { + /*if (msg.is(0x01)) { + console.log('ae title ', msg.getValue(0x00001031)) + }*/ + } + + } else { + if (!this.lastCommand) { + throw "Only dataset?"; + } else if (!this.lastCommand.haveData()) { + throw "Last command didn't indicate presence of data"; + } + + if (this.lastCommand.isResponse()) { + var replyId = this.lastCommand.respondedTo(); + if (this.messages[replyId].listener) { + var flag = this.lastCommand.failure() ? true : false; + + this.messages[replyId].listener.emit("result", msg, flag); + + if (this.lastCommand.failure()) { + delete this.messages[replyId]; + } + } + } else { + if (this.lastCommand.is(C.COMMAND_C_STORE_RQ)) { + var moveMessageId = this.lastCommand.getMoveMessageId(), + useId = moveMessageId; + if (!moveMessageId) { + //!! Going to deprecate now + //kinda hacky but we know this c-store is came from a c-get + if (this.lastGets.length > 0) { + useId = this.lastGets[0]; + } else { + throw "Where does this c-store came from?"; + } + } else console.log('move ', moveMessageId); + //this.storeResponse(useId, msg); + } + } + } +}; + +CSocket.prototype.wrapToPData = function(message, context) { + var useContext = message.contextUID ? message.contextUID : context; + var ctx = this.getContextByUID(useContext); + + var pdata = new PDataTF(), + pdv = new PresentationDataValueItem(ctx.id); + pdv.setMessage(message); + pdata.setPresentationDataValueItems([pdv]); + return pdata; +} + +CSocket.prototype.sendMessage = function(context, command, dataset) { + var nContext = this.getContextByUID(context), + syntax = nContext.transferSyntax, + cid = nContext.id, + messageId = this.newMessageId(), + msgData = {}; + + msgData.listener = new Envelope(command); + + var o = this; + msgData.listener.on('cancel', function(){ + var cancelMessage = null; + if (this.command.is(C.COMMAND_C_FIND_RQ) || this.command.is(C.COMMAND_C_MOVE_RQ)) { + cancelMessage = new CCancelRQ(); + + cancelMessage.setReplyMessageId(this.command.messageId); + cancelMessage.setSyntax(C.IMPLICIT_LITTLE_ENDIAN); + + o.send(o.wrapToPData(cancelMessage, this.command.contextUID)); + } + }); + + command.setSyntax(C.IMPLICIT_LITTLE_ENDIAN); + command.setContextId(context); + command.setMessageId(messageId); + if (dataset) + command.setDataSetPresent(C.DATA_SET_PRESENT); + + this.lastSent = command; + if (command.is(C.COMMAND_C_GET_RQ)) { + this.lastGets.push(messageId); + } + var pdata = this.wrapToPData(command); + + msgData.command = command; + this.messages[messageId] = msgData; + + this.send(pdata); + if (dataset) { + dataset.setSyntax(syntax); + var dsData = new PDataTF(), + dPdv = new PresentationDataValueItem(cid); + + dPdv.setMessage(dataset); + dsData.setPresentationDataValueItems([dPdv]); + this.send(dsData); + } + return msgData.listener; +}; + +CSocket.prototype.verify = function() { + this.setPresentationContexts([C.SOP_VERIFICATION]); + this.startAssociationRequest(function() { + //associated, we can release now + this.release(); + }); +}; + +CSocket.prototype.wrapMessage = function(data) { + if (data) { + var datasetMessage = new DataSetMessage(); + datasetMessage.setElements(data); + return datasetMessage; + } else return data; +}; + +CSocket.prototype.find = function(params, options) { + return this.sendMessage(options.context, new CFindRQ(), this.wrapMessage(params)); +}; + +CSocket.prototype.move = function(destination, params, options) { + var moveMessage = new CMoveRQ(); + moveMessage.setDestination(destination); + + return this.sendMessage(options.context, moveMessage, this.wrapMessage(params)); +}; + +CSocket.prototype.moveInstances = function(destination, params, options) { + var sendParams = Object.assign({ + 0x00080052: C.QUERY_RETRIEVE_LEVEL_IMAGE, + }, params); + options = Object.assign({ + context : C.SOP_STUDY_ROOT_MOVE + }, options); + + return this.move(destination, sendParams, options); +}; + +CSocket.prototype.findPatients = function(params, options) { + var sendParams = Object.assign({ + 0x00080052: C.QUERY_RETRIEVE_LEVEL_PATIENT, + 0x00100010: "", + 0x00100020: "", + 0x00100030: "", + 0x00100040: "", + }, params); + options = Object.assign({ + context : C.SOP_PATIENT_ROOT_FIND + }, options); + + return this.find(sendParams, options); +}; + +CSocket.prototype.findStudies = function(params, options) { + var sendParams = Object.assign({ + 0x00080052: C.QUERY_RETRIEVE_LEVEL_STUDY, + 0x00080020: "", + 0x00100010: "", + 0x00080061: "", + 0x0020000D: "" + }, params); + options = Object.assign({ + context : C.SOP_STUDY_ROOT_FIND + }, options); + + return this.find(sendParams, options); +}; + +CSocket.prototype.findSeries = function(params, options) { + var sendParams = Object.assign({ + 0x00080052: C.QUERY_RETRIEVE_LEVEL_SERIES, + 0x00080020: "", + 0x0020000E: "", + 0x0008103E: "", + 0x0020000D: "" + }, params); + options = Object.assign({ + context : C.SOP_STUDY_ROOT_FIND + }, options); + + return this.find(sendParams, options); +}; + +CSocket.prototype.findInstances = function(params, options) { + var sendParams = Object.assign({ + 0x00080052: C.QUERY_RETRIEVE_LEVEL_IMAGE, + 0x00080020: "", + 0x0020000E: "", + 0x0008103E: "", + 0x0020000D: "" + }, params); + options = Object.assign({ + context : C.SOP_STUDY_ROOT_FIND + }, options); + + return this.find(sendParams, options); +}; \ No newline at end of file diff --git a/Packages/dimseservice/server/Connection.js b/Packages/dimseservice/server/Connection.js index 35fb86b54..ba988cd05 100755 --- a/Packages/dimseservice/server/Connection.js +++ b/Packages/dimseservice/server/Connection.js @@ -1,461 +1,69 @@ -var EventEmitter = Npm.require('events').EventEmitter; - -function time() { - return Math.floor(Date.now() / 1000); -} +var EventEmitter = Npm.require('events').EventEmitter, net = Npm.require('net'), Socket = net.Socket; var DEFAULT_MAX_PACKAGE_SIZE = 32768; -var DEFAULT_SOURCE_AE = 'OHIFDCM'; -var Envelope = function(conn, command, dataset) { +Connection = function(options) { EventEmitter.call(this); - this.command = command; - this.dataset = dataset; - this.conn = conn; -}; - -util.inherits(Envelope, EventEmitter); - -Envelope.prototype.send = function() { - return this; -}; - -Connection = function(socket, options) { - EventEmitter.call(this); - this.socket = socket; this.options = Object.assign({ - hostAE: '', - sourceAE: 'OHIFDCM', - maxPackageSize: 32768, - idle: 60, + maxPackageSize: C.DEFAULT_MAX_PACKAGE_SIZE, + idle: false, reconnect: true, vr: { split: true } }, options); - this.connected = false; - this.started = null; - this.lastReceived = null; - this.associated = false; - this.receiving = null; - this.receiveLength = null; - this.minRecv = null; - this.pendingPDVs = null; - this.server = null; - //this.retrieveModel = RETRIEVE_MODEL_STUDY_ROOT; - this.presentationContexts = []; - this.transferSyntaxes = []; - this.negotiatedContexts = {}; - this.messages = {}; - this.messageIdCounter = 0; - this.services = []; - this.lastCommand = null; - this.lastSent = null; - this.lastGets = []; - this.findContext = C.SOP_STUDY_ROOT_FIND; - - //register hooks - var o = this; - this.socket.on('data', function(data) { - o.received(data); - }); - this.socket.on('close', function(he) { - o.closed(he); - o.emit('close', he); - }); - this.socket.on('error', function(he) { - o.error(he); - }); - this.socket.on('end', function() { - if (o.intervalId) { - clearInterval(o.intervalId); - } - - if (o.server) { - console.log('Closing server'); - o.server.close(); - } - - console.log('ended'); - }); - this.on('released', function() { - this.released(); - }); - this.on('aborted', function() { - this.released(); - }); - this.on('message', function(pdvs) { - this.receivedMessage(pdvs); - }); - this.on('init', this.ready); - - //this.pause(); - if (this.options.listenHost && this.options.listenPort) { - this.server = net.createServer(); - this.server.listen(this.options.listenPort, this.options.listenHost); - this.server.on('listening', function() { - console.log('listening on %j', this.address()); - }); - this.server.on('connection', function(socket) { - - }); - } - - this.emit('init'); -}; + this.peers = {}; + this.peerSockets = {}; + this.defaultPeer = null; + this.defaultServer = null; +} util.inherits(Connection, EventEmitter); -Connection.prototype.checkIdle = function() { - var current = time(), - idl = this.options.idle; - if (!this.lastReceived && (current - this.started >= idl)) { - this.idleClose(); - } else if (this.lastReceived && (current - this.lastReceived >= idl)) { - this.idleClose(); +Connection.prototype.addPeer = function(options) { + if (!options.aeTitle || !options.host || !options.port) { + return false; + } + this.peers[options.aeTitle] = { + host : options.host, port : options.port + }; + if (options.default) { + if (options.server) { + this.defaultServer = options.aeTitle; } else { - //console.log('keep idling') + this.defaultPeer = options.aeTitle; } -}; - -Connection.prototype.released = function() { - this.socket.end(); -}; - -Connection.prototype.idleClose = function() { - console.log('Exceed idle time, closing connection'); - this.release(); -}; - -Connection.prototype.getSoureceAE = function() { - return this.options.sourceAE; -}; - -Connection.prototype.ready = function() { - console.log('Connection established'); - this.connected = true; - this.started = time(); - + } + if (options.server) { + //start listening + var server = net.createServer(); + server.listen(options.port, options.host, function(){ + console.log("listening on %j", this.address()); + }); + server.on('error', function(err){ + console.log("server error %j", err); + }); var o = this; - this.intervalId = setInterval(function() { - o.checkIdle(); - }, 3000); + server.on('connection', function(nativeSocket) { + //incoming connections + var socket = new CSocket(nativeSocket, o.options); + o.addSocket(options.aeTitle, socket); - //this.emit("init"); - //this.startAssociationRequest(); -}; - -Connection.prototype.resetReceive = function() { - this.receiving = this.receiveLength = null; -}; - -Connection.prototype.received = function(data) { - var i = 0; - do { - data = this.process(data); - } while (data !== null); - this.lastReceived = time(); -}; - -Connection.prototype.process = function(data) { - //console.log("Data received"); - if (this.receiving === null) { - if (this.minRecv) { - data = Buffer.concat([ this.minRecv, data ], this.minRecv.length + data.length); - this.minRecv = null; - } - - if (data.length < 6) { - this.minRecv = data; - return null; - } - - var stream = new ReadStream(data); - var type = stream.read(C.TYPE_UINT8); - stream.increment(1); - var len = stream.read(C.TYPE_UINT32), - cmp = data.length - 6; - if (len > cmp) { - this.receiving = data; - this.receiveLength = len; - } else { - var process = data, - remaining = null; - if (len < cmp) { - process = data.slice(0, len + 6); - remaining = data.slice(len + 6, cmp + 6); - } - - this.resetReceive(); - this.interpret(new ReadStream(process)); - if (remaining) { - return remaining; - } - } - } else { - var newData = Buffer.concat([ this.receiving, data ], this.receiving.length + data.length), - pduLength = newData.length - 6; - - if (pduLength < this.receiveLength) { - this.receiving = newData; - } else { - var remaining = null; - if (pduLength > this.receiveLength) { - remaining = newData.slice(this.receiveLength + 6, pduLength + 6); - newData = newData.slice(0, this.receiveLength + 6); - } - - this.resetReceive(); - this.interpret(new ReadStream(newData)); - if (remaining) { - return remaining; - } - } - } - - return null; -}; - -Connection.prototype.interpret = function(stream) { - var pdatas = [], - size = stream.size(), - o = this; - while (stream.offset < size) { - var pdu = pduByStream(stream); - //console.log("Received PDU-TYPE " + pdu.type); - if (pdu.is(C.ITEM_TYPE_PDU_ASSOCIATE_AC)) { - pdu.presentationContextItems.forEach(function(ctx) { - var requested = o.getContext(ctx.presentationContextID); - if (!requested) { - throw 'Accepted presentation context not found'; - } - - o.negotiatedContexts[ctx.presentationContextID] = { - id: ctx.presentationContextID, - transferSyntax: ctx.transferSyntaxesItems[0].transferSyntaxName, - abstractSyntax: requested.abstractSyntax - }; - - var notfound = false; - o.services.forEach(function(service) { - if (service.contextUID == requested.abstractSyntax) { - service.contextID = ctx.presentationContextID; - } - }); - }); - - //console.log('Accepted'); - this.associated = true; - this.emit('associated', pdu); - } else if (pdu.is(C.ITEM_TYPE_PDU_RELEASE_RP)) { - //console.log('Released'); - this.associated = false; - this.emit('released'); - } else if (pdu.is(C.ITEM_TYPE_PDU_AABORT)) { - //console.log('Aborted'); - this.emit('aborted'); - } else if (pdu.is(C.ITEM_TYPE_PDU_PDATA)) { - pdatas.push(pdu); - } - } - - if (pdatas) { - var pdvs = this.pendingPDVs ? this.pendingPDVs : []; - pdatas.forEach(function(pdata) { - pdvs = pdvs.concat(pdata.presentationDataValueItems); - }); - this.pendingPDVs = null; - var i = 0, - count = pdvs.length; - while (i < count) { - if (!pdvs[i].isLast) { - var j = i + 1; - while (j < count) { - pdvs[i].messageStream.concat(pdvs[j].messageStream); - if (pdvs[j++].isLast) { - pdvs[i].isLast = true; - break; - } - } - - if (pdvs[i].isLast) { - this.emit('message', pdvs[i]); - } else { - this.pendingPDVs = [ pdvs[i] ]; - } - - i = j; - } else { - this.emit('message', pdvs[i++]); - } - } - } - - //this.release(); -}; - -Connection.prototype.newMessageId = function() { - return (++this.messageIdCounter) % 255; -}; - -Connection.prototype.closed = function(had_error) { - this.connected = false; - console.log('Connection closed', had_error); - //this.destroy(); -}; - -Connection.prototype.error = function(err) { - console.log('Error: ', err); -}; - -Connection.prototype.send = function(pdu, afterCbk) { - //console.log('SEND PDU-TYPE: ', pdu.type); - var toSend = pdu.buffer(); - //console.log('send buffer', toSend.toString('hex')); - this.socket.write(toSend, afterCbk ? afterCbk : function() { - //console.log('Data written'); - }); -}; - -Connection.prototype.getSyntax = function(contextId) { - if (!this.negotiatedContexts[contextId]) return null; - - return this.negotiatedContexts[contextId].transferSyntax; -}; - -Connection.prototype.getContextByUID = function(uid) { - for (var k in this.negotiatedContexts) { - var ctx = this.negotiatedContexts[k]; - if (ctx.abstractSyntax == uid) { - return ctx; - } - } - - return null; -}; - -Connection.prototype.getContextId = function(contextId) { - if (!this.negotiatedContexts[contextId]) return null; - - return this.negotiatedContexts[contextId].id; -}; - -Connection.prototype.getContext = function(id) { - for (var k in this.presentationContexts) { - var ctx = this.presentationContexts[k]; - if (id == ctx.id) return ctx; - } - - return null; -}; - -Connection.prototype.setPresentationContexts = function(uids) { - var contexts = [], - id = 0; - uids.forEach(function(uid) { - contexts.push({ - id: ++id, - abstractSyntax: uid, - transferSyntaxes: [ C.IMPLICIT_LITTLE_ENDIAN, C.EXPLICIT_LITTLE_ENDIAN, C.EXPLICIT_BIG_ENDIAN ] + //close server on close socket + socket.on('close', function(){ + server.close(); }); }); - this.presentationContexts = contexts; + } }; -Connection.prototype.verify = function() { - this.setPresentationContexts([ C.SOP_VERIFICATION ]); - this.startAssociationRequest(function() { - //associated, we can release now - this.release(); - }); -}; - -Connection.prototype.release = function() { - var releaseRQ = new ReleaseRQ(); - this.send(releaseRQ); -}; - -Connection.prototype.addService = function(service) { - service.setConnection(this); - this.services.push(service); -}; - -Connection.prototype.receivedMessage = function(pdv) { - var syntax = this.getSyntax(pdv.contextId), - msg = readMessage(pdv.messageStream, pdv.type, syntax, this.options.vr); - - if (msg.isCommand()) { - this.lastCommand = msg; - - if (msg.isResponse()) { - if (msg.is(C.COMMAND_C_GET_RSP) || msg.is(C.COMMAND_C_MOVE_RSP)) { - //console.log('remaining', msg.getNumOfRemainingSubOperations(), msg.getNumOfCompletedSubOperations()); - } - - if (msg.failure()) { - //console.log("message failed with status ", msg.getStatus().toString(16)); - } - - if (msg.isFinal()) { - var replyId = msg.respondedTo(); - if (this.messages[replyId].listener) { - this.messages[replyId].listener.emit('end', msg); - /*if (this.messages[replyId].listener[1]) { - this.messages[replyId].listener[1].call(this, msg); - }*/ - if (!msg.haveData()) - delete this.messages[replyId]; - } - - if (msg.is(C.COMMAND_C_GET_RSP)) { - if (!msg.getNumOfRemainingSubOperations()) { - if (this.lastGets && this.lastGets.length > 0) this.lastGets.shift(); - } - } - } - } else { - /*if (msg.is(0x01)) { - console.log('ae title ', msg.getValue(0x00001031)) - }*/ - } - - } else { - if (!this.lastCommand) { - throw 'Only dataset?'; - } else if (!this.lastCommand.haveData()) { - throw "Last command didn't indicate presence of data"; - } - - if (this.lastCommand.isResponse()) { - var replyId = this.lastCommand.respondedTo(); - if (this.messages[replyId].listener) { - var flag = this.lastCommand.failure() ? true : false; - - this.messages[replyId].listener.emit('result', msg, flag); - - if (this.lastCommand.failure()) { - delete this.messages[replyId]; - } - } - } else { - if (this.lastCommand.is(C.COMMAND_C_STORE_RQ)) { - var moveMessageId = this.lastCommand.getMoveMessageId(), - useId = moveMessageId; - if (!moveMessageId) { - //!! Going to deprecate now - //kinda hacky but we know this c-store is came from a c-get - if (this.lastGets.length > 0) { - useId = this.lastGets[0]; - } else { - throw 'Where does this c-store came from?'; - } - } else console.log('move ', moveMessageId); - //this.storeResponse(useId, msg); - } - } +Connection.prototype.selectPeer = function(aeTitle) { + if (!aeTitle || !this.peers[aeTitle]) { + throw "No such peer"; } -}; + return this.peers[aeTitle]; +} Connection.prototype.storeResponse = function(messageId, msg) { var rq = this.messages[messageId]; @@ -470,183 +78,62 @@ Connection.prototype.storeResponse = function(messageId, msg) { replyMessage.setReplyMessageId(this.lastCommand.messageId); this.sendMessage(replyMessage, null, null, storeSr); } else { - throw 'Missing store status'; + throw "Missing store status"; } } }; -Connection.prototype.sendMessage = function(context, command, dataset, listener) { - var nContext = this.getContextByUID(context), - syntax = nContext.transferSyntax, - cid = nContext.id, - messageId = this.newMessageId(), - msgData = {}; - - /*if (listener) { - if (typeof listener != 'object') { - listener = [listener, null]; +Connection.prototype.allClosed = function() { + var allClosed = true; + for (var i in o.peerSockets) { + if (Object.keys(o.peerSockets[ae]).length > 0) { + allClosed = false; + break; + } } - msgData.listener = listener; - }*/ - msgData.listener = new Envelope(); + return allClosed; +}; - var pdata = new PDataTF(), - pdv = new PresentationDataValueItem(cid); - - command.setSyntax(C.IMPLICIT_LITTLE_ENDIAN); - command.setContextId(context); - command.setMessageId(messageId); - if (dataset) - command.setDataSetPresent(C.DATA_SET_PRESENT); - - this.lastSent = command; - if (command.is(C.COMMAND_C_GET_RQ)) { - this.lastGets.push(messageId); +Connection.prototype.addSocket = function(ae, socket) { + if (!this.peerSockets[ae]) { + this.peerSockets[ae] = {}; } + this.peerSockets[ae][socket.id] = socket; - pdv.setMessage(command); - pdata.setPresentationDataValueItems([ pdv ]); - - msgData.command = command; - this.messages[messageId] = msgData; - - /*var stream = new ReadStream(pdata.buffer()), np = pduByStream(stream), pdv = np.presentationDataValueItems[0]; - var msg = readMessage(pdv.messageStream, pdv.type, C.IMPLICIT_LITTLE_ENDIAN); - console.log(msg.isCommand()); - return;*/ - - this.send(pdata); - if (dataset) { - dataset.setSyntax(syntax); - var dsData = new PDataTF(), - dPdv = new PresentationDataValueItem(cid); - - dPdv.setMessage(dataset); - dsData.setPresentationDataValueItems([ dPdv ]); - this.send(dsData); - } - - return msgData.listener; + var o = this; + socket.on("close", function() { + if (o.peerSockets[ae][this.id]) { + delete o.peerSockets[ae][this.id]; + } + }); }; Connection.prototype.associate = function(options, callback) { + var hostAE = options.hostAE ? options.hostAE : this.defaultPeer, + sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer; + peerInfo = this.selectPeer(hostAE), nativeSocket = new Socket(); + + var socket = new CSocket(nativeSocket, this.options), o = this; if (callback) { - this.once('associated', callback); + socket.once('associated', callback); } + socket.setCalledAe(hostAE); + socket.setCallingAE(sourceAE); - if (this.associated) { - this.emit('associated'); - return; - } + nativeSocket.connect({ + host : peerInfo.host, port : peerInfo.port + }, function(){ + //connected + o.addSocket(hostAE, socket); - if (options.contexts) { - this.setPresentationContexts(options.contexts); - } else { - throw 'No services attached'; - } + if (options.contexts) { + socket.setPresentationContexts(options.contexts); + } else { + throw "Contexts must be specified"; + } - var associateRQ = new AssociateRQ(); - associateRQ.setCalledAETitle(options.hostAE); - var sourceAE = options.sourceAE ? options.sourceAE : DEFAULT_SOURCE_AE; - associateRQ.setCallingAETitle(sourceAE); - associateRQ.setApplicationContextItem(new ApplicationContextItem()); - - var contextItems = []; - this.presentationContexts.forEach(function(context) { - var contextItem = new PresentationContextItem(), - syntaxes = []; - context.transferSyntaxes.forEach(function(transferSyntax) { - var transfer = new TransferSyntaxItem(); - transfer.setTransferSyntaxName(transferSyntax); - syntaxes.push(transfer); - }); - contextItem.setTransferSyntaxesItems(syntaxes); - contextItem.setPresentationContextID(context.id); - - var abstractItem = new AbstractSyntaxItem(); - abstractItem.setAbstractSyntaxName(context.abstractSyntax); - contextItem.setAbstractSyntaxItem(abstractItem); - contextItems.push(contextItem); + socket.associate(); }); - associateRQ.setPresentationContextItems(contextItems); - var maxLengthItem = new MaximumLengthItem(), - classUIDItem = new ImplementationClassUIDItem(), - versionItem = new ImplementationVersionNameItem(); - - classUIDItem.setImplementationClassUID(C.IMPLEM_UID); - versionItem.setImplementationVersionName(C.IMPLEM_VERSION); - var packageSize = options.maxPackageSize ? options.maxPackageSize : DEFAULT_MAX_PACKAGE_SIZE; - maxLengthItem.setMaximumLengthReceived(packageSize); - - var userInfo = new UserInformationItem(); - userInfo.setUserDataItems([ maxLengthItem, classUIDItem, versionItem ]); - - associateRQ.setUserInformationItem(userInfo); - - this.send(associateRQ); -}; - -Connection.prototype.wrapMessage = function(data) { - if (data) { - var datasetMessage = new DataSetMessage(); - datasetMessage.setElements(data); - return datasetMessage; - } else return data; -}; - -Connection.prototype.setFindContext = function(ctx) { - this.findContext = ctx; -}; - -Connection.prototype.find = function(params, callback) { - return this.sendMessage(this.findContext, new CFindRQ(), this.wrapMessage(params), callback); -}; - -Connection.prototype.findPatients = function(params, callback) { - var sendParams = Object.assign({ - 0x00080052: C.QUERY_RETRIEVE_LEVEL_PATIENT, - 0x00100010: '', - 0x00100020: '', - 0x00100030: '', - 0x00100040: '', - }, params); - - return this.find(sendParams, callback); -}; - -Connection.prototype.findStudies = function(params, callback) { - var sendParams = Object.assign({ - 0x00080052: C.QUERY_RETRIEVE_LEVEL_STUDY, - 0x00080020: '', - 0x00100010: '', - 0x00080061: '', - 0x0020000D: '' - }, params); - - return this.find(sendParams, callback); -}; - -Connection.prototype.findSeries = function(params, callback) { - var sendParams = Object.assign({ - 0x00080052: C.QUERY_RETRIEVE_LEVEL_SERIES, - 0x00080020: '', - 0x0020000E: '', - 0x0008103E: '', - 0x0020000D: '' - }, params); - - return this.find(sendParams, callback); -}; - -Connection.prototype.findInstances = function(params, callback) { - var sendParams = Object.assign({ - 0x00080052: C.QUERY_RETRIEVE_LEVEL_IMAGE, - 0x00080020: '', - 0x0020000E: '', - 0x0008103E: '', - 0x0020000D: '' - }, params); - - return this.find(sendParams, callback); -}; + return socket; +}; \ No newline at end of file diff --git a/Packages/dimseservice/server/DIMSE.js b/Packages/dimseservice/server/DIMSE.js index fcc4671af..bcb9ca157 100755 --- a/Packages/dimseservice/server/DIMSE.js +++ b/Packages/dimseservice/server/DIMSE.js @@ -1,61 +1,43 @@ -var net = Npm.require('net'), - Future = Npm.require('fibers/future'); +var Future = Npm.require('fibers/future'); DIMSE = {}; +var conn = new Connection({ + vr: { + split: false + } +}); + +Meteor.startup(function(){ + var peers = Meteor.settings.dimse; + peers.forEach(function(peer){ + conn.addPeer(peer); + }); +}); + DIMSE.associate = function(contexts, callback) { - var host = Meteor.settings.dimse.host, - port = Meteor.settings.dimse.port, - ae = Meteor.settings.dimse.hostAE; - - console.log("Associating via DIMSE"); - console.log(Meteor.settings.dimse); - - var client = net.connect({ - host: host, - port: port - }); - - client.on('connect', function() { - //'connect' listener - console.log('==Connected'); - - var conn = new Connection(client, { - vr: { - split: false - } - }); - - conn.associate({ - contexts: contexts, - hostAE: ae - }, function(pdu) { - // associated - console.log('==Associated'); - - callback.call(conn, pdu); - }); - }); - - client.on('error', function(error) { - throw error; + conn.associate({ + contexts: contexts + }, function(pdu) { + // associated + console.log('==Associated'); + callback.call(this, pdu); }); }; DIMSE.retrievePatients = function(params) { //var start = new Date(); var future = new Future; - DIMSE.associate([ C.SOP_PATIENT_ROOT_FIND ], function(pdu) { + DIMSE.associate([C.SOP_PATIENT_ROOT_FIND], function(pdu) { var defaultParams = { - 0x00100010: '', - 0x00100020: '', - 0x00100030: '', - 0x00100040: '', - 0x00101010: '', - 0x00101040: '' + 0x00100010: "", + 0x00100020: "", + 0x00100030: "", + 0x00100040: "", + 0x00101010: "", + 0x00101040: "" }; - this.setFindContext(C.SOP_PATIENT_ROOT_FIND); var result = this.findPatients(Object.assign(defaultParams, params)), o = this; @@ -76,30 +58,32 @@ DIMSE.retrievePatients = function(params) { return future.wait(); }; -DIMSE.retrieveStudies = function(params) { +DIMSE.retrieveStudies = function(params, options) { //var start = new Date(); - var future = new Future; - DIMSE.associate([ C.SOP_STUDY_ROOT_FIND ], function(pdu) { + var future = new Future, options = Object.assign({limit : 100}, options); + DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(pdu) { var defaultParams = { - 0x0020000D: '', - 0x00080060: '', - 0x00080005: '', - 0x00080020: '', - 0x00080030: '', - 0x00080090: '', - 0x00100010: '', - 0x00100020: '', - 0x00200010: '', - 0x00100030: '' + 0x0020000D: "", + 0x00080060: "", + 0x00080005: "", + 0x00080020: "", + 0x00080030: "", + 0x00080090: "", + 0x00100010: "", + 0x00100020: "", + 0x00200010: "", + 0x00100030: "" }; - this.setFindContext(C.SOP_STUDY_ROOT_FIND); var result = this.findStudies(Object.assign(defaultParams, params)), o = this; var studies = []; result.on('result', function(msg) { studies.push(msg); + if (options.limit && options.limit == studies.length) { + result.emit('cancel'); + } }); result.on('end', function() { @@ -116,22 +100,21 @@ DIMSE.retrieveStudies = function(params) { DIMSE.retrieveSeries = function(studyInstanceUID, params) { var future = new Future; - DIMSE.associate([ C.SOP_STUDY_ROOT_FIND ], function(pdu) { + DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(pdu) { var defaultParams = { - 0x0020000D: studyInstanceUID ? studyInstanceUID : '', - 0x00080005: '', - 0x00080020: '', - 0x00080030: '', - 0x00080090: '', - 0x00100010: '', - 0x00100020: '', - 0x00200010: '', - 0x0008103E: '', - 0x0020000E: '', - 0x00200011: '' + 0x0020000D: studyInstanceUID ? studyInstanceUID : "", + 0x00080005: "", + 0x00080020: "", + 0x00080030: "", + 0x00080090: "", + 0x00100010: "", + 0x00100020: "", + 0x00200010: "", + 0x0008103E: "", + 0x0020000E: "", + 0x00200011: "" }; - this.setFindContext(C.SOP_STUDY_ROOT_FIND); var result = this.findSeries(Object.assign(defaultParams, params)), o = this; @@ -151,37 +134,34 @@ DIMSE.retrieveSeries = function(studyInstanceUID, params) { return future.wait(); }; -DIMSE.retrieveInstances = function(studyInstanceUID, seriesInstanceUID, params) { +DIMSE.retrieveInstances = function(studyInstanceUID, seriesInstanceUID, params, options) { var future = new Future; - DIMSE.associate([ C.SOP_STUDY_ROOT_FIND ], function(pdu) { + DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(pdu) { var defaultParams = { - 0x0020000D: studyInstanceUID ? studyInstanceUID : '', - 0x0020000E: (studyInstanceUID && seriesInstanceUID) ? seriesInstanceUID : '', - 0x00080005: '', - 0x00080020: '', - 0x00080030: '', - 0x00080090: '', - 0x00100010: '', - 0x00100020: '', - 0x00200010: '', - 0x0008103E: '', - 0x00200011: '', - 0x00080016: '', - 0x00080018: '', // sopInstanceUid. This is missing from the results? - 0x00200013: '', - 0x00280010: '', - 0x00280011: '', - 0x00280100: '', - 0x00280103: '' + 0x0020000D: studyInstanceUID ? studyInstanceUID : "", + 0x0020000E: (studyInstanceUID && seriesInstanceUID) ? seriesInstanceUID : "", + 0x00080005: "", + 0x00080020: "", + 0x00080030: "", + 0x00080090: "", + 0x00100010: "", + 0x00100020: "", + 0x00200010: "", + 0x0008103E: "", + 0x00200011: "", + 0x00080016: "", + 0x00080018: "", + 0x00200013: "", + 0x00280010: "", + 0x00280011: "", + 0x00280100: "", + 0x00280103: "" }; - - this.setFindContext(C.SOP_STUDY_ROOT_FIND); - var result = this.findInstances(Object.assign(defaultParams, params)), + var result = this.findInstances(Object.assign(defaultParams, params), options), o = this; var instances = []; result.on('result', function(msg) { - console.log(msg); instances.push(msg); }); @@ -195,3 +175,14 @@ DIMSE.retrieveInstances = function(studyInstanceUID, seriesInstanceUID, params) }); return future.wait(); }; + +DIMSE.moveInstances = function(studyInstanceUID, seriesInstanceUID, sopInstanceUID, sopClassUID, params) { + DIMSE.associate([C.SOP_STUDY_ROOT_MOVE, sopClassUID], function() { + var defaultParams = { + 0x0020000D: studyInstanceUID ? studyInstanceUID : "", + 0x0020000E: seriesInstanceUID ? seriesInstanceUID : "", + 0x00080018: sopInstanceUID ? sopInstanceUID : "" + } + this.moveInstances("OHIFDCM", Object.assign(defaultParams, params)); + }); +} \ No newline at end of file diff --git a/Packages/dimseservice/server/Data.js b/Packages/dimseservice/server/Data.js index f92fcc55b..afa88b772 100755 --- a/Packages/dimseservice/server/Data.js +++ b/Packages/dimseservice/server/Data.js @@ -1,964 +1,927 @@ function paddingLeft(paddingValue, string) { - return String(paddingValue + string).slice(-paddingValue.length); + return String(paddingValue + string).slice(-paddingValue.length); }; function rtrim(str) { - return str.replace(/\s*$/g, ''); + return str.replace(/\s*$/g, ''); } function ltrim(str) { - return str.replace(/^\s*/g, ''); + return str.replace(/^\s*/g, ''); } function fieldsLength(fields) { - var length = 0; - fields.forEach(function(field) { - length += field.length(); - }); - return length; + var length = 0; + fields.forEach(function(field) { + length += field.length(); + }); + return length; }; Tag = function(value) { - this.value = value; + this.value = value; }; Tag.prototype.toString = function() { - return '(' + paddingLeft('0000', this.group().toString(16)) + ',' + - paddingLeft('0000', this.element().toString(16)) + ')'; -}; - -Tag.prototype.is = function(t) { - return this.value == t; -}; - -Tag.prototype.group = function() { - return this.value >>> 16; -}; - -Tag.prototype.element = function() { - return this.value & 0xffff; -}; - -tagFromNumbers = function(group, element) { - return new Tag(((group << 16) | element) >>> 0); -}; - -function readTag(stream) { - var group = stream.read(C.TYPE_UINT16), - element = stream.read(C.TYPE_UINT16); - - var tag = tagFromNumbers(group, element); - return tag; + return "(" + paddingLeft("0000", this.group().toString(16)) + "," + + paddingLeft("0000", this.element().toString(16)) + ")"; } -parseElements = function(stream, syntax) { - var pairs = {}; - stream.reset(); - while (!stream.end()) { - var elem = new DataElement(); - elem.setSyntax(syntax); - elem.readBytes(stream); - pairs[elem.tag.value] = elem; - } +Tag.prototype.is = function(t) { + return this.value == t; +} - return pairs; -}; +Tag.prototype.group = function() { + return this.value >>> 16; +} + +Tag.prototype.element = function() { + return this.value & 0xffff; +} + +tagFromNumbers = function(group, element) { + return new Tag(((group << 16) | element) >>> 0); +} + +function readTag(stream) { + var group = stream.read(C.TYPE_UINT16), + element = stream.read(C.TYPE_UINT16); + + var tag = tagFromNumbers(group, element); + return tag; +} + +parseElements = function (stream, syntax) { + var pairs = {}; + stream.reset(); + while (!stream.end()) { + var elem = new DataElement(); + elem.setSyntax(syntax); + elem.readBytes(stream); + pairs[elem.tag.value] = elem; + } + return pairs; +} ValueRepresentation = function(type) { - this.type = type; - this.multi = false; -}; + this.type = type; + this.multi = false; +} ValueRepresentation.prototype.read = function(stream, length, syntax) { - if (this.fixed && this.maxLength) { - if (!length) - return this.defaultValue; - if (this.maxLength != length) - throw 'Invalid length for fixed length tag, vr ' + this.type + ', length ' + this.maxLength + ' != ' + length; - } - - return this.readBytes(stream, length, syntax); -}; + if (this.fixed && this.maxLength) { + if (!length) + return this.defaultValue; + if (this.maxLength != length) + throw "Invalid length for fixed length tag, vr " + this.type + ", length " + this.maxLength + " != " + length; + } + return this.readBytes(stream, length, syntax); +} ValueRepresentation.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_ASCII, length); -}; + return stream.read(C.TYPE_ASCII, length); +} ValueRepresentation.prototype.readNullPaddedString = function(stream, length) { - if (!length) return ''; + if (!length) return ""; - var str = stream.read(C.TYPE_ASCII, length - 1); - if (stream.read(C.TYPE_UINT8) != 0) { - stream.increment(-1); - str += stream.read(C.TYPE_ASCII, 1); - } - - return str; -}; + var str = stream.read(C.TYPE_ASCII, length - 1); + if (stream.read(C.TYPE_UINT8) != 0) { + stream.increment(-1); + str += stream.read(C.TYPE_ASCII, 1); + } + return str; +} ValueRepresentation.prototype.getFields = function(fields) { - var valid = true; - if (this.checkLength) { - valid = this.checkLength(fields); - } else if (this.maxCharLength) { - var check = this.maxCharLength, length = 0; - fields.forEach(function(field) { - if (typeof field.value == 'string') - length += field.value.length; - }); - valid = length <= check; - } else if (this.maxLength) { - var check = this.maxLength, length = fieldsLength(fields); - valid = length <= check; + var valid = true; + if (this.checkLength) { + valid = this.checkLength(fields); + } else if (this.maxCharLength) { + var check = this.maxCharLength, length = 0; + fields.forEach(function(field){ + if (typeof field.value == 'string') + length += field.value.length; + }); + valid = length <= check; + } else if (this.maxLength) { + var check = this.maxLength, length = fieldsLength(fields); + valid = length <= check; + } + if (!valid) + throw "Value exceeds max length"; + + //check for odd + var length = fieldsLength(fields); + if (length & 1) { + fields.push(new HexField(this.padByte)); + } + + for (var i = 0;i < fields.length;i++) { + if (fields[i].isNumeric() && (fields[i].value === "" || fields[i].value === null)) { + fields[i] = new StringField(""); } + } - if (!valid) - throw 'Value exceeds max length'; - - //check for odd - var length = fieldsLength(fields); - if (length & 1) { - fields.push(new HexField(this.padByte)); - } - - for (var i = 0;i < fields.length;i++) { - if (fields[i].isNumeric() && (fields[i].value === '' || fields[i].value === null)) { - fields[i] = new StringField(''); - } - } - - return fields; -}; + return fields; +} ApplicationEntity = function() { - ValueRepresentation.call(this, 'AE'); - this.maxLength = 16; - this.padByte = '20'; + ValueRepresentation.call(this, "AE"); + this.maxLength = 16; + this.padByte = "20"; }; - util.inherits(ApplicationEntity, ValueRepresentation); ApplicationEntity.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_ASCII, length).trim(); -}; + return stream.read(C.TYPE_ASCII, length).trim(); +} ApplicationEntity.prototype.getFields = function(value) { - return ApplicationEntity.super_.prototype.getFields.call(this, [ new FilledField(value, 16) ]); -}; + return ApplicationEntity.super_.prototype.getFields.call(this, [new FilledField(value, 16)]); +} CodeString = function() { - ValueRepresentation.call(this, 'CS'); - this.maxLength = 16; - this.padByte = '20'; + ValueRepresentation.call(this, "CS"); + this.maxLength = 16; + this.padByte = "20"; }; - util.inherits(CodeString, ValueRepresentation); CodeString.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return str.trim(); -}; + var str = this.readNullPaddedString(stream, length); + return str.trim(); +} CodeString.prototype.getFields = function(value) { - return CodeString.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return CodeString.super_.prototype.getFields.call(this, [new StringField(value)]); +} AgeString = function() { - ValueRepresentation.call(this, 'AS'); - this.maxLength = 4; - this.padByte = '20'; - this.fixed = true; - this.defaultValue = ''; + ValueRepresentation.call(this, "AS"); + this.maxLength = 4; + this.padByte = "20"; + this.fixed = true; + this.defaultValue = ""; }; - util.inherits(AgeString, ValueRepresentation); AgeString.prototype.getFields = function(value) { - var str = ''; - if (value) { - if (value.days) { - str = paddingLeft('000' + value.days) + 'D'; - } else if (value.weeks) { - str = paddingLeft('000' + value.weeks) + 'W'; - } else if (value.months) { - str = paddingLeft('000' + value.months) + 'M'; - } else if (value.years) { - str = paddingLeft('000' + value.years) + 'Y'; - } else { - throw 'Invalid age string'; - } - } + var str = ""; + if (value) { + if (value.days) { + str = paddingLeft("000" + value.days) + "D"; + } else if (value.weeks) { + str = paddingLeft("000" + value.weeks) + "W"; + } else if (value.months) { + str = paddingLeft("000" + value.months) + "M"; + } else if (value.years) { + str = paddingLeft("000" + value.years) + "Y"; + } else { + throw "Invalid age string"; + } + } - return AgeString.super_.prototype.getFields.call(this, [ new StringField(str) ]); -}; + return AgeString.super_.prototype.getFields.call(this, [new StringField(str)]); +} AttributeTag = function() { - ValueRepresentation.call(this, 'AT'); - this.maxLength = 4; - this.padByte = '00'; - this.fixed = true; + ValueRepresentation.call(this, "AT"); + this.maxLength = 4; + this.padByte = "00"; + this.fixed = true; }; - util.inherits(AttributeTag, ValueRepresentation); AttributeTag.prototype.readBytes = function(stream, length) { - var group = stream.read(C.TYPE_UINT16), element = stream.read(C.TYPE_UINT16); - return tagFromNumbers(group, element); -}; + var group = stream.read(C.TYPE_UINT16), element = stream.read(C.TYPE_UINT16); + return tagFromNumbers(group, element); +} AttributeTag.prototype.getFields = function(value) { - return AttributeTag.super_.prototype.getFields.call(this, [ new UInt16Field(value.group()), new UInt16Field(value.element()) ]); -}; + return AttributeTag.super_.prototype.getFields.call(this, [new UInt16Field(value.group()), new UInt16Field(value.element())]); +} DateValue = function() { - ValueRepresentation.call(this, 'DA'); - this.maxLength = 8; - this.padByte = '20'; - this.fixed = true; - this.defaultValue = ''; + ValueRepresentation.call(this, "DA"); + this.maxLength = 8; + this.padByte = "20"; + this.fixed = true; + this.defaultValue = ""; }; - util.inherits(DateValue, ValueRepresentation); DateValue.prototype.readBytes = function(stream, length) { - var datestr = stream.read(C.TYPE_ASCII, 8); + var datestr = stream.read(C.TYPE_ASCII, 8); - var year = parseInt(datestr.substring(0,4)), - month = parseInt(datestr.substring(4,6)), - day = parseInt(datestr.substring(6,8)); - return datestr;//new Date(year, month, day); -}; + var year = parseInt(datestr.substring(0,4)), + month = parseInt(datestr.substring(4,6)), + day = parseInt(datestr.substring(6,8)); + return datestr;//new Date(year, month, day); +} DateValue.prototype.getFields = function(date) { - var str = null; - if (typeof date == 'object') { - var year = date.getFullYear(), month = paddingLeft('00', date.getMonth()), day = paddingLeft('00', date.getDate()); - str = year + month + day; - } else if (date && date.length > 0) { - this.maxLength = 18; - this.fixed = false; - str = date; - } else { - str = ''; - } + var str = null; + if (typeof date == 'object') { + var year = date.getFullYear(), month = paddingLeft("00", date.getMonth()), day = paddingLeft("00", date.getDate()); + str = year + month + day; + } else if (date && date.length > 0) { + this.maxLength = 18; + this.fixed = false; + str = date; + } else { + str = ""; + } - return DateValue.super_.prototype.getFields.call(this, [ new StringField(str) ]); -}; + return DateValue.super_.prototype.getFields.call(this, [new StringField(str)]); +} DecimalString = function() { - ValueRepresentation.call(this, 'DS'); - this.maxLength = 16; - this.padByte = '20'; + ValueRepresentation.call(this, "DS"); + this.maxLength = 16; + this.padByte = "20"; }; - util.inherits(DecimalString, ValueRepresentation); DecimalString.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return str.trim(); -}; + var str = this.readNullPaddedString(stream, length); + return str.trim(); +} DecimalString.prototype.getFields = function(value) { - var f = parseFloat(value); - return DecimalString.super_.prototype.getFields.call(this, [ new StringField(isNaN(f) ? '' : f.toExponential()) ]); -}; + var f = parseFloat(value); + return DecimalString.super_.prototype.getFields.call(this, [new StringField(isNaN(f) ? '' : f.toExponential())]); +} DateTime = function() { - ValueRepresentation.call(this, 'DT'); - this.maxLength = 26; - this.padByte = '20'; + ValueRepresentation.call(this, "DT"); + this.maxLength = 26; + this.padByte = "20"; }; - util.inherits(DateTime, ValueRepresentation); DateTime.prototype.getFields = function(value) { - var year = date.getUTCFullYear(), month = paddingLeft('00', date.getUTCMonth()), - day = paddingLeft('00', date.getUTCDate()), hour = paddingLeft('00', date.getUTCHours()), - minute = paddingLeft('00', date.getUTCMinutes()), second = paddingLeft('00', date.getUTCSeconds()), - millisecond = paddingLeft('000', date.getUTCMilliseconds()); + var year = date.getUTCFullYear(), month = paddingLeft("00", date.getUTCMonth()), + day = paddingLeft("00", date.getUTCDate()), hour = paddingLeft("00", date.getUTCHours()), + minute = paddingLeft("00", date.getUTCMinutes()), second = paddingLeft("00", date.getUTCSeconds()), + millisecond = paddingLeft("000", date.getUTCMilliseconds()); - return DateTime.super_.prototype.getFields.call(this, [ new StringField(year + month + day + hour + minute + second + '.' + millisecond + '+0000') ]); -}; + return DateTime.super_.prototype.getFields.call(this, [new StringField(year + month + day + hour + minute + second + "." + millisecond + "+0000")]); +} FloatingPointSingle = function() { - ValueRepresentation.call(this, 'FL'); - this.maxLength = 4; - this.padByte = '00'; - this.fixed = true; - this.defaultValue = 0.0; + ValueRepresentation.call(this, "FL"); + this.maxLength = 4; + this.padByte = "00"; + this.fixed = true; + this.defaultValue = 0.0; }; - util.inherits(FloatingPointSingle, ValueRepresentation); FloatingPointSingle.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_FLOAT); -}; + return stream.read(C.TYPE_FLOAT); +} FloatingPointSingle.prototype.getFields = function(value) { - return FloatingPointSingle.super_.prototype.getFields.call(this, [ new FloatField(value) ]); -}; + return FloatingPointSingle.super_.prototype.getFields.call(this, [new FloatField(value)]); +} FloatingPointDouble = function() { - ValueRepresentation.call(this, 'FD'); - this.maxLength = 8; - this.padByte = '00'; - this.fixed = true; - this.defaultValue = 0.0; + ValueRepresentation.call(this, "FD"); + this.maxLength = 8; + this.padByte = "00"; + this.fixed = true; + this.defaultValue = 0.0; }; - util.inherits(FloatingPointDouble, ValueRepresentation); FloatingPointDouble.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_DOUBLE); -}; + return stream.read(C.TYPE_DOUBLE); +} FloatingPointDouble.prototype.getFields = function(value) { - return FloatingPointDouble.super_.prototype.getFields.call(this, [ new DoubleField(value) ]); -}; + return FloatingPointDouble.super_.prototype.getFields.call(this, [new DoubleField(value)]); +} IntegerString = function() { - ValueRepresentation.call(this, 'IS'); - this.maxLength = 12; - this.padByte = '20'; + ValueRepresentation.call(this, "IS"); + this.maxLength = 12; + this.padByte = "20"; }; - util.inherits(IntegerString, ValueRepresentation); IntegerString.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return str.trim(); -}; + var str = this.readNullPaddedString(stream, length); + return str.trim(); +} IntegerString.prototype.getFields = function(value) { - return IntegerString.super_.prototype.getFields.call(this, [ new StringField(value.toString()) ]); -}; + return IntegerString.super_.prototype.getFields.call(this, [new StringField(value.toString())]); +} LongString = function() { - ValueRepresentation.call(this, 'LO'); - this.maxCharLength = 64; - this.padByte = '20'; + ValueRepresentation.call(this, "LO"); + this.maxCharLength = 64; + this.padByte = "20"; }; - util.inherits(LongString, ValueRepresentation); LongString.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return str.trim(); -}; + var str = this.readNullPaddedString(stream, length); + return str.trim(); +} LongString.prototype.getFields = function(value) { - return LongString.super_.prototype.getFields.call(this, [ new StringField(value ? value : '') ]); -}; + return LongString.super_.prototype.getFields.call(this, [new StringField(value ? value : "")]); +} LongText = function() { - ValueRepresentation.call(this, 'LT'); - this.maxCharLength = 10240; - this.padByte = '20'; + ValueRepresentation.call(this, "LT"); + this.maxCharLength = 10240; + this.padByte = "20"; }; - util.inherits(LongText, ValueRepresentation); LongText.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return rtrim(str); -}; + var str = this.readNullPaddedString(stream, length); + return rtrim(str); +} LongText.prototype.getFields = function(value) { - return LongText.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return LongText.super_.prototype.getFields.call(this, [new StringField(value)]); +} PersonName = function() { - ValueRepresentation.call(this, 'PN'); - this.maxLength = null; - this.padByte = '20'; + ValueRepresentation.call(this, "PN"); + this.maxLength = null; + this.padByte = "20"; }; - util.inherits(PersonName, ValueRepresentation); PersonName.prototype.checkLength = function(field) { - var cmps = field[0].value.split(/\^/); - for (var i in cmps) { - var cmp = cmps[i]; - if (cmp.length > 64) return false; - } - - return true; -}; + var cmps = field[0].value.split(/\^/); + for (var i in cmps) { + var cmp = cmps[i]; + if (cmp.length > 64) return false; + } + return true; +} PersonName.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return rtrim(str); -}; + var str = this.readNullPaddedString(stream, length); + return rtrim(str); +} PersonName.prototype.getFields = function(value) { - var str = null; - if (typeof value == 'string') { - str = value; - } else if (value) { - var fName = value.family || '', gName = value.given || '', - middle = value.middle || '', prefix = value.prefix || '', suffix = value.suffix || ''; + var str = null; + if (typeof value == 'string') { + str = value; + } else if (value) { + var fName = value.family || "", gName = value.given || "", + middle = value.middle || "", prefix = value.prefix || "", suffix = value.suffix || ""; - str = [ fName, gName, middle, prefix, suffix ].join('^'); - } else str = ''; + str = [fName, gName, middle, prefix, suffix].join("^"); + } else str = ''; - return PersonName.super_.prototype.getFields.call(this, [ new StringField(str) ]); -}; + return PersonName.super_.prototype.getFields.call(this, [new StringField(str)]); +} ShortString = function() { - ValueRepresentation.call(this, 'SH'); - this.maxCharLength = 16; - this.padByte = '20'; + ValueRepresentation.call(this, "SH"); + this.maxCharLength = 16; + this.padByte = "20"; }; - util.inherits(ShortString, ValueRepresentation); ShortString.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return str.trim(); -}; + var str = this.readNullPaddedString(stream, length); + return str.trim(); +} ShortString.prototype.getFields = function(value) { - return ShortString.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return ShortString.super_.prototype.getFields.call(this, [new StringField(value)]); +} SignedLong = function() { - ValueRepresentation.call(this, 'SL'); - this.maxLength = 4; - this.padByte = '00'; - this.fixed = true; - this.defaultValue = 0; + ValueRepresentation.call(this, "SL"); + this.maxLength = 4; + this.padByte = "00"; + this.fixed = true; + this.defaultValue = 0; }; - util.inherits(SignedLong, ValueRepresentation); SignedLong.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_INT32); -}; + return stream.read(C.TYPE_INT32); +} SignedLong.prototype.getFields = function(value) { - return SignedLong.super_.prototype.getFields.call(this, [ new Int32Field(value) ]); -}; + return SignedLong.super_.prototype.getFields.call(this, [new Int32Field(value)]); +} SequenceOfItems = function() { - ValueRepresentation.call(this, 'SQ'); - this.maxLength = null; - this.padByte = '00'; + ValueRepresentation.call(this, "SQ"); + this.maxLength = null; + this.padByte = "00"; }; - util.inherits(SequenceOfItems, ValueRepresentation); SequenceOfItems.prototype.readBytes = function(stream, sqlength, syntax) { - if (sqlength == 0x0) { - return []; //contains no dataset - } else { - var undefLength = sqlength == 0xffffffff, elements = [], read = 0; + if (sqlength == 0x0) { + return []; //contains no dataset + } else { + var undefLength = sqlength == 0xffffffff, elements = [], read = 0; - while (true) { - var tag = readTag(stream), length = null; - read += 4; + while (true) { + var tag = readTag(stream), length = null; + read += 4; - if (tag.is(0xfffee0dd)) { - stream.read(C.TYPE_UINT32); - break; - } else if (!undefLength && (read == sqlength)) { - break; - } else if (tag.is(0xfffee000)) { - length = stream.read(C.TYPE_UINT32); - read += 4; - var itemStream = null, toRead = 0, undef = length == 0xffffffff; + if (tag.is(0xfffee0dd)) { + stream.read(C.TYPE_UINT32) + break; + } else if (!undefLength && (read == sqlength)) { + break; + } else if (tag.is(0xfffee000)) { + length = stream.read(C.TYPE_UINT32); + read += 4; + var itemStream = null, toRead = 0, undef = length == 0xffffffff; - if (undef) { - var stack = 0; - while (1) { - var g = stream.read(C.TYPE_UINT16); - if (g == 0xfffe) { - var ge = stream.read(C.TYPE_UINT16); - if (ge == 0xe00d) { - stack--; - if (stack < 0) { - stream.increment(4); - read += 8; - break; - } else { - toRead += 4; - } - } else if (ge == 0xe000) { - stack++; - toRead += 4; - } else { - toRead += 2; - stream.increment(-2); - } - } else { - toRead += 2; - } - } + if (undef) { + var stack = 0; + while (1) { + var g = stream.read(C.TYPE_UINT16); + if (g == 0xfffe) { + var ge = stream.read(C.TYPE_UINT16); + if (ge == 0xe00d) { + stack--; + if (stack < 0) { + stream.increment(4); + read += 8; + break; } else { - toRead = length; - } - - if (toRead) { - stream.increment(undef ? (-toRead - 8) : 0); - itemStream = stream.more(toRead);//parseElements - read += toRead; - if (undef) - stream.increment(8); - - elements.push(parseElements(itemStream, syntax)); - } - - if (!undefLength && (read == sqlength)) { - break; + toRead += 4; } + } else if (ge == 0xe000) { + stack++; + toRead += 4; + } else { + toRead += 2; + stream.increment(-2); + } + } else { + toRead += 2; } + } + } else { + toRead = length; } - return elements; + if (toRead) { + stream.increment(undef ? (-toRead-8) : 0); + itemStream = stream.more(toRead);//parseElements + read += toRead; + if (undef) + stream.increment(8); + + elements.push(parseElements(itemStream, syntax)); + } + if (!undefLength && (read == sqlength)) { + break; + } + } } -}; + return elements; + } +} SequenceOfItems.prototype.getFields = function(value, syntax) { - var fields = []; - if (value) { - value.forEach(function(message) { - fields.push(new UInt16Field(0xfffe)); - fields.push(new UInt16Field(0xe000)); - fields.push(new UInt32Field(0xffffffff)); + var fields = []; + if (value) { + value.forEach(function(message) { + fields.push(new UInt16Field(0xfffe)); + fields.push(new UInt16Field(0xe000)); + fields.push(new UInt32Field(0xffffffff)); - message.forEach(function(element) { - element.setSyntax(syntax); - fields = fields.concat(element.getFields()); - }); + message.forEach(function(element) { + element.setSyntax(syntax); + fields = fields.concat(element.getFields()); + }); - fields.push(new UInt16Field(0xfffe)); - fields.push(new UInt16Field(0xe00d)); - fields.push(new UInt32Field(0x00000000)); - }); - } + fields.push(new UInt16Field(0xfffe)); + fields.push(new UInt16Field(0xe00d)); + fields.push(new UInt32Field(0x00000000)); + }); + } - fields.push(new UInt16Field(0xfffe)); - fields.push(new UInt16Field(0xe0dd)); - fields.push(new UInt32Field(0x00000000)); + fields.push(new UInt16Field(0xfffe)); + fields.push(new UInt16Field(0xe0dd)); + fields.push(new UInt32Field(0x00000000)); - return SequenceOfItems.super_.prototype.getFields.call(this, fields); -}; + return SequenceOfItems.super_.prototype.getFields.call(this, fields); +} SignedShort = function() { - ValueRepresentation.call(this, 'SS'); - this.maxLength = 2; - this.padByte = '00'; - this.fixed = true; - this.defaultValue = 0; + ValueRepresentation.call(this, "SS"); + this.maxLength = 2; + this.padByte = "00"; + this.fixed = true; + this.defaultValue = 0; }; - util.inherits(SignedShort, ValueRepresentation); SignedShort.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_INT16); -}; + return stream.read(C.TYPE_INT16); +} SignedShort.prototype.getFields = function(value) { - return SignedShort.super_.prototype.getFields.call(this, [ new Int16Field(value) ]); -}; + return SignedShort.super_.prototype.getFields.call(this, [new Int16Field(value)]); +} ShortText = function() { - ValueRepresentation.call(this, 'ST'); - this.maxCharLength = 1024; - this.padByte = '20'; + ValueRepresentation.call(this, "ST"); + this.maxCharLength = 1024; + this.padByte = "20"; }; - util.inherits(ShortText, ValueRepresentation); ShortText.prototype.readBytes = function(stream, length) { - var str = this.readNullPaddedString(stream, length); - return rtrim(str); -}; + var str = this.readNullPaddedString(stream, length); + return rtrim(str); +} ShortText.prototype.getFields = function(value) { - return ShortText.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return ShortText.super_.prototype.getFields.call(this, [new StringField(value)]); +} TimeValue = function() { - ValueRepresentation.call(this, 'TM'); - this.maxLength = 14; - this.padByte = '20'; + ValueRepresentation.call(this, "TM"); + this.maxLength = 14; + this.padByte = "20"; }; - util.inherits(TimeValue, ValueRepresentation); TimeValue.prototype.readBytes = function(stream, length) { - return rtrim(stream.read(C.TYPE_ASCII, length)); -}; + return rtrim(stream.read(C.TYPE_ASCII, length)); +} TimeValue.prototype.getFields = function(date) { - var dateStr = ''; - if (date) { - var hour = paddingLeft('00', date.getHours()), - minute = paddingLeft('00', date.getMinutes()), second = paddingLeft('00', date.getSeconds()), - millisecond = paddingLeft('000', date.getMilliseconds()); - dateStr = hour + minute + second + '.' + millisecond; - } + var dateStr = ''; + if (date) { + var hour = paddingLeft("00", date.getHours()), + minute = paddingLeft("00", date.getMinutes()), second = paddingLeft("00", date.getSeconds()), + millisecond = paddingLeft("000", date.getMilliseconds()); + dateStr = hour + minute + second + "." + millisecond; + } - return TimeValue.super_.prototype.getFields.call(this, [ new StringField(dateStr) ]); -}; + return TimeValue.super_.prototype.getFields.call(this, [new StringField(dateStr)]); +} UnlimitedCharacters = function() { - ValueRepresentation.call(this, 'UC'); - this.maxLength = null; - this.multi = true; - this.padByte = '20'; + ValueRepresentation.call(this, "UC"); + this.maxLength = null; + this.multi = true; + this.padByte = "20"; }; - util.inherits(UnlimitedCharacters, ValueRepresentation); UnlimitedCharacters.prototype.readBytes = function(stream, length) { - return rtrim(stream.read(C.TYPE_ASCII, length)); -}; + return rtrim(stream.read(C.TYPE_ASCII, length)); +} UnlimitedCharacters.prototype.getFields = function(value) { - return UnlimitedCharacters.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return UnlimitedCharacters.super_.prototype.getFields.call(this, [new StringField(value)]); +} UnlimitedText = function() { - ValueRepresentation.call(this, 'UT'); - this.maxLength = null; - this.padByte = '20'; + ValueRepresentation.call(this, "UT"); + this.maxLength = null; + this.padByte = "20"; }; - util.inherits(UnlimitedText, ValueRepresentation); UnlimitedText.prototype.readBytes = function(stream, length) { - return this.readNullPaddedString(stream, length); -}; + return this.readNullPaddedString(stream, length); +} UnlimitedText.prototype.getFields = function(value) { - return UnlimitedText.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return UnlimitedText.super_.prototype.getFields.call(this, [new StringField(value)]); +} UnsignedShort = function() { - ValueRepresentation.call(this, 'US'); - this.maxLength = 2; - this.padByte = '00'; - this.fixed = true; - this.defaultValue = 0; + ValueRepresentation.call(this, "US"); + this.maxLength = 2; + this.padByte = "00"; + this.fixed = true; + this.defaultValue = 0; }; - util.inherits(UnsignedShort, ValueRepresentation); UnsignedShort.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_UINT16); -}; + return stream.read(C.TYPE_UINT16); +} UnsignedShort.prototype.getFields = function(value) { - return UnsignedShort.super_.prototype.getFields.call(this, [ new UInt16Field(value) ]); -}; + return UnsignedShort.super_.prototype.getFields.call(this, [new UInt16Field(value)]); +} UnsignedLong = function() { - ValueRepresentation.call(this, 'UL'); - this.maxLength = 4; - this.padByte = '00'; - this.fixed = true; - this.defaultValue = 0; + ValueRepresentation.call(this, "UL"); + this.maxLength = 4; + this.padByte = "00"; + this.fixed = true; + this.defaultValue = 0; }; - util.inherits(UnsignedLong, ValueRepresentation); UnsignedLong.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_UINT32); -}; + return stream.read(C.TYPE_UINT32); +} UnsignedLong.prototype.getFields = function(value) { - return UnsignedLong.super_.prototype.getFields.call(this, [ new UInt32Field(value) ]); -}; + return UnsignedLong.super_.prototype.getFields.call(this, [new UInt32Field(value)]); +} UniqueIdentifier = function() { - ValueRepresentation.call(this, 'UI'); - this.maxLength = 64; - this.padByte = '00'; + ValueRepresentation.call(this, "UI"); + this.maxLength = 64; + this.padByte = "00"; }; - util.inherits(UniqueIdentifier, ValueRepresentation); UniqueIdentifier.prototype.readBytes = function(stream, length) { - return this.readNullPaddedString(stream, length); -}; + return this.readNullPaddedString(stream, length); +} UniqueIdentifier.prototype.getFields = function(value) { - return UniqueIdentifier.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return UniqueIdentifier.super_.prototype.getFields.call(this, [new StringField(value)]); +} UniversalResource = function() { - ValueRepresentation.call(this, 'UR'); - this.maxLength = null; - this.padByte = '20'; + ValueRepresentation.call(this, "UR"); + this.maxLength = null; + this.padByte = "20"; }; - util.inherits(UniversalResource, ValueRepresentation); UniversalResource.prototype.readBytes = function(stream, length) { - return rtrim(stream.read(C.TYPE_ASCII, length)); -}; + return rtrim(stream.read(C.TYPE_ASCII, length)); +} UniversalResource.prototype.getFields = function(value) { - return UniversalResource.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return UniversalResource.super_.prototype.getFields.call(this, [new StringField(value)]); +} UnknownValue = function() { - ValueRepresentation.call(this, 'UN'); - this.maxLength = null; - this.padByte = '00'; + ValueRepresentation.call(this, "UN"); + this.maxLength = null; + this.padByte = "00"; }; - util.inherits(UnknownValue, ValueRepresentation); UnknownValue.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_ASCII, length); -}; + return stream.read(C.TYPE_ASCII, length); +} UnknownValue.prototype.getFields = function(value) { - return UnknownValue.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return UnknownValue.super_.prototype.getFields.call(this, [new StringField(value)]); +} OtherWordString = function() { - ValueRepresentation.call(this, 'OW'); - this.maxLength = null; - this.padByte = '00'; + ValueRepresentation.call(this, "OW"); + this.maxLength = null; + this.padByte = "00"; }; - util.inherits(OtherWordString, ValueRepresentation); OtherWordString.prototype.readBytes = function(stream, length) { - return stream.read(C.TYPE_ASCII, length); -}; + return stream.read(C.TYPE_ASCII, length); +} OtherWordString.prototype.getFields = function(value) { - return OtherWordString.super_.prototype.getFields.call(this, [ new StringField(value) ]); -}; + return OtherWordString.super_.prototype.getFields.call(this, [new StringField(value)]); +} + elementByType = function(type, value, syntax) { - var elem = null, nk = DicomElements.dicomNDict[type]; - if (nk) { - if (nk.vr == 'SQ') { - var sq = []; - if (value) + var elem = null, nk = DicomElements.dicomNDict[type]; + if (nk) { + if (nk.vr == 'SQ') { + var sq = []; + if (value) value.forEach(function(el) { - var values = []; - for (var tag in el) { - values.push(elementByType(tag, el[tag], syntax)); - } - - sq.push(values); + var values = []; + for (var tag in el) { + values.push(elementByType(tag, el[tag], syntax)); + } + sq.push(values); }); - elem = new DataElement(type, nk.vr, nk.vm, sq, false, syntax); - } else { - elem = new DataElement(type, nk.vr, nk.vm, value, false, syntax); - } + elem = new DataElement(type, nk.vr, nk.vm, sq, false, syntax); } else { - throw 'Unrecognized element type'; + elem = new DataElement(type, nk.vr, nk.vm, value, false, syntax); } - - return elem; -}; + } else { + throw "Unrecognized element type"; + } + return elem; +} elementDataByTag = function(tag) { - var nk = DicomElements.dicomNDict[tag]; - if (nk) { - return nk; - } - - throw ('Unrecognized tag ' + (tag >>> 0).toString(16)); -}; + var nk = DicomElements.dicomNDict[tag]; + if (nk) { + return nk; + } + throw ("Unrecognized tag " + (tag >>> 0).toString(16)); +} elementKeywordByTag = function(tag) { - var nk = elementDataByTag(tag); - return nk.keyword; -}; + var nk = elementDataByTag(tag); + return nk.keyword; +} vrByType = function(type) { - var vr = null; - if (type == 'AE') vr = new ApplicationEntity(); - else if (type == 'AS') vr = new AgeString(); - else if (type == 'AT') vr = new AttributeTag(); - else if (type == 'CS') vr = new CodeString(); - else if (type == 'DA') vr = new DateValue(); - else if (type == 'DS') vr = new DecimalString(); - else if (type == 'DT') vr = new DateTime(); - else if (type == 'FL') vr = new FloatingPointSingle(); - else if (type == 'FD') vr = new FloatingPointDouble(); - else if (type == 'IS') vr = new IntegerString(); - else if (type == 'LO') vr = new LongString(); - else if (type == 'LT') vr = new LongText(); - else if (type == 'OB') vr = new OtherByteString(); - else if (type == 'OD') vr = new OtherDoubleString(); - else if (type == 'OF') vr = new OtherFloatString(); - else if (type == 'OW') vr = new OtherWordString(); - else if (type == 'PN') vr = new PersonName(); - else if (type == 'SH') vr = new ShortString(); - else if (type == 'SL') vr = new SignedLong(); - else if (type == 'SQ') vr = new SequenceOfItems(); - else if (type == 'SS') vr = new SignedShort(); - else if (type == 'ST') vr = new ShortText(); - else if (type == 'TM') vr = new TimeValue(); - else if (type == 'UC') vr = new UnlimitedCharacters(); - else if (type == 'UI') vr = new UniqueIdentifier(); - else if (type == 'UL') vr = new UnsignedLong(); - else if (type == 'UN') vr = new UnknownValue(); - else if (type == 'UR') vr = new UniversalResource(); - else if (type == 'US') vr = new UnsignedShort(); - else if (type == 'UT') vr = new UnlimitedText(); - else throw 'Invalid vr type ' + type; + var vr = null; + if (type == "AE") vr = new ApplicationEntity(); + else if (type == "AS") vr = new AgeString(); + else if (type == "AT") vr = new AttributeTag(); + else if (type == "CS") vr = new CodeString(); + else if (type == "DA") vr = new DateValue(); + else if (type == "DS") vr = new DecimalString(); + else if (type == "DT") vr = new DateTime(); + else if (type == "FL") vr = new FloatingPointSingle(); + else if (type == "FD") vr = new FloatingPointDouble(); + else if (type == "IS") vr = new IntegerString(); + else if (type == "LO") vr = new LongString(); + else if (type == "LT") vr = new LongText(); + else if (type == "OB") vr = new OtherByteString(); + else if (type == "OD") vr = new OtherDoubleString(); + else if (type == "OF") vr = new OtherFloatString(); + else if (type == "OW") vr = new OtherWordString(); + else if (type == "PN") vr = new PersonName(); + else if (type == "SH") vr = new ShortString(); + else if (type == "SL") vr = new SignedLong(); + else if (type == "SQ") vr = new SequenceOfItems(); + else if (type == "SS") vr = new SignedShort(); + else if (type == "ST") vr = new ShortText(); + else if (type == "TM") vr = new TimeValue(); + else if (type == "UC") vr = new UnlimitedCharacters(); + else if (type == "UI") vr = new UniqueIdentifier(); + else if (type == "UL") vr = new UnsignedLong(); + else if (type == "UN") vr = new UnknownValue(); + else if (type == "UR") vr = new UniversalResource(); + else if (type == "US") vr = new UnsignedShort(); + else if (type == "UT") vr = new UnlimitedText(); + else throw "Invalid vr type " + type; - return vr; -}; + return vr; +} readElements = function(stream, syntax) { - if (stream.end()) return false; + if (stream.end()) return false; - var oldEndian = stream.endian; - stream.setEndian(this.endian); + var oldEndian = stream.endian; + stream.setEndian(this.endian); - var group = stream.read(C.TYPE_UINT16), - element = stream.read(C.TYPE_UINT16), - tag = new Tag((group << 16) | element), - length = stream.read(C.TYPE_UINT32); + var group = stream.read(C.TYPE_UINT16), + element = stream.read(C.TYPE_UINT16), + tag = new Tag((group << 16) | element), + length = stream.read(C.TYPE_UINT32); - stream.setEndian(oldEndian); -}; + stream.setEndian(oldEndian); +} -var explicitVRList = [ 'OB', 'OW', 'OF', 'SQ', 'UC', 'UR', 'UT', 'UN' ], - binaryVRs = [ 'FL', 'FD', 'SL', 'SS', 'UL', 'US' ]; +var explicitVRList = ["OB", "OW", "OF", "SQ", "UC", "UR", "UT", "UN"], + binaryVRs = ["FL", "FD", "SL", "SS", "UL", "US"]; DataElement = function(tag, vr, vm, value, vvr, syntax, options) { - this.vr = vr ? vrByType(vr) : null; - this.tag = !vvr ? new Tag(tag) : tag; - this.value = value; - this.vm = vm; - this.vvr = vvr ? true : false; - this.setOptions(options); - this.setSyntax(syntax ? syntax : C.IMPLICIT_LITTLE_ENDIAN); + this.vr = vr ? vrByType(vr) : null; + this.tag = !vvr ? new Tag(tag) : tag; + this.value = value; + this.vm = vm; + this.vvr = vvr ? true : false; + this.setOptions(options); + this.setSyntax(syntax ? syntax : C.IMPLICIT_LITTLE_ENDIAN); }; DataElement.prototype.setOptions = function(options) { - this.options = Object.assign({ - split: true - }, options); -}; + this.options = Object.assign({split : true}, options); +} DataElement.prototype.setSyntax = function(syn) { - this.syntax = syn; - this.implicit = this.syntax == C.IMPLICIT_LITTLE_ENDIAN ? true : false; - this.endian = (this.syntax == C.IMPLICIT_LITTLE_ENDIAN || this.syntax == C.EXPLICIT_LITTLE_ENDIAN) ? C.LITTLE_ENDIAN : C.BIG_ENDIAN; -}; + this.syntax = syn; + this.implicit = this.syntax == C.IMPLICIT_LITTLE_ENDIAN ? true : false; + this.endian = (this.syntax == C.IMPLICIT_LITTLE_ENDIAN || this.syntax == C.EXPLICIT_LITTLE_ENDIAN) ? C.LITTLE_ENDIAN : C.BIG_ENDIAN; +} DataElement.prototype.getValue = function() { - if (!this.singleValue() && !this.isBinaryNumber()) { - return this.options.split ? this.value.split(String.fromCharCode(0x5c)) : this.value; - } else { - return this.value; - } -}; + if (!this.singleValue() && !this.isBinaryNumber()) { + return this.options.split ? this.value.split(String.fromCharCode(0x5c)) : this.value; + } else { + return this.value; + } +} DataElement.prototype.singleValue = function() { - return this.vm == C.VM_SINGLE ? true : false; -}; + return this.vm == C.VM_SINGLE ? true : false; +} DataElement.prototype.getVMNum = function() { - var num = 1; - switch (this.vm) { - case C.VM_SINGLE : num = 1; break; - case C.VM_TWO : num = 2; break; - case C.VM_THREE : num = 3; break; - case C.VM_FOUR : num = 4; break; - case C.VM_16 : num = 16; break; - default : break; - } - return num; -}; + var num = 1; + switch(this.vm) { + case C.VM_SINGLE : num = 1; break; + case C.VM_TWO : num = 2; break; + case C.VM_THREE : num = 3; break; + case C.VM_FOUR : num = 4; break; + case C.VM_16 : num = 16; break; + default : break; + } + return num; +} DataElement.prototype.isBinaryNumber = function() { - return binaryVRs.indexOf(this.vr.type) != -1; -}; + return binaryVRs.indexOf(this.vr.type) != -1; +} DataElement.prototype.length = function(fields) { - //let fields = this.vr.getFields(this.value); - return fieldsLength(fields); -}; + //let fields = this.vr.getFields(this.value); + return fieldsLength(fields); +} DataElement.prototype.readBytes = function(stream) { - var oldEndian = stream.endian; - stream.setEndian(this.endian); + var oldEndian = stream.endian; + stream.setEndian(this.endian); - var group = stream.read(C.TYPE_UINT16), - element = stream.read(C.TYPE_UINT16), - tag = tagFromNumbers(group, element); + var group = stream.read(C.TYPE_UINT16), + element = stream.read(C.TYPE_UINT16), + tag = tagFromNumbers(group, element); - var length = null, vr = null, edata = elementDataByTag(tag.value), - vm = edata.vm; + var length = null, vr = null, edata = elementDataByTag(tag.value), + vm = edata.vm; - if (this.implicit) { - length = stream.read(C.TYPE_UINT32); - vr = edata.vr; + if (this.implicit) { + length = stream.read(C.TYPE_UINT32); + vr = edata.vr; + } else { + vr = stream.read(C.TYPE_ASCII, 2); + if (explicitVRList.indexOf(vr) != -1) { + stream.increment(2); + length = stream.read(C.TYPE_UINT32); } else { - vr = stream.read(C.TYPE_ASCII, 2); - if (explicitVRList.indexOf(vr) != -1) { - stream.increment(2); - length = stream.read(C.TYPE_UINT32); - } else { - length = stream.read(C.TYPE_UINT16); - } + length = stream.read(C.TYPE_UINT16); } + } - this.vr = vrByType(vr); - this.tag = tag; - this.vm = vm; + this.vr = vrByType(vr); + this.tag = tag; + this.vm = vm; + //try { + if (this.isBinaryNumber() && length > this.vr.maxLength) { + var times = length / this.vr.maxLength, i = 0; + this.value = [];//console.log(times, length, this.vr.maxLength);return; //try { - if (this.isBinaryNumber() && length > this.vr.maxLength) { - var times = length / this.vr.maxLength, i = 0; - this.value = [];//console.log(times, length, this.vr.maxLength);return; - //try { - while (i++ < times) { - this.value.push(this.vr.read(stream, this.vr.maxLength)); - } - //} catch (e) { } - } else { - this.value = this.vr.read(stream, length, this.syntax); + while (i++ < times) { + this.value.push(this.vr.read(stream, this.vr.maxLength)); } - //} catch (e) { console.log('error', vr, length); } + //} catch (e) { } + } else { + this.value = this.vr.read(stream, length, this.syntax); + } + //} catch (e) { console.log('error', vr, length); } - stream.setEndian(oldEndian); -}; + stream.setEndian(oldEndian); +} DataElement.prototype.write = function(stream) { - var oldEndian = stream.endian; - stream.setEndian(this.endian); + var oldEndian = stream.endian; + stream.setEndian(this.endian); - var fields = this.getFields(); - fields.forEach(function(field) { - field.write(stream); - }); + var fields = this.getFields(); + fields.forEach(function(field){ + field.write(stream); + }); - stream.setEndian(oldEndian); -}; + stream.setEndian(oldEndian); +} DataElement.prototype.getFields = function() { - var fields = [ new UInt16Field(this.tag.group()), new UInt16Field(this.tag.element()) ], - valueFields = this.vr.getFields(this.value, this.syntax), valueLength = fieldsLength(valueFields), vrType = this.vr.type; + var fields = [new UInt16Field(this.tag.group()), new UInt16Field(this.tag.element())], + valueFields = this.vr.getFields(this.value, this.syntax), valueLength = fieldsLength(valueFields), vrType = this.vr.type; - if (vrType == 'SQ') { - valueLength = 0xffffffff; - } + if (vrType == "SQ") { + valueLength = 0xffffffff; + } - if (this.implicit) { - fields.push(new UInt32Field(valueLength)); + if (this.implicit) { + fields.push(new UInt32Field(valueLength)); + } else { + if (explicitVRList.indexOf(vrType) != -1) { + fields.push(new StringField(vrType), new ReservedField(2), new UInt32Field(valueLength)); } else { - if (explicitVRList.indexOf(vrType) != -1) { - fields.push(new StringField(vrType), new ReservedField(2), new UInt32Field(valueLength)); - } else { - fields.push(new StringField(vrType), new UInt16Field(valueLength)); - } - } + fields.push(new StringField(vrType), new UInt16Field(valueLength)); + } + } + + fields = fields.concat(valueFields); + return fields; +} - fields = fields.concat(valueFields); - return fields; -}; diff --git a/Packages/dimseservice/server/Field.js b/Packages/dimseservice/server/Field.js index 274faa17e..c1e5a6b2a 100755 --- a/Packages/dimseservice/server/Field.js +++ b/Packages/dimseservice/server/Field.js @@ -1,141 +1,128 @@ Field = function(type, value) { - this.type = type; - this.value = value; + this.type = type; + this.value = value; }; Field.prototype.length = function() { - return calcLength(this.type, this.value); -}; + return calcLength(this.type, this.value); +} Field.prototype.write = function(stream) { - stream.write(this.type, this.value); -}; + stream.write(this.type, this.value); +} Field.prototype.isNumeric = function() { - return false; -}; + return false; +} StringField = function(str) { - Field.call(this, C.TYPE_ASCII, typeof str == 'string' ? str : ''); -}; - + Field.call(this, C.TYPE_ASCII, typeof str == 'string' ? str : ""); +} util.inherits(StringField, Field); FilledField = function(value, length) { - Field.call(this, C.TYPE_COMPOSITE, value); - this.fillLength = length; -}; - + Field.call(this, C.TYPE_COMPOSITE, value); + this.fillLength = length; +} util.inherits(FilledField, Field); FilledField.prototype.length = function() { - return this.fillLength; -}; + return this.fillLength; +} FilledField.prototype.write = function(stream) { - var len = this.value.length; - if (len < this.fillLength && len >= 0) { - if (len > 0) - stream.write(C.TYPE_ASCII, this.value); - var zeroLength = this.fillLength - len; - stream.write(C.TYPE_HEX, '20'.repeat(zeroLength)); - } else if (len == this.fillLength) { - stream.write(C.TYPE_ASCII, this.value); - } else { - throw 'Length mismatch'; - } -}; + var len = this.value.length; + if (len < this.fillLength && len >= 0) { + if (len > 0) + stream.write(C.TYPE_ASCII, this.value); + var zeroLength = this.fillLength - len; + stream.write(C.TYPE_HEX, "20".repeat(zeroLength)); + } else if (len == this.fillLength) { + stream.write(C.TYPE_ASCII, this.value); + } else { + throw "Length mismatch"; + } +} HexField = function(hex) { - Field.call(this, C.TYPE_HEX, hex); -}; - + Field.call(this, C.TYPE_HEX, hex); +} util.inherits(HexField, Field); ReservedField = function(length) { - length = length || 1; - Field.call(this, C.TYPE_HEX, '00'.repeat(length)); -}; - + length = length || 1; + Field.call(this, C.TYPE_HEX, "00".repeat(length)); +} util.inherits(ReservedField, Field); UInt8Field = function(value) { - Field.call(this, C.TYPE_UINT8, value); -}; - + Field.call(this, C.TYPE_UINT8, value); +} util.inherits(UInt8Field, Field); UInt8Field.prototype.isNumeric = function() { - return true; -}; + return true; +} UInt16Field = function(value) { - Field.call(this, C.TYPE_UINT16, value); -}; - + Field.call(this, C.TYPE_UINT16, value); +} util.inherits(UInt16Field, Field); UInt16Field.prototype.isNumeric = function() { - return true; -}; + return true; +} UInt32Field = function(value) { - Field.call(this, C.TYPE_UINT32, value); -}; - + Field.call(this, C.TYPE_UINT32, value); +} util.inherits(UInt32Field, Field); UInt32Field.prototype.isNumeric = function() { - return true; -}; + return true; +} Int8Field = function(value) { - Field.call(this, C.TYPE_INT8, value); -}; - + Field.call(this, C.TYPE_INT8, value); +} util.inherits(Int8Field, Field); Int8Field.prototype.isNumeric = function() { - return true; -}; + return true; +} Int16Field = function(value) { - Field.call(this, C.TYPE_INT16, value); -}; - + Field.call(this, C.TYPE_INT16, value); +} util.inherits(Int16Field, Field); Int16Field.prototype.isNumeric = function() { - return true; -}; + return true; +} Int32Field = function(value) { - Field.call(this, C.TYPE_INT32, value); -}; - + Field.call(this, C.TYPE_INT32, value); +} util.inherits(Int32Field, Field); Int32Field.prototype.isNumeric = function() { - return true; -}; + return true; +} FloatField = function(value) { - Field.call(this, C.TYPE_FLOAT, value); -}; - + Field.call(this, C.TYPE_FLOAT, value); +} util.inherits(FloatField, Field); FloatField.prototype.isNumeric = function() { - return true; -}; + return true; +} DoubleField = function(value) { - Field.call(this, C.TYPE_DOUBLE, value); -}; - + Field.call(this, C.TYPE_DOUBLE, value); +} util.inherits(DoubleField, Field); DoubleField.prototype.isNumeric = function() { - return true; -}; - \ No newline at end of file + return true; +} \ No newline at end of file diff --git a/Packages/dimseservice/server/Message.js b/Packages/dimseservice/server/Message.js index aa22a0bb9..30981b6b7 100755 --- a/Packages/dimseservice/server/Message.js +++ b/Packages/dimseservice/server/Message.js @@ -1,463 +1,459 @@ DicomMessage = function(syntax) { - this.syntax = syntax ? syntax : null; - this.type = C.DATA_TYPE_COMMAND; - this.messageId = C.DEFAULT_MESSAGE_ID; - this.elementPairs = {}; + this.syntax = syntax ? syntax : null; + this.type = C.DATA_TYPE_COMMAND; + this.messageId = C.DEFAULT_MESSAGE_ID; + this.elementPairs = {}; }; DicomMessage.prototype.isCommand = function() { - return this.type == C.DATA_TYPE_COMMAND; -}; + return this.type == C.DATA_TYPE_COMMAND; +} DicomMessage.prototype.setSyntax = function(syntax) { - this.syntax = syntax; + this.syntax = syntax; - for (var tag in this.elementPairs) { - this.elementPairs[tag].setSyntax(this.syntax); - } -}; + for (var tag in this.elementPairs) { + this.elementPairs[tag].setSyntax(this.syntax); + } +} DicomMessage.prototype.setMessageId = function(id) { - this.messageId = id; -}; + this.messageId = id; +} DicomMessage.prototype.setReplyMessageId = function(id) { - this.replyMessageId = id; -}; + this.replyMessageId = id; +} DicomMessage.prototype.command = function(cmds) { - cmds.unshift(this.newElement(0x00000800, this.dataSetPresent ? C.DATA_SET_PRESENT : C.DATE_SET_ABSENCE)); - cmds.unshift(this.newElement(0x00000700, this.priority)); - cmds.unshift(this.newElement(0x00000110, this.messageId)); - cmds.unshift(this.newElement(0x00000100, this.commandType)); - cmds.unshift(this.newElement(0x00000002, this.contextUID)); + cmds.unshift(this.newElement(0x00000800, this.dataSetPresent ? C.DATA_SET_PRESENT : C.DATE_SET_ABSENCE)); + cmds.unshift(this.newElement(0x00000700, this.priority)); + cmds.unshift(this.newElement(0x00000110, this.messageId)); + cmds.unshift(this.newElement(0x00000100, this.commandType)); + cmds.unshift(this.newElement(0x00000002, this.contextUID)); - var length = 0; - cmds.forEach(function(cmd) { - length += cmd.length(cmd.getFields()); - }); + var length = 0; + cmds.forEach(function(cmd) { + length += cmd.length(cmd.getFields()); + }); - cmds.unshift(this.newElement(0x00000000, length)); - return cmds; -}; + cmds.unshift(this.newElement(0x00000000, length)); + return cmds; +} DicomMessage.prototype.response = function(cmds) { - cmds.unshift(this.newElement(0x00000800, this.dataSetPresent ? C.DATA_SET_PRESENT : C.DATE_SET_ABSENCE)); - cmds.unshift(this.newElement(0x00000120, this.replyMessageId)); - cmds.unshift(this.newElement(0x00000100, this.commandType)); + cmds.unshift(this.newElement(0x00000800, this.dataSetPresent ? C.DATA_SET_PRESENT : C.DATE_SET_ABSENCE)); + cmds.unshift(this.newElement(0x00000120, this.replyMessageId)); + cmds.unshift(this.newElement(0x00000100, this.commandType)); + if (this.contextUID) cmds.unshift(this.newElement(0x00000002, this.contextUID)); - var length = 0; - cmds.forEach(function(cmd) { - length += cmd.length(cmd.getFields()); - }); + var length = 0; + cmds.forEach(function(cmd) { + length += cmd.length(cmd.getFields()); + }); - cmds.unshift(this.newElement(0x00000000, length)); - return cmds; -}; + cmds.unshift(this.newElement(0x00000000, length)); + return cmds; +} DicomMessage.prototype.setElements = function(pairs) { - var p = {}; - for (var tag in pairs) { - p[tag] = this.newElement(tag, pairs[tag]); - } - - this.elementPairs = p; -}; + var p = {}; + for (var tag in pairs) { + p[tag] = this.newElement(tag, pairs[tag]); + } + this.elementPairs = p; +} DicomMessage.prototype.newElement = function(tag, value) { - return elementByType(tag, value, this.syntax); -}; + return elementByType(tag, value, this.syntax); +} DicomMessage.prototype.setElement = function(key, value) { - this.elementPairs[key] = elementByType(key, value); -}; + this.elementPairs[key] = elementByType(key, value); +} DicomMessage.prototype.setElementPairs = function(pairs) { - this.elementPairs = pairs; -}; + this.elementPairs = pairs; +} DicomMessage.prototype.setContextId = function(context) { - this.contextUID = context; -}; + this.contextUID = context; +} DicomMessage.prototype.setPriority = function(pri) { - this.priority = pri; -}; + this.priority = pri; +} DicomMessage.prototype.setType = function(type) { - this.type = type; -}; + this.type = type; +} DicomMessage.prototype.setDataSetPresent = function(present) { - this.dataSetPresent = present == 0x0101 ? false : true; -}; + this.dataSetPresent = present == 0x0101 ? false : true; +} DicomMessage.prototype.haveData = function() { - return this.dataSetPresent; -}; + return this.dataSetPresent; +} DicomMessage.prototype.tags = function() { - return Object.keys(this.elementPairs); -}; + return Object.keys(this.elementPairs); +} DicomMessage.prototype.key = function(tag) { - return elementKeywordByTag(tag); -}; + return elementKeywordByTag(tag); +} DicomMessage.prototype.getValue = function(tag) { - return this.elementPairs[tag] ? this.elementPairs[tag].getValue() : null; -}; + return this.elementPairs[tag] ? this.elementPairs[tag].getValue() : null; +} DicomMessage.prototype.affectedSOPClassUID = function() { - return this.getValue(0x00000002); -}; + return this.getValue(0x00000002); +} DicomMessage.prototype.getMessageId = function() { - return this.getValue(0x00000110); -}; + return this.getValue(0x00000110); +} DicomMessage.prototype.getFields = function() { - var eles = []; - for (var tag in this.elementPairs) { - eles.push(this.elementPairs[tag]); - } - - return eles; -}; + var eles = []; + for (var tag in this.elementPairs) { + eles.push(this.elementPairs[tag]); + } + return eles; +} DicomMessage.prototype.length = function(elems) { - var len = 0; - elems.forEach(function(elem) { - len += elem.length(elem.getFields()); - }); - return len; -}; + var len = 0; + elems.forEach(function(elem){ + len += elem.length(elem.getFields()); + }); + return len; +} DicomMessage.prototype.isResponse = function() { - return false; -}; + return false; +} DicomMessage.prototype.is = function(type) { - return this.commandType == type; -}; + return this.commandType == type; +} DicomMessage.prototype.write = function(stream) { - var fields = this.getFields(), o = this; - fields.forEach(function(field) { - field.setSyntax(o.syntax); - field.write(stream); - }); -}; + var fields = this.getFields(), o = this; + fields.forEach(function(field){ + field.setSyntax(o.syntax); + field.write(stream); + }); +} DicomMessage.prototype.printElements = function(pairs, indent) { - var typeName = ''; - for (var tag in pairs) { - var value = pairs[tag].getValue(); - typeName += (' '.repeat(indent)) + this.key(tag) + ' : '; - if (value instanceof Array) { - var o = this; - value.forEach(function(p) { - if (typeof p == 'object') { - typeName += '[\n' + o.printElements(p, indent + 2) + (' '.repeat(indent)) + ']'; - } else { - typeName += '[' + p + ']'; - } - }); - if (typeName[typeName.length - 1] != '\n') { - typeName += '\n'; - } + var typeName = ""; + for (var tag in pairs) { + var value = pairs[tag].getValue(); + typeName += (" ".repeat(indent)) + this.key(tag) + " : "; + if (value instanceof Array) { + var o = this; + value.forEach(function(p) { + if (typeof p == "object") { + typeName += "[\n" + o.printElements(p, indent + 2) + (" ".repeat(indent)) + "]"; } else { - typeName += value + '\n'; + typeName += "[" + p + "]"; } + }); + if (typeName[typeName.length-1] != "\n") { + typeName += "\n"; + } + } else { + typeName += value + "\n"; } - - return typeName; -}; + } + return typeName; +} DicomMessage.prototype.toString = function() { - var typeName = ''; - if (!this.isCommand()) { - typeName = 'DateSet Message'; - } else { - switch (this.commandType) { - case C.COMMAND_C_GET_RSP : typeName = 'C-GET-RSP'; break; - case C.COMMAND_C_MOVE_RSP : typeName = 'C-MOVE-RSP'; break; - case C.COMMAND_C_GET_RQ : typeName = 'C-GET-RQ'; break; - case C.COMMAND_C_STORE_RQ : typeName = 'C-STORE-RQ'; break; - case C.COMMAND_C_FIND_RSP : typeName = 'C-FIND-RSP'; break; - case C.COMMAND_C_MOVE_RQ : typeName = 'C-MOVE-RQ'; break; - case C.COMMAND_C_FIND_RQ : typeName = 'C-FIND-RQ'; break; - case C.COMMAND_C_STORE_RSP : typeName = 'C-STORE-RSP'; break; - } - } - - typeName += ' [\n'; - typeName += this.printElements(this.elementPairs, 0); - typeName += ']'; - return typeName; -}; + var typeName = ""; + if (!this.isCommand()) { + typeName = "DateSet Message"; + } else { + switch (this.commandType) { + case C.COMMAND_C_GET_RSP : typeName = "C-GET-RSP"; break; + case C.COMMAND_C_MOVE_RSP : typeName = "C-MOVE-RSP"; break; + case C.COMMAND_C_GET_RQ : typeName = "C-GET-RQ"; break; + case C.COMMAND_C_STORE_RQ : typeName = "C-STORE-RQ"; break; + case C.COMMAND_C_FIND_RSP : typeName = "C-FIND-RSP"; break; + case C.COMMAND_C_MOVE_RQ : typeName = "C-MOVE-RQ"; break; + case C.COMMAND_C_FIND_RQ : typeName = "C-FIND-RQ"; break; + case C.COMMAND_C_STORE_RSP : typeName = "C-STORE-RSP"; break; + } + } + typeName += " [\n"; + typeName += this.printElements(this.elementPairs, 0); + typeName += "]"; + return typeName; +} DicomMessage.prototype.walkObject = function(pairs) { - var obj = {}, o = this; - for (var tag in pairs) { - var v = pairs[tag].getValue(), u = v; - if (v instanceof Array) { - u = []; - v.forEach(function(a) { - if (typeof a == 'object') { - u.push(o.walkObject(a)); - } else u.push(a); - }); - } - - obj[tag] = u; + var obj = {}, o = this; + for (var tag in pairs) { + var v = pairs[tag].getValue(), u = v; + if (v instanceof Array) { + u = []; + v.forEach(function(a) { + if (typeof a == 'object') { + u.push(o.walkObject(a)); + } else u.push(a); + }); } + obj[tag] = u; + } - return obj; -}; + return obj; +} DicomMessage.prototype.toObject = function() { - return this.walkObject(this.elementPairs); -}; + return this.walkObject(this.elementPairs); +} -readMessage = function(stream, type, syntax, options) { - var elements = [], pairs = {}, useSyntax = type == C.DATA_TYPE_COMMAND ? C.IMPLICIT_LITTLE_ENDIAN : syntax; - stream.reset(); - while (!stream.end()) { - var elem = new DataElement(); - if (options) { - elem.setOptions(options); - } +DicomMessage.read = function(stream, type, syntax, options) { + var elements = [], pairs = {}, useSyntax = type == C.DATA_TYPE_COMMAND ? C.IMPLICIT_LITTLE_ENDIAN : syntax; + stream.reset(); + while (!stream.end()) { + var elem = new DataElement(); + if (options) { + elem.setOptions(options); + } + elem.setSyntax(useSyntax); + elem.readBytes(stream);//return; + pairs[elem.tag.value] = elem; + } - elem.setSyntax(useSyntax); - elem.readBytes(stream);//return; - pairs[elem.tag.value] = elem; + var message = null; + if (type == C.DATA_TYPE_COMMAND) { + var cmdType = pairs[0x00000100].value; + + switch (cmdType) { + case 0x8020 : message = new CFindRSP(useSyntax); break; + case 0x8021 : message = new CMoveRSP(useSyntax); break; + case 0x8010 : message = new CGetRSP(useSyntax); break; + case 0x0001 : message = new CStoreRQ(useSyntax); break; + case 0x0020 : message = new CFindRQ(useSyntax); break; + default : throw "Unrecognized command type " + cmdType.toString(16); break; } - var message = null; - if (type == C.DATA_TYPE_COMMAND) { - var cmdType = pairs[0x00000100].value; - - switch (cmdType) { - case 0x8020 : message = new CFindRSP(useSyntax); break; - case 0x8021 : message = new CMoveRSP(useSyntax); break; - case 0x8010 : message = new CGetRSP(useSyntax); break; - case 0x0001 : message = new CStoreRQ(useSyntax); break; - case 0x0020 : message = new CFindRQ(useSyntax); break; - default : throw 'Unrecognized command type ' + cmdType.toString(16); break; - } - - message.setElementPairs(pairs); - message.setDataSetPresent(message.getValue(0x00000800)); - message.setContextId(message.getValue(0x00000002)); - if (!message.isResponse()) { - message.setMessageId(message.getValue(0x00000110)); - } else { - message.setReplyMessageId(message.getValue(0x00000120)); - } - } else if (type == C.DATA_TYPE_DATA) { - message = new DataSetMessage(useSyntax); - message.setElementPairs(pairs); + message.setElementPairs(pairs); + message.setDataSetPresent(message.getValue(0x00000800)); + message.setContextId(message.getValue(0x00000002)); + if (!message.isResponse()) { + message.setMessageId(message.getValue(0x00000110)); } else { - throw 'Unrecognized message type'; + message.setReplyMessageId(message.getValue(0x00000120)); } + } else if (type == C.DATA_TYPE_DATA) { + message = new DataSetMessage(useSyntax); + message.setElementPairs(pairs); + } else { + throw "Unrecognized message type"; + } + return message; +} - return message; +DataSetMessage = function(syntax){ + DicomMessage.call(this, syntax); + this.type = C.DATA_TYPE_DATA; }; - -DataSetMessage = function(syntax) { - DicomMessage.call(this, syntax); - this.type = C.DATA_TYPE_DATA; -}; - util.inherits(DataSetMessage, DicomMessage); DataSetMessage.prototype.is = function(type) { - return false; -}; + return false; +} CommandMessage = function(syntax) { - DicomMessage.call(this, syntax); - this.type = C.DATA_TYPE_COMMAND; - this.priority = C.PRIORITY_MEDIUM; - this.dataSetPresent = true; -}; - + DicomMessage.call(this, syntax); + this.type = C.DATA_TYPE_COMMAND; + this.priority = C.PRIORITY_MEDIUM; + this.dataSetPresent = true; +} util.inherits(CommandMessage, DicomMessage); CommandMessage.prototype.getFields = function() { - return this.command(CommandMessage.super_.prototype.getFields.call(this)); -}; + return this.command(CommandMessage.super_.prototype.getFields.call(this)); +} CommandResponse = function(syntax) { - DicomMessage.call(this, syntax); - this.type = C.DATA_TYPE_COMMAND; - this.dataSetPresent = true; + DicomMessage.call(this, syntax); + this.type = C.DATA_TYPE_COMMAND; + this.dataSetPresent = true; }; - util.inherits(CommandResponse, DicomMessage); CommandResponse.prototype.isResponse = function() { - return true; -}; + return true; +} CommandResponse.prototype.respondedTo = function() { - return this.getValue(0x00000120); -}; + return this.getValue(0x00000120); +} CommandResponse.prototype.isFinal = function() { - return this.success() || this.failure() || this.cancel(); -}; + return this.success() || this.failure() || this.cancel(); +} CommandResponse.prototype.warning = function() { - var status = this.getStatus(); - return (status == 0x0001) || (status >> 12 == 0xb); -}; + var status = this.getStatus(); + return (status == 0x0001) || (status >> 12 == 0xb); +} CommandResponse.prototype.success = function() { - return this.getStatus() == 0x0000; -}; + return this.getStatus() == 0x0000; +} CommandResponse.prototype.failure = function() { - var status = this.getStatus(); - return (status >> 12 == 0xa) || (status >> 12 == 0xc) || (status >> 8 == 0x1); -}; + var status = this.getStatus(); + return (status >> 12 == 0xa) || (status >> 12 == 0xc) || (status >> 8 == 0x1) +} CommandResponse.prototype.cancel = function() { - return this.getStatus() == C.STATUS_CANCEL; -}; + return this.getStatus() == C.STATUS_CANCEL; +} CommandResponse.prototype.pending = function() { - var status = this.getStatus(); - return (status == 0xff00) || (status == 0xff01); -}; + var status = this.getStatus(); + return (status == 0xff00) || (status == 0xff01); +} CommandResponse.prototype.getStatus = function() { - return this.getValue(0x00000900); -}; + return this.getValue(0x00000900); +} CommandResponse.prototype.setStatus = function(status) { - this.setElement(0x00000900, status); -}; + this.setElement(0x00000900, status); +} // following four methods only available to C-GET-RSP and C-MOVE-RSP CommandResponse.prototype.getNumOfRemainingSubOperations = function() { - return this.getValue(0x00001020); -}; + return this.getValue(0x00001020); +} CommandResponse.prototype.getNumOfCompletedSubOperations = function() { - return this.getValue(0x00001021); -}; + return this.getValue(0x00001021); +} CommandResponse.prototype.getNumOfFailedSubOperations = function() { - return this.getValue(0x00001022); -}; + return this.getValue(0x00001022); +} CommandResponse.prototype.getNumOfWarningSubOperations = function() { - return this.getValue(0x00001023); -}; + return this.getValue(0x00001023); +} //end CommandResponse.prototype.getFields = function() { - return this.response(CommandResponse.super_.prototype.getFields.call(this)); -}; + return this.response(CommandResponse.super_.prototype.getFields.call(this)); +} CFindRSP = function(syntax) { - CommandResponse.call(this, syntax); - this.commandType = 0x8020; + CommandResponse.call(this, syntax); + this.commandType = 0x8020; }; - util.inherits(CFindRSP, CommandResponse); CGetRSP = function(syntax) { - CommandResponse.call(this, syntax); - this.commandType = 0x8010; + CommandResponse.call(this, syntax); + this.commandType = 0x8010; }; - util.inherits(CGetRSP, CommandResponse); CMoveRSP = function(syntax) { - CommandResponse.call(this, syntax); - this.commandType = 0x8021; + CommandResponse.call(this, syntax); + this.commandType = 0x8021; }; - util.inherits(CMoveRSP, CommandResponse); CFindRQ = function(syntax) { - CommandMessage.call(this, syntax); - this.commandType = 0x20; - this.contextUID = C.SOP_STUDY_ROOT_FIND; + CommandMessage.call(this, syntax); + this.commandType = 0x20; + this.contextUID = C.SOP_STUDY_ROOT_FIND; }; - util.inherits(CFindRQ, CommandMessage); -CMoveRQ = function(syntax, destination) { - CommandMessage.call(this, syntax); - this.commandType = 0x21; - this.contextUID = C.SOP_STUDY_ROOT_MOVE; - this.setDestination(destination || ''); +CCancelRQ = function(syntax) { + CommandResponse.call(this, syntax); + this.commandType = 0x0fff; + this.contextUID = null; + this.dataSetPresent = false; }; +util.inherits(CCancelRQ, CommandResponse); +CCancelMoveRQ = function(syntax) { + CommandResponse.call(this, syntax); + this.commandType = 0x0fff; + this.contextUID = null; + this.dataSetPresent = false; +}; +util.inherits(CCancelMoveRQ, CommandResponse); + +CMoveRQ = function(syntax, destination) { + CommandMessage.call(this, syntax); + this.commandType = 0x21; + this.contextUID = C.SOP_STUDY_ROOT_MOVE; + this.setDestination(destination || ""); +}; util.inherits(CMoveRQ, CommandMessage); CMoveRQ.prototype.setStore = function(cstr) { - this.store = cstr; -}; + this.store = cstr; +} CMoveRQ.prototype.setDestination = function(dest) { - this.setElements({ - 0x00000600: dest - }); -}; + this.setElement(0x00000600, dest); +} CGetRQ = function(syntax) { - CommandMessage.call(this, syntax); - this.commandType = 0x10; - this.contextUID = C.SOP_STUDY_ROOT_GET; - this.store = null; + CommandMessage.call(this, syntax); + this.commandType = 0x10; + this.contextUID = C.SOP_STUDY_ROOT_GET; + this.store = null; }; - util.inherits(CGetRQ, CommandMessage); CGetRQ.prototype.setStore = function(cstr) { - this.store = cstr; -}; + this.store = cstr; +} CStoreRQ = function(syntax) { - CommandMessage.call(this, syntax); - this.commandType = 0x01; - this.contextUID = C.SOP_STUDY_ROOT_GET; + CommandMessage.call(this, syntax); + this.commandType = 0x01; + this.contextUID = C.SOP_STUDY_ROOT_GET; }; - util.inherits(CStoreRQ, CommandMessage); CStoreRQ.prototype.getOriginAETitle = function() { - return this.getValue(0x00001030); -}; + return this.getValue(0x00001030); +} CStoreRQ.prototype.getMoveMessageId = function() { - return this.getValue(0x00001031); -}; + return this.getValue(0x00001031); +} CStoreRQ.prototype.getSOPInstanceUID = function() { - return this.getValue(0x00001000); -}; + return this.getValue(0x00001000); +} CStoreRSP = function(syntax) { - CommandResponse.call(this, syntax); - this.commandType = 0x8001; - this.contextUID = C.SOP_STUDY_ROOT_GET; - this.dataSetPresent = false; + CommandResponse.call(this, syntax); + this.commandType = 0x8001; + this.contextUID = C.SOP_STUDY_ROOT_GET; + this.dataSetPresent = false; }; - util.inherits(CStoreRSP, CommandResponse); CStoreRSP.prototype.setAffectedSOPInstanceUID = function(uid) { - this.setElement(0x00001000, uid); -}; + this.setElement(0x00001000, uid); +} CStoreRSP.prototype.getAffectedSOPInstanceUID = function(uid) { - return this.getValue(0x00001000); -}; - \ No newline at end of file + return this.getValue(0x00001000); +} \ No newline at end of file diff --git a/Packages/dimseservice/server/PDU.js b/Packages/dimseservice/server/PDU.js index ea0e57e1b..85deb9203 100755 --- a/Packages/dimseservice/server/PDU.js +++ b/Packages/dimseservice/server/PDU.js @@ -1,675 +1,684 @@ PDU = function() { - this.fields = []; - this.lengthBytes = 4; -}; + this.fields = []; + this.lengthBytes = 4; +} PDU.prototype.length = function(fields) { - var len = 0; - fields.forEach(function(f) { - len += !f.getFields ? f.length() : f.length(f.getFields()); - }); - return len; -}; + var len = 0; + fields.forEach(function(f) { + len += !f.getFields ? f.length() : f.length(f.getFields()); + }); + return len; +} PDU.prototype.is = function(type) { - return this.type == type; -}; + return this.type == type; +} PDU.prototype.getFields = function(fields) { - var len = this.lengthField(fields); - fields.unshift(len); - if (this.type !== null) { - fields.unshift(new ReservedField()); - fields.unshift(new HexField(this.type)); - } + var len = this.lengthField(fields); + fields.unshift(len); + if (this.type !== null) { + fields.unshift(new ReservedField()); + fields.unshift(new HexField(this.type)); + } - return fields; -}; + return fields; +} PDU.prototype.lengthField = function(fields) { - if (this.lengthBytes == 4) { - return new UInt32Field(this.length(fields)); - } else if (this.lengthBytes == 2) { - return new UInt16Field(this.length(fields)); - } else { - throw 'Invalid length bytes'; - } -}; + if (this.lengthBytes == 4) { + return new UInt32Field(this.length(fields)); + } else if (this.lengthBytes == 2) { + return new UInt16Field(this.length(fields)); + } else { + throw "Invalid length bytes"; + } +} PDU.prototype.read = function(stream) { - stream.read(C.TYPE_HEX, 1); - var length = stream.read(C.TYPE_UINT32); - this.readBytes(stream, length); -}; + stream.read(C.TYPE_HEX, 1); + var length = stream.read(C.TYPE_UINT32); + this.readBytes(stream, length); +} PDU.prototype.load = function(stream) { - return pduByStream(stream); -}; + return PDU.createByStream(stream); +} PDU.prototype.loadPDV = function(stream, length) { - if (stream.end()) return false; - var bytesRead = 0, pdvs = []; - while (bytesRead < length) { - var plength = stream.read(C.TYPE_UINT32), - pdv = new PresentationDataValueItem(); - pdv.readBytes(stream, plength); - bytesRead += plength + 4; + if (stream.end()) return false; + var bytesRead = 0, pdvs = []; + while (bytesRead < length) { + var plength = stream.read(C.TYPE_UINT32), + pdv = new PresentationDataValueItem(); + pdv.readBytes(stream, plength); + bytesRead += plength + 4; - pdvs.push(pdv); - } + pdvs.push(pdv); + } - return pdvs; -}; + return pdvs; +} PDU.prototype.loadDicomMessage = function(stream, isCommand, isLast) { - var message = readMessage(stream, isCommand, isLast); - return message; -}; + var message = DicomMessage.read(stream, isCommand, isLast); + return message; +} PDU.prototype.stream = function() { - var stream = new WriteStream(), - fields = this.getFields(); + var stream = new WriteStream(), + fields = this.getFields(); - // writing to buffer - fields.forEach(function(field) { - field.write(stream); - }); + // writing to buffer + fields.forEach(function(field){ + field.write(stream); + }); - return stream; -}; + return stream; +} PDU.prototype.buffer = function() { - return this.stream().buffer(); -}; + return this.stream().buffer(); +} var interpretCommand = function(stream, isLast) { - parseDicomMessage(stream); -}; + parseDicomMessage(stream); +} mergePDVs = function(pdvs) { - var merges = [], count = pdvs.length, i = 0; - while (i < count) {console.log(pdvs[i].isLast, pdvs[i].type); - if (!pdvs[i].isLast) { - var j = i; - while (!pdvs[j++].isLast && j < count) { - pdvs[i].messageStream.concat(pdvs[j].messageStream); - } - - merges.push(pdvs[i]); - i = j; - } else { - merges.push(pdvs[i++]); - } + var merges = [], count = pdvs.length, i = 0; + while (i < count) {console.log(pdvs[i].isLast, pdvs[i].type); + if (!pdvs[i].isLast) { + var j = i; + while (!pdvs[j++].isLast && j < count) { + pdvs[i].messageStream.concat(pdvs[j].messageStream); + } + merges.push(pdvs[i]); + i = j; + } else { + merges.push(pdvs[i++]); } + } + return merges; +} - return merges; -}; +PDU.typeToString = function(type) { + var pdu = null, typeNum = parseInt(type, 16); + //console.log("RECEIVED PDU-TYPE ", typeNum); + switch (typeNum) { + case 0x01 : pdu = 'ASSOCIATE-RQ'; break; + case 0x02 : pdu = 'ASSOCIATE-AC'; break; + case 0x04 : pdu = 'P-DATA-TF'; break; + case 0x06 : pdu = 'RELEASE-RP'; break; + case 0x07 : pdu = 'ASSOCIATE-ABORT'; break; + case 0x10 : pdu = 'APPLICATION-CONTEXT-ITEM'; break; + case 0x20 : pdu = 'PRESENTATION-CONTEXT-ITEM'; break; + case 0x21 : pdu = 'PRESENTATION-CONTEXT-ITEM-AC'; break; + case 0x30 : pdu = 'ABSTRACT-SYNTAX-ITEM'; break; + case 0x40 : pdu = 'TRANSFER-SYNTAX-ITEM'; break; + case 0x50 : pdu = 'USER-INFORMATION-ITEM'; break; + case 0x51 : pdu = 'MAXIMUM-LENGTH-ITEM'; break; + case 0x52 : pdu = 'IMPLEMENTATION-CLASS-UID-ITEM'; break; + case 0x55 : pdu = 'IMPLEMENTATION-VERSION-NAME-ITEM'; break; + default : break; + } -pduByStream = function(stream) { - if (stream.end()) return null; + return pdu; +} - var pduType = stream.read(C.TYPE_HEX, 1), typeNum = parseInt(pduType, 16), pdu = null; - //console.log("RECEIVED PDU-TYPE ", pduType); - switch (typeNum) { - case 0x01 : pdu = new AssociateRQ(); break; - case 0x02 : pdu = new AssociateAC(); break; - case 0x04 : pdu = new PDataTF(); break; - case 0x06 : pdu = new ReleaseRP(); break; - case 0x07 : pdu = new AssociateAbort(); break; - case 0x10 : pdu = new ApplicationContextItem(); break; - case 0x20 : pdu = new PresentationContextItem(); break; - case 0x21 : pdu = new PresentationContextItemAC(); break; - case 0x30 : pdu = new AbstractSyntaxItem(); break; - case 0x40 : pdu = new TransferSyntaxItem(); break; - case 0x50 : pdu = new UserInformationItem(); break; - case 0x51 : pdu = new MaximumLengthItem(); break; - case 0x52 : pdu = new ImplementationClassUIDItem(); break; - case 0x55 : pdu = new ImplementationVersionNameItem(); break; - default : throw 'Unrecoginized pdu type ' + pduType; break; - } - if (pdu) - pdu.read(stream); +PDU.createByStream = function(stream) { + if (stream.end()) return null; - return pdu; -}; + var pduType = stream.read(C.TYPE_HEX, 1), typeNum = parseInt(pduType, 16), pdu = null; + //console.log("RECEIVED PDU-TYPE ", pduType); + switch (typeNum) { + case 0x01 : pdu = new AssociateRQ(); break; + case 0x02 : pdu = new AssociateAC(); break; + case 0x04 : pdu = new PDataTF(); break; + case 0x06 : pdu = new ReleaseRP(); break; + case 0x07 : pdu = new AssociateAbort(); break; + case 0x10 : pdu = new ApplicationContextItem(); break; + case 0x20 : pdu = new PresentationContextItem(); break; + case 0x21 : pdu = new PresentationContextItemAC(); break; + case 0x30 : pdu = new AbstractSyntaxItem(); break; + case 0x40 : pdu = new TransferSyntaxItem(); break; + case 0x50 : pdu = new UserInformationItem(); break; + case 0x51 : pdu = new MaximumLengthItem(); break; + case 0x52 : pdu = new ImplementationClassUIDItem(); break; + case 0x55 : pdu = new ImplementationVersionNameItem(); break; + default : throw "Unrecoginized pdu type " + pduType; break; + } + if (pdu) + pdu.read(stream); + + return pdu; +} var nextItemIs = function(stream, pduType) { - if (stream.end()) return false; + if (stream.end()) return false; - var nextType = stream.read(C.TYPE_HEX, 1); - stream.increment(-1); - return pduType == nextType; -}; + var nextType = stream.read(C.TYPE_HEX, 1); + stream.increment(-1); + return pduType == nextType; +} AssociateRQ = function() { - PDU.call(this); - this.type = C.ITEM_TYPE_PDU_ASSOCIATE_RQ; - this.protocolVersion = 1; -}; + PDU.call(this); + this.type = C.ITEM_TYPE_PDU_ASSOCIATE_RQ; + this.protocolVersion = 1; +} util.inherits(AssociateRQ, PDU); AssociateRQ.prototype.setProtocolVersion = function(version) { - this.protocolVersion = version; -}; + this.protocolVersion = version; +} AssociateRQ.prototype.setCalledAETitle = function(title) { - this.calledAETitle = title; -}; + this.calledAETitle = title; +} AssociateRQ.prototype.setCallingAETitle = function(title) { - this.callingAETitle = title; -}; + this.callingAETitle = title; +} AssociateRQ.prototype.setApplicationContextItem = function(item) { - this.applicationContextItem = item; -}; + this.applicationContextItem = item; +} AssociateRQ.prototype.setPresentationContextItems = function(items) { - this.presentationContextItems = items; -}; + this.presentationContextItems = items; +} AssociateRQ.prototype.setUserInformationItem = function(item) { - this.userInformationItem = item; -}; + this.userInformationItem = item; +} AssociateRQ.prototype.allAccepted = function() { - for (var i in this.presentationContextItems) { - var item = this.presentationContextItems[i]; - if (!item.accepted()) return false; - } - - return true; -}; + for (var i in this.presentationContextItems) { + var item = this.presentationContextItems[i]; + if (!item.accepted()) return false; + } + return true; +} AssociateRQ.prototype.getFields = function() { - var f = [ - new UInt16Field(this.protocolVersion), new ReservedField(2), - new FilledField(this.calledAETitle, 16), new FilledField(this.callingAETitle, 16), - new ReservedField(32), this.applicationContextItem - ]; - this.presentationContextItems.forEach(function(context) { - f.push(context); - }); - f.push(this.userInformationItem); - return AssociateRQ.super_.prototype.getFields.call(this, f); -}; + var f = [ + new UInt16Field(this.protocolVersion), new ReservedField(2), + new FilledField(this.calledAETitle, 16), new FilledField(this.callingAETitle, 16), + new ReservedField(32), this.applicationContextItem + ]; + this.presentationContextItems.forEach(function(context){ + f.push(context); + }); + f.push(this.userInformationItem); + return AssociateRQ.super_.prototype.getFields.call(this, f); +} AssociateRQ.prototype.readBytes = function(stream, length) { - this.type = C.ITEM_TYPE_PDU_ASSOCIATE_RQ; - var version = stream.read(C.TYPE_UINT16); - this.setProtocolVersion(version); - stream.increment(2); - var calledAE = stream.read(C.TYPE_ASCII, 16); - this.setCalledAETitle(calledAE); - var callingAE = stream.read(C.TYPE_ASCII, 16); - this.setCallingAETitle(callingAE); - stream.increment(32); + this.type = C.ITEM_TYPE_PDU_ASSOCIATE_RQ; + var version = stream.read(C.TYPE_UINT16); + this.setProtocolVersion(version); + stream.increment(2); + var calledAE = stream.read(C.TYPE_ASCII, 16); + this.setCalledAETitle(calledAE); + var callingAE = stream.read(C.TYPE_ASCII, 16); + this.setCallingAETitle(callingAE); + stream.increment(32); - var appContext = this.load(stream); - this.setApplicationContextItem(appContext); + var appContext = this.load(stream); + this.setApplicationContextItem(appContext); - var presContexts = []; - do { - presContexts.push(this.load(stream)); - } while (nextItemIs(stream, C.ITEM_TYPE_PRESENTATION_CONTEXT_AC)); - this.setPresentationContextItems(presContexts); + var presContexts = []; + do { + presContexts.push(this.load(stream)); + } while (nextItemIs(stream, C.ITEM_TYPE_PRESENTATION_CONTEXT)); + this.setPresentationContextItems(presContexts); - var userItem = this.load(stream); - this.setUserInformationItem(userItem); -}; + var userItem = this.load(stream); + this.setUserInformationItem(userItem); +} AssociateRQ.prototype.buffer = function() { - return AssociateRQ.super_.prototype.buffer.call(this); -}; + return AssociateRQ.super_.prototype.buffer.call(this); +} AssociateAC = function() { - AssociateRQ.call(this); + AssociateRQ.call(this); }; util.inherits(AssociateAC, AssociateRQ); AssociateAC.prototype.readBytes = function(stream, length) { - this.type = C.ITEM_TYPE_PDU_ASSOCIATE_AC; - var version = stream.read(C.TYPE_UINT16); - this.setProtocolVersion(version); - stream.increment(66); + this.type = C.ITEM_TYPE_PDU_ASSOCIATE_AC; + var version = stream.read(C.TYPE_UINT16); + this.setProtocolVersion(version); + stream.increment(66); - var appContext = this.load(stream); - this.setApplicationContextItem(appContext); + var appContext = this.load(stream); + this.setApplicationContextItem(appContext); - var presContexts = []; - do { - presContexts.push(this.load(stream)); - } while (nextItemIs(stream, C.ITEM_TYPE_PRESENTATION_CONTEXT_AC)); - this.setPresentationContextItems(presContexts); + var presContexts = []; + do { + presContexts.push(this.load(stream)); + } while (nextItemIs(stream, C.ITEM_TYPE_PRESENTATION_CONTEXT_AC)); + this.setPresentationContextItems(presContexts); - var userItem = this.load(stream); - this.setUserInformationItem(userItem); -}; + var userItem = this.load(stream); + this.setUserInformationItem(userItem); +} AssociateAbort = function() { - this.type = C.ITEM_TYPE_PDU_AABORT; - this.source = 1; - this.reason = 0; - PDU.call(this); -}; + this.type = C.ITEM_TYPE_PDU_AABORT; + this.source = 1; + this.reason = 0; + PDU.call(this); +} util.inherits(AssociateAbort, PDU); AssociateAbort.prototype.setSource = function(src) { - this.source = src; -}; + this.source = src; +} AssociateAbort.prototype.setReason = function(reason) { - this.reason = reason; -}; + this.reason = reason; +} AssociateAbort.prototype.readBytes = function(stream, length) { - stream.increment(2); + stream.increment(2); - var source = stream.read(C.TYPE_UINT8); - this.setSource(source); + var source = stream.read(C.TYPE_UINT8); + this.setSource(source); - var reason = stream.read(C.TYPE_UINT8); - this.setReason(reason); -}; + var reason = stream.read(C.TYPE_UINT8); + this.setReason(reason); +} AssociateAbort.prototype.getFields = function() { - return AssociateAbort.super_.prototype.getFields.call(this, [ - new ReservedField(), new ReservedField(), - new UInt8Field(this.source), new UInt8Field(this.reason) - ]); -}; + return AssociateAbort.super_.prototype.getFields.call(this, [ + new ReservedField(), new ReservedField(), + new UInt8Field(this.source), new UInt8Field(this.reason) + ]); +} ReleaseRQ = function() { - this.type = C.ITEM_TYPE_PDU_RELEASE_RQ; - PDU.call(this); + this.type = C.ITEM_TYPE_PDU_RELEASE_RQ; + PDU.call(this); }; util.inherits(ReleaseRQ, PDU); ReleaseRQ.prototype.getFields = function() { - return ReleaseRQ.super_.prototype.getFields.call(this, [ new ReservedField(4) ]); + return ReleaseRQ.super_.prototype.getFields.call(this, [new ReservedField(4)]); }; ReleaseRP = function() { - this.type = C.ITEM_TYPE_PDU_RELEASE_RP; - PDU.call(this); -}; + this.type = C.ITEM_TYPE_PDU_RELEASE_RP; + PDU.call(this); +} util.inherits(ReleaseRP, PDU); ReleaseRP.prototype.readBytes = function(stream, length) { - stream.increment(4); + stream.increment(4); }; ReleaseRP.prototype.getFields = function() { - return ReleaseRP.super_.prototype.getFields.call(this, [ new ReservedField(4) ]); -}; + return ReleaseRP.super_.prototype.getFields.call(this, [new ReservedField(4)]); +} PDataTF = function() { - this.type = C.ITEM_TYPE_PDU_PDATA; - this.presentationDataValueItems = []; - PDU.call(this); -}; - + this.type = C.ITEM_TYPE_PDU_PDATA; + this.presentationDataValueItems = []; + PDU.call(this); +} util.inherits(PDataTF, PDU); PDataTF.prototype.setPresentationDataValueItems = function(items) { - this.presentationDataValueItems = items ? items : []; -}; + this.presentationDataValueItems = items ? items : []; +} PDataTF.prototype.getFields = function() { - var fields = this.presentationDataValueItems; + var fields = this.presentationDataValueItems; - return PDataTF.super_.prototype.getFields.call(this, fields); -}; + return PDataTF.super_.prototype.getFields.call(this, fields); +} PDataTF.prototype.readBytes = function(stream, length) { - var pdvs = this.loadPDV(stream, length); - //let merges = mergePDVs(pdvs); + var pdvs = this.loadPDV(stream, length); + //let merges = mergePDVs(pdvs); - this.setPresentationDataValueItems(pdvs); -}; + this.setPresentationDataValueItems(pdvs); +} Item = function() { - PDU.call(this); - this.lengthBytes = 2; + PDU.call(this); + this.lengthBytes = 2; }; - util.inherits(Item, PDU); Item.prototype.read = function(stream) { - stream.read(C.TYPE_HEX, 1); - var length = stream.read(C.TYPE_UINT16); - this.readBytes(stream, length); -}; + stream.read(C.TYPE_HEX, 1); + var length = stream.read(C.TYPE_UINT16); + this.readBytes(stream, length); +} Item.prototype.write = function(stream) { - stream.concat(this.stream()); -}; + stream.concat(this.stream()); +} Item.prototype.getFields = function(fields) { - return Item.super_.prototype.getFields.call(this, fields); -}; + return Item.super_.prototype.getFields.call(this, fields); +} PresentationDataValueItem = function(context) { - this.type = null; - this.isLast = true; - this.dataFragment = null; - this.contextId = context; - this.messageStream = null; - Item.call(this); + this.type = null; + this.isLast = true; + this.dataFragment = null; + this.contextId = context; + this.messageStream = null; + Item.call(this); - this.lengthBytes = 4; + this.lengthBytes = 4; }; - util.inherits(PresentationDataValueItem, Item); PresentationDataValueItem.prototype.setContextId = function(id) { - this.contextId = id; -}; + this.contextId = id; +} PresentationDataValueItem.prototype.setFlag = function(flag) { - this.flag = flag; -}; + this.flag = flag; +} PresentationDataValueItem.prototype.setPresentationDataValue = function(pdv) { - this.pdv = pdv; -}; + this.pdv = pdv; +} PresentationDataValueItem.prototype.setMessage = function(msg) { - this.dataFragment = msg; -}; + this.dataFragment = msg; +} PresentationDataValueItem.prototype.getMessage = function() { - return this.dataFragment; -}; + return this.dataFragment; +} PresentationDataValueItem.prototype.readBytes = function(stream, length) { - this.contextId = stream.read(C.TYPE_UINT8); - var messageHeader = stream.read(C.TYPE_UINT8); - this.isLast = messageHeader >> 1; - this.type = messageHeader & 1 ? C.DATA_TYPE_COMMAND : C.DATA_TYPE_DATA; + this.contextId = stream.read(C.TYPE_UINT8); + var messageHeader = stream.read(C.TYPE_UINT8); + this.isLast = messageHeader >> 1; + this.type = messageHeader & 1 ? C.DATA_TYPE_COMMAND : C.DATA_TYPE_DATA; - //load dicom messages - this.messageStream = stream.more(length - 2); -}; + //load dicom messages + this.messageStream = stream.more(length - 2); +} PresentationDataValueItem.prototype.getFields = function() { - var fields = [ new UInt8Field(this.contextId) ]; - //define header - var messageHeader = (1 & this.dataFragment.type) | ((this.isLast ? 1 : 0) << 1); - fields.push(new UInt8Field(messageHeader)); + var fields = [new UInt8Field(this.contextId)]; + //define header + var messageHeader = (1 & this.dataFragment.type) | ((this.isLast ? 1 : 0) << 1); + fields.push(new UInt8Field(messageHeader)); - fields.push(this.dataFragment); - /*var stream = new WriteStream();this.dataFragment.write(stream); - //var f = this.dataFragment.getFields(); - //var wr = new WriteStream();f[0].setSyntax(this.dataFragment.syntax);f[0].write(wr); - var rst = stream.toReadBuffer(); - rst.setEndian(C.LITTLE_ENDIAN); - var group = rst.read(C.TYPE_UINT16), - element = rst.read(C.TYPE_UINT16), - tag = tagFromNumbers(group, element); + fields.push(this.dataFragment); +/*var stream = new WriteStream();this.dataFragment.write(stream); +//var f = this.dataFragment.getFields(); +//var wr = new WriteStream();f[0].setSyntax(this.dataFragment.syntax);f[0].write(wr); +var rst = stream.toReadBuffer(); +rst.setEndian(C.LITTLE_ENDIAN); + var group = rst.read(C.TYPE_UINT16), + element = rst.read(C.TYPE_UINT16), + tag = tagFromNumbers(group, element); - console.log(tag.toString(), rst.read(C.TYPE_UINT32));*/ - return PresentationDataValueItem.super_.prototype.getFields.call(this, fields); -}; + console.log(tag.toString(), rst.read(C.TYPE_UINT32));*/ + return PresentationDataValueItem.super_.prototype.getFields.call(this, fields); +} ApplicationContextItem = function() { - this.type = C.ITEM_TYPE_APPLICATION_CONTEXT; - this.applicationContextName = C.APPLICATION_CONTEXT_NAME; - Item.call(this); -}; - + this.type = C.ITEM_TYPE_APPLICATION_CONTEXT; + this.applicationContextName = C.APPLICATION_CONTEXT_NAME; + Item.call(this); +} util.inherits(ApplicationContextItem, Item); ApplicationContextItem.prototype.setApplicationContextName = function(name) { - this.applicationContextName = name; -}; + this.applicationContextName = name; +} ApplicationContextItem.prototype.getFields = function() { - return ApplicationContextItem.super_.prototype.getFields.call(this, [ new StringField(this.applicationContextName) ]); -}; + return ApplicationContextItem.super_.prototype.getFields.call(this, [new StringField(this.applicationContextName)]); +} ApplicationContextItem.prototype.readBytes = function(stream, length) { - var appContext = stream.read(C.TYPE_ASCII, length); - this.setApplicationContextName(appContext); -}; + var appContext = stream.read(C.TYPE_ASCII, length); + this.setApplicationContextName(appContext); +} ApplicationContextItem.prototype.buffer = function() { - return ApplicationContextItem.super_.prototype.buffer.call(this); -}; + return ApplicationContextItem.super_.prototype.buffer.call(this); +} PresentationContextItem = function() { - this.type = C.ITEM_TYPE_PRESENTATION_CONTEXT; - Item.call(this); + this.type = C.ITEM_TYPE_PRESENTATION_CONTEXT; + Item.call(this); }; - util.inherits(PresentationContextItem, Item); PresentationContextItem.prototype.setPresentationContextID = function(id) { - this.presentationContextID = id; -}; + this.presentationContextID = id; +} PresentationContextItem.prototype.setAbstractSyntaxItem = function(item) { - this.abstractSyntaxItem = item; -}; + this.abstractSyntaxItem = item; +} PresentationContextItem.prototype.setTransferSyntaxesItems = function(items) { - this.transferSyntaxesItems = items; -}; + this.transferSyntaxesItems = items; +} PresentationContextItem.prototype.setResultReason = function(reason) { - this.resultReason = reason; -}; + this.resultReason = reason; +} PresentationContextItem.prototype.accepted = function() { - return this.resultReason == 0; -}; + return this.resultReason == 0; +} PresentationContextItem.prototype.readBytes = function(stream, length) { - var contextId = stream.read(C.TYPE_UINT8); - this.setPresentationContextID(contextId); - stream.increment(1); - stream.increment(1); - stream.increment(1); + var contextId = stream.read(C.TYPE_UINT8); + this.setPresentationContextID(contextId); + stream.increment(1); + stream.increment(1); + stream.increment(1); - var abstractItem = this.load(stream); - this.setAbstractSyntaxItem(abstractItem); + var abstractItem = this.load(stream); + this.setAbstractSyntaxItem(abstractItem); - var transContexts = []; - do { - transContexts.push(this.load(stream)); - } while (nextItemIs(stream, C.ITEM_TYPE_TRANSFER_CONTEXT)); - this.setTransferSyntaxesItems(transContexts); -}; + var transContexts = []; + do { + transContexts.push(this.load(stream)); + } while (nextItemIs(stream, C.ITEM_TYPE_TRANSFER_CONTEXT)); + this.setTransferSyntaxesItems(transContexts); +} PresentationContextItem.prototype.getFields = function() { - var f = [ - new UInt8Field(this.presentationContextID), - new ReservedField(), new ReservedField(), new ReservedField(), this.abstractSyntaxItem - ]; - this.transferSyntaxesItems.forEach(function(syntaxItem) { - f.push(syntaxItem); - }); - return PresentationContextItem.super_.prototype.getFields.call(this, f); -}; + var f = [ + new UInt8Field(this.presentationContextID), + new ReservedField(), new ReservedField(), new ReservedField(), this.abstractSyntaxItem + ]; + this.transferSyntaxesItems.forEach(function(syntaxItem){ + f.push(syntaxItem); + }); + return PresentationContextItem.super_.prototype.getFields.call(this, f); +} PresentationContextItem.prototype.buffer = function() { - return PresentationContextItem.super_.prototype.buffer.call(this); -}; + return PresentationContextItem.super_.prototype.buffer.call(this); +} PresentationContextItemAC = function() { - this.type = C.ITEM_TYPE_PRESENTATION_CONTEXT_AC; - Item.call(this); + this.type = C.ITEM_TYPE_PRESENTATION_CONTEXT_AC; + Item.call(this); }; - util.inherits(PresentationContextItemAC, PresentationContextItem); PresentationContextItemAC.prototype.readBytes = function(stream, length) { - var contextId = stream.read(C.TYPE_UINT8); - this.setPresentationContextID(contextId); - stream.increment(1); - var resultReason = stream.read(C.TYPE_UINT8); - this.setResultReason(resultReason); - stream.increment(1); + var contextId = stream.read(C.TYPE_UINT8); + this.setPresentationContextID(contextId); + stream.increment(1); + var resultReason = stream.read(C.TYPE_UINT8); + this.setResultReason(resultReason); + stream.increment(1); - var transItem = this.load(stream); - this.setTransferSyntaxesItems([ transItem ]); -}; + var transItem = this.load(stream); + this.setTransferSyntaxesItems([transItem]); +} AbstractSyntaxItem = function() { - this.type = C.ITEM_TYPE_ABSTRACT_CONTEXT; - Item.call(this); -}; - + this.type = C.ITEM_TYPE_ABSTRACT_CONTEXT; + Item.call(this); +} util.inherits(AbstractSyntaxItem, Item); AbstractSyntaxItem.prototype.setAbstractSyntaxName = function(name) { - this.abstractSyntaxName = name; -}; + this.abstractSyntaxName = name; +} AbstractSyntaxItem.prototype.getFields = function() { - return AbstractSyntaxItem.super_.prototype.getFields.call(this, [ new StringField(this.abstractSyntaxName) ]); -}; + return AbstractSyntaxItem.super_.prototype.getFields.call(this, [new StringField(this.abstractSyntaxName)]); +} AbstractSyntaxItem.prototype.buffer = function() { - return AbstractSyntaxItem.super_.prototype.buffer.call(this); -}; + return AbstractSyntaxItem.super_.prototype.buffer.call(this); +} AbstractSyntaxItem.prototype.readBytes = function(stream, length) { - var name = stream.read(C.TYPE_ASCII, length); - this.setAbstractSyntaxName(name); -}; + var name = stream.read(C.TYPE_ASCII, length); + this.setAbstractSyntaxName(name); +} TransferSyntaxItem = function() { - this.type = C.ITEM_TYPE_TRANSFER_CONTEXT; - Item.call(this); + this.type = C.ITEM_TYPE_TRANSFER_CONTEXT; + Item.call(this); }; - util.inherits(TransferSyntaxItem, Item); TransferSyntaxItem.prototype.setTransferSyntaxName = function(name) { - this.transferSyntaxName = name; -}; + this.transferSyntaxName = name; +} TransferSyntaxItem.prototype.readBytes = function(stream, length) { - var transfer = stream.read(C.TYPE_ASCII, length); - this.setTransferSyntaxName(transfer); -}; + var transfer = stream.read(C.TYPE_ASCII, length); + this.setTransferSyntaxName(transfer); +} TransferSyntaxItem.prototype.getFields = function() { - return TransferSyntaxItem.super_.prototype.getFields.call(this, [ new StringField(this.transferSyntaxName) ]); -}; + return TransferSyntaxItem.super_.prototype.getFields.call(this, [new StringField(this.transferSyntaxName)]); +} TransferSyntaxItem.prototype.buffer = function() { - return TransferSyntaxItem.super_.prototype.buffer.call(this); -}; + return TransferSyntaxItem.super_.prototype.buffer.call(this); +} UserInformationItem = function() { - this.type = C.ITEM_TYPE_USER_INFORMATION; - Item.call(this); + this.type = C.ITEM_TYPE_USER_INFORMATION; + Item.call(this); }; - util.inherits(UserInformationItem, Item); UserInformationItem.prototype.setUserDataItems = function(items) { - this.userDataItems = items; -}; + this.userDataItems = items; +} UserInformationItem.prototype.readBytes = function(stream, length) { - var items = [], pdu = this.load(stream); + var items = [], pdu = this.load(stream); - do { - items.push(pdu); - } while (pdu = this.load(stream)); - this.setUserDataItems(items); -}; + do { + items.push(pdu); + } while (pdu = this.load(stream)); + this.setUserDataItems(items); +} UserInformationItem.prototype.getFields = function() { - var f = []; - this.userDataItems.forEach(function(userData) { - f.push(userData); - }); - return UserInformationItem.super_.prototype.getFields.call(this, f); -}; + var f = []; + this.userDataItems.forEach(function(userData){ + f.push(userData); + }); + return UserInformationItem.super_.prototype.getFields.call(this, f); +} UserInformationItem.prototype.buffer = function() { - return UserInformationItem.super_.prototype.buffer.call(this); -}; + return UserInformationItem.super_.prototype.buffer.call(this); +} ImplementationClassUIDItem = function() { - this.type = C.ITEM_TYPE_IMPLEMENTATION_UID; - Item.call(this); -}; - + this.type = C.ITEM_TYPE_IMPLEMENTATION_UID; + Item.call(this); +} util.inherits(ImplementationClassUIDItem, Item); ImplementationClassUIDItem.prototype.setImplementationClassUID = function(id) { - this.implementationClassUID = id; -}; + this.implementationClassUID = id; +} ImplementationClassUIDItem.prototype.readBytes = function(stream, length) { - var uid = stream.read(C.TYPE_ASCII, length); - this.setImplementationClassUID(uid); -}; + var uid = stream.read(C.TYPE_ASCII, length); + this.setImplementationClassUID(uid); +} ImplementationClassUIDItem.prototype.getFields = function() { - return ImplementationClassUIDItem.super_.prototype.getFields.call(this, [ new StringField(this.implementationClassUID) ]); -}; + return ImplementationClassUIDItem.super_.prototype.getFields.call(this, [new StringField(this.implementationClassUID)]); +} ImplementationClassUIDItem.prototype.buffer = function() { - return ImplementationClassUIDItem.super_.prototype.buffer.call(this); -}; + return ImplementationClassUIDItem.super_.prototype.buffer.call(this); +} ImplementationVersionNameItem = function() { - this.type = C.ITEM_TYPE_IMPLEMENTATION_VERSION; - Item.call(this); -}; - + this.type = C.ITEM_TYPE_IMPLEMENTATION_VERSION; + Item.call(this); +} util.inherits(ImplementationVersionNameItem, Item); ImplementationVersionNameItem.prototype.setImplementationVersionName = function(name) { - this.implementationVersionName = name; -}; + this.implementationVersionName = name; +} ImplementationVersionNameItem.prototype.readBytes = function(stream, length) { - var name = stream.read(C.TYPE_ASCII, length); - this.setImplementationVersionName(name); -}; + var name = stream.read(C.TYPE_ASCII, length); + this.setImplementationVersionName(name); +} ImplementationVersionNameItem.prototype.getFields = function() { - return ImplementationVersionNameItem.super_.prototype.getFields.call(this, [ new StringField(this.implementationVersionName) ]); -}; + return ImplementationVersionNameItem.super_.prototype.getFields.call(this, [new StringField(this.implementationVersionName)]); +} ImplementationVersionNameItem.prototype.buffer = function() { - return ImplementationVersionNameItem.super_.prototype.buffer.call(this); -}; + return ImplementationVersionNameItem.super_.prototype.buffer.call(this); +} MaximumLengthItem = function() { - this.type = C.ITEM_TYPE_MAXIMUM_LENGTH; - this.maximumLengthReceived = 32768; - Item.call(this); -}; - + this.type = C.ITEM_TYPE_MAXIMUM_LENGTH; + this.maximumLengthReceived = 32768; + Item.call(this); +} util.inherits(MaximumLengthItem, Item); MaximumLengthItem.prototype.setMaximumLengthReceived = function(length) { - this.maximumLengthReceived = length; -}; + this.maximumLengthReceived = length; +} MaximumLengthItem.prototype.readBytes = function(stream, length) { - var l = stream.read(C.TYPE_UINT32); - this.setMaximumLengthReceived(l); -}; + var l = stream.read(C.TYPE_UINT32); + this.setMaximumLengthReceived(l); +} MaximumLengthItem.prototype.getFields = function() { - return MaximumLengthItem.super_.prototype.getFields.call(this, [ new UInt32Field(this.maximumLengthReceived) ]); -}; + return MaximumLengthItem.super_.prototype.getFields.call(this, [new UInt32Field(this.maximumLengthReceived)]); +} MaximumLengthItem.prototype.buffer = function() { - return MaximumLengthItem.super_.prototype.buffer.call(this); -}; + return MaximumLengthItem.super_.prototype.buffer.call(this); +} diff --git a/Packages/dimseservice/server/RWStream.js b/Packages/dimseservice/server/RWStream.js index c54af8300..8c8d4e37a 100755 --- a/Packages/dimseservice/server/RWStream.js +++ b/Packages/dimseservice/server/RWStream.js @@ -1,229 +1,229 @@ var isString = function(type) { - if (type == C.TYPE_ASCII || type == C.TYPE_HEX) { - return true; - } else return false; + if (type == C.TYPE_ASCII || type == C.TYPE_HEX) { + return true; + } else return false; }; calcLength = function(type, value) { - var size = NaN; - switch (type) { - case C.TYPE_HEX : size = Buffer.byteLength(value, 'hex'); break; - case C.TYPE_ASCII : size = Buffer.byteLength(value, 'ascii'); break; - case C.TYPE_UINT8 : size = 1; break; - case C.TYPE_UINT16 : size = 2; break; - case C.TYPE_UINT32 : size = 4; break; - case C.TYPE_FLOAT : size = 4; break; - case C.TYPE_DOUBLE : size = 8; break; - case C.TYPE_INT8 : size = 1; break; - case C.TYPE_INT16 : size = 2; break; - case C.TYPE_INT32 : size = 4; break; - default :break; - } - return size; -}; + var size = NaN; + switch (type) { + case C.TYPE_HEX : size = Buffer.byteLength(value, 'hex'); break; + case C.TYPE_ASCII : size = Buffer.byteLength(value, 'ascii'); break; + case C.TYPE_UINT8 : size = 1; break; + case C.TYPE_UINT16 : size = 2; break; + case C.TYPE_UINT32 : size = 4; break; + case C.TYPE_FLOAT : size = 4; break; + case C.TYPE_DOUBLE : size = 8; break; + case C.TYPE_INT8 : size = 1; break; + case C.TYPE_INT16 : size = 2; break; + case C.TYPE_INT32 : size = 4; break; + default :break; + } + return size; +} var RWStream = function() { - this.endian = C.BIG_ENDIAN; + this.endian = C.BIG_ENDIAN; }; RWStream.prototype.setEndian = function(endian) { - this.endian = endian; -}; + this.endian = endian; +} RWStream.prototype.getEncoding = function(type) { - return RWStream.encodings[type]; -}; + return RWStream.encodings[type]; +} RWStream.prototype.getWriteType = function(type) { - return RWStream.writes[this.endian][type]; -}; + return RWStream.writes[this.endian][type]; +} RWStream.prototype.getReadType = function(type) { - return RWStream.reads[this.endian][type]; -}; + return RWStream.reads[this.endian][type]; +} WriteStream = function() { - RWStream.call(this); - this.defaultBufferSize = 512; //512 bytes - this.rawBuffer = new Buffer(this.defaultBufferSize); - this.offset = 0; - this.contentSize = 0; -}; + RWStream.call(this); + this.defaultBufferSize = 512; //512 bytes + this.rawBuffer = new Buffer(this.defaultBufferSize); + this.offset = 0; + this.contentSize = 0; +} util.inherits(WriteStream, RWStream); WriteStream.prototype.increment = function(add) { - this.offset += add; - if (this.offset > this.contentSize) { - this.contentSize = this.offset; - } -}; + this.offset += add; + if (this.offset > this.contentSize) { + this.contentSize = this.offset; + } +} WriteStream.prototype.size = function() { - return this.contentSize; -}; + return this.contentSize; +} WriteStream.prototype.skip = function(amount) { - this.increment(amount); -}; + this.increment(amount); +} WriteStream.prototype.checkSize = function(length) { - if (this.offset + length > this.rawBuffer.length) { - // we need more size, copying old one to new buffer - var oldLength = this.rawBuffer.length, - newBuffer = new Buffer(oldLength + length + (oldLength / 2)); - this.rawBuffer.copy(newBuffer, 0, 0, this.contentSize); - this.rawBuffer = newBuffer; - } -}; + if (this.offset + length > this.rawBuffer.length) { + // we need more size, copying old one to new buffer + var oldLength = this.rawBuffer.length, + newBuffer = new Buffer(oldLength + length + (oldLength / 2)); + this.rawBuffer.copy(newBuffer, 0, 0, this.contentSize); + this.rawBuffer = newBuffer; + } +} WriteStream.prototype.writeToBuffer = function(type, value, length) { - if (value === '' || value === null) return; + if (value === "" || value === null) return; - this.checkSize(length); - this.rawBuffer[this.getWriteType(type)](value, this.offset); - this.increment(length); -}; + this.checkSize(length); + this.rawBuffer[this.getWriteType(type)](value, this.offset); + this.increment(length); +} WriteStream.prototype.write = function(type, value) { - if (isString(type)) { - this.writeString(value, type); - } else { - this.writeToBuffer(type, value, calcLength(type)); - } -}; + if (isString(type)) { + this.writeString(value, type); + } else { + this.writeToBuffer(type, value, calcLength(type)); + } +} WriteStream.prototype.writeString = function(string, type) { - var encoding = this.getEncoding(type), length = Buffer.byteLength(string, encoding); - this.rawBuffer.write(string, this.offset, length, encoding); - this.increment(length); -}; + var encoding = this.getEncoding(type), length = Buffer.byteLength(string, encoding); + this.rawBuffer.write(string, this.offset, length, encoding); + this.increment(length); +} WriteStream.prototype.buffer = function() { - return this.rawBuffer.slice(0, this.contentSize); -}; + return this.rawBuffer.slice(0, this.contentSize); +} WriteStream.prototype.toReadBuffer = function() { - return new ReadStream(this.buffer()); -}; + return new ReadStream(this.buffer()); +} WriteStream.prototype.concat = function(newStream) { - var newSize = this.size() + newStream.size(); - this.rawBuffer = Buffer.concat([ this.buffer(), newStream.buffer() ], newSize); - this.contentSize = newSize; - this.offset = newSize; -}; + var newSize = this.size() + newStream.size(); + this.rawBuffer = Buffer.concat([this.buffer(), newStream.buffer()], newSize); + this.contentSize = newSize; + this.offset = newSize; +} ReadStream = function(buffer) { - RWStream.call(this); - this.rawBuffer = buffer; - this.offset = 0; + RWStream.call(this); + this.rawBuffer = buffer; + this.offset = 0; }; util.inherits(ReadStream, RWStream); ReadStream.prototype.size = function() { - return this.rawBuffer.length; -}; + return this.rawBuffer.length; +} ReadStream.prototype.increment = function(add) { - this.offset += add; -}; + this.offset += add; +} ReadStream.prototype.more = function(length) { - var newBuf = this.rawBuffer.slice(this.offset, this.offset + length); - this.increment(length); - return new ReadStream(newBuf); -}; + var newBuf = this.rawBuffer.slice(this.offset, this.offset + length); + this.increment(length); + return new ReadStream(newBuf); +} ReadStream.prototype.reset = function() { - this.offset = 0; - return this; -}; + this.offset = 0; + return this; +} ReadStream.prototype.end = function() { - return this.offset >= this.size(); -}; + return this.offset >= this.size(); +} ReadStream.prototype.readFromBuffer = function(type, length) { - //this.checkSize(length); - //if (this.offset + length > this.rawBuffer.length) throw ("out of bound " + this.offset + "," + length + "," + this.rawBuffer.length); - var value = this.rawBuffer[this.getReadType(type)](this.offset); - this.increment(length); - return value; -}; + //this.checkSize(length); + //if (this.offset + length > this.rawBuffer.length) throw ("out of bound " + this.offset + "," + length + "," + this.rawBuffer.length); + var value = this.rawBuffer[this.getReadType(type)](this.offset); + this.increment(length); + return value; +} ReadStream.prototype.read = function(type, length) { - var value = null; - if (isString(type)) { - value = this.readString(length, type); - } else { - value = this.readFromBuffer(type, calcLength(type)); - } + var value = null; + if (isString(type)) { + value = this.readString(length, type); + } else { + value = this.readFromBuffer(type, calcLength(type)); + } - return value; -}; + return value; +} ReadStream.prototype.readString = function(length, type) { - var encoding = this.getEncoding(type), - str = this.rawBuffer.toString(encoding, this.offset, this.offset + length); - this.increment(length); - return str; -}; + var encoding = this.getEncoding(type), + str = this.rawBuffer.toString(encoding, this.offset, this.offset + length); + this.increment(length); + return str; +} ReadStream.prototype.buffer = function() { - return this.rawBuffer; -}; + return this.rawBuffer; +} ReadStream.prototype.concat = function(newStream) { - var newSize = this.size() + newStream.size(); - this.rawBuffer = Buffer.concat([ this.buffer(), newStream.buffer() ], newSize); - this.contentSize = newSize; - this.offset = newSize; -}; + var newSize = this.size() + newStream.size(); + this.rawBuffer = Buffer.concat([this.buffer(), newStream.buffer()], newSize); + this.contentSize = newSize; + this.offset = newSize; +} RWStream.writes = {}; RWStream.writes[C.BIG_ENDIAN] = {}; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_UINT8] = 'writeUInt8'; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_UINT16] = 'writeUInt16BE'; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_UINT32] = 'writeUInt32BE'; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_INT8] = 'writeInt8'; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_INT16] = 'writeInt16BE'; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_INT32] = 'writeInt32BE'; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_FLOAT] = 'writeFloatBE'; -RWStream.writes[C.BIG_ENDIAN][C.TYPE_DOUBLE] = 'writeDoubleBE'; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_UINT8] = "writeUInt8"; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_UINT16] = "writeUInt16BE"; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_UINT32] = "writeUInt32BE"; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_INT8] = "writeInt8"; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_INT16] = "writeInt16BE"; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_INT32] = "writeInt32BE"; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_FLOAT] = "writeFloatBE"; +RWStream.writes[C.BIG_ENDIAN][C.TYPE_DOUBLE] = "writeDoubleBE"; RWStream.writes[C.LITTLE_ENDIAN] = {}; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_UINT8] = 'writeUInt8'; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_UINT16] = 'writeUInt16LE'; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_UINT32] = 'writeUInt32LE'; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_INT8] = 'writeInt8'; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_INT16] = 'writeInt16LE'; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_INT32] = 'writeInt32LE'; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_FLOAT] = 'writeFloatLE'; -RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_DOUBLE] = 'writeDoubleLE'; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_UINT8] = "writeUInt8"; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_UINT16] = "writeUInt16LE"; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_UINT32] = "writeUInt32LE"; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_INT8] = "writeInt8"; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_INT16] = "writeInt16LE"; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_INT32] = "writeInt32LE"; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_FLOAT] = "writeFloatLE"; +RWStream.writes[C.LITTLE_ENDIAN][C.TYPE_DOUBLE] = "writeDoubleLE"; RWStream.reads = {}; RWStream.reads[C.BIG_ENDIAN] = {}; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_UINT8] = 'readUInt8'; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_UINT16] = 'readUInt16BE'; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_UINT32] = 'readUInt32BE'; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_INT8] = 'readInt8'; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_INT16] = 'readInt16BE'; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_INT32] = 'readInt32BE'; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_FLOAT] = 'readFloatBE'; -RWStream.reads[C.BIG_ENDIAN][C.TYPE_DOUBLE] = 'readDoubleBE'; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_UINT8] = "readUInt8"; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_UINT16] = "readUInt16BE"; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_UINT32] = "readUInt32BE"; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_INT8] = "readInt8"; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_INT16] = "readInt16BE"; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_INT32] = "readInt32BE"; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_FLOAT] = "readFloatBE"; +RWStream.reads[C.BIG_ENDIAN][C.TYPE_DOUBLE] = "readDoubleBE"; RWStream.reads[C.LITTLE_ENDIAN] = {}; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_UINT8] = 'readUInt8'; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_UINT16] = 'readUInt16LE'; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_UINT32] = 'readUInt32LE'; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_INT8] = 'readInt8'; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_INT16] = 'readInt16LE'; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_INT32] = 'readInt32LE'; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_FLOAT] = 'readFloatLE'; -RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_DOUBLE] = 'readDoubleLE'; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_UINT8] = "readUInt8"; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_UINT16] = "readUInt16LE"; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_UINT32] = "readUInt32LE"; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_INT8] = "readInt8"; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_INT16] = "readInt16LE"; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_INT32] = "readInt32LE"; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_FLOAT] = "readFloatLE"; +RWStream.reads[C.LITTLE_ENDIAN][C.TYPE_DOUBLE] = "readDoubleLE"; RWStream.encodings = {}; -RWStream.encodings[C.TYPE_HEX] = 'hex'; -RWStream.encodings[C.TYPE_ASCII] = 'ascii'; +RWStream.encodings[C.TYPE_HEX] = "hex"; +RWStream.encodings[C.TYPE_ASCII] = "ascii"; \ No newline at end of file diff --git a/Packages/dimseservice/server/constants.js b/Packages/dimseservice/server/constants.js index 2afe3f11b..d97906ebd 100755 --- a/Packages/dimseservice/server/constants.js +++ b/Packages/dimseservice/server/constants.js @@ -1,98 +1,99 @@ C = { - IMPLEM_UID: '1.2.840.0.1.3680045.8.641', - IMPLEM_VERSION: 'OHIF-DCM-0.1', - APPLICATION_CONTEXT_NAME: '1.2.840.10008.3.1.1.1', - PROTOCOL_VERSION: '0001', - ITEM_TYPE_RESERVED: '00', - ITEM_TYPE_APPLICATION_CONTEXT: '10', - ITEM_TYPE_PDU_ASSOCIATE_RQ: '01', - ITEM_TYPE_PDU_ASSOCIATE_AC: '02', - ITEM_TYPE_PDU_PDATA: '04', - ITEM_TYPE_PDU_RELEASE_RQ: '05', - ITEM_TYPE_PDU_RELEASE_RP: '06', - ITEM_TYPE_PDU_AABORT: '07', - ITEM_TYPE_PRESENTATION_CONTEXT: '20', - ITEM_TYPE_PRESENTATION_CONTEXT_AC: '21', - ITEM_TYPE_ABSTRACT_CONTEXT: '30', - ITEM_TYPE_TRANSFER_CONTEXT: '40', - ITEM_TYPE_USER_INFORMATION: '50', - ITEM_TYPE_MAXIMUM_LENGTH: '51', - ITEM_TYPE_IMPLEMENTATION_UID: '52', - ITEM_TYPE_IMPLEMENTATION_VERSION: '55', - IMPLICIT_LITTLE_ENDIAN: '1.2.840.10008.1.2', - EXPLICIT_LITTLE_ENDIAN: '1.2.840.10008.1.2.1', - EXPLICIT_BIG_ENDIAN: '1.2.840.10008.1.2.2', - SOP_PATIENT_ROOT_FIND: '1.2.840.10008.5.1.4.1.2.1.1', - SOP_PATIENT_ROOT_MOVE: '1.2.840.10008.5.1.4.1.2.1.2', - SOP_PATIENT_ROOT_GET: '1.2.840.10008.5.1.4.1.2.1.3', - SOP_STUDY_ROOT_FIND: '1.2.840.10008.5.1.4.1.2.2.1', - SOP_STUDY_ROOT_MOVE: '1.2.840.10008.5.1.4.1.2.2.2', - SOP_STUDY_ROOT_GET: '1.2.840.10008.5.1.4.1.2.2.3', - SOP_VERIFICATION: '1.2.840.10008.1.1', - SOP_HANGING_PROTOCOL_FIND: '1.2.840.10008.5.1.4.38.2', - SOP_MR_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.4', - TYPE_ASCII: 1, - TYPE_HEX: 2, - TYPE_UINT8: 3, - TYPE_UINT16: 4, - TYPE_UINT32: 5, - TYPE_COMPOSITE: 6, - TYPE_FLOAT: 7, - TYPE_DOUBLE: 8, - TYPE_INT8: 9, - TYPE_INT16: 10, - TYPE_INT32: 11, - RESULT_REASON_ACCEPTANCE: 0, - RESULT_REASON_USER_REJECTION: 1, - RESULT_REASON_NO_REASON: 2, - RESULT_REASON_ABSTRACT_NOT_SUPPORTED: 3, - RESULT_REASON_TRANSFER_NOT_SUPPORTED: 4, - DEFAULT_MESSAGE_ID: 1, - LITTLE_ENDIAN: 1, - BIG_ENDIAN: 2, - VM_SINGLE: 1, - VM_TWO: 3, - VM_THREE: 4, - VM_FOUR: 5, - VM_1N: 6, - VM_2N: 7, - VM_3N: 8, - VM_6N: 9, - VM_3_3N: 10, - VM_2_2N: 11, - VM_16: 12, - VM_1_2: 13, - VM_1_3: 18, - VM_SIX: 14, - VM_NINE: 15, - VM_1_32: 16, - VM_1_99: 17, - PRIORITY_LOW: 0x2, - PRIORITY_MEDIUM: 0x0, - PRIORITY_HIGH: 0x1, - DATA_SET_PRESENT: 1, - DATE_SET_ABSENCE: 0x0101, - DATA_TYPE_COMMAND: 1, - DATA_TYPE_DATA: 0, - DATA_IS_LAST: 1, - DATA_NOT_LAST: 0, - SOURCE_SERVICE_USER: 0, - SOURCE_SERVICE_PROVIDER: 2, - QUERY_RETRIEVE_LEVEL_PATIENT: 'PATIENT', - QUERY_RETRIEVE_LEVEL_STUDY: 'STUDY', - QUERY_RETRIEVE_LEVEL_SERIES: 'SERIES', - QUERY_RETRIEVE_LEVEL_IMAGE: 'IMAGE', - VALUE_LENGTH_UNDEFINED: 0xffffffff, - STATUS_SUCCESS: 0x0000, - STATUS_CANCEL: 0xfe00, - STATUS_CFIND_CONT_OK: 0xff00, - STATUS_CFIND_CONT_WARN: 0xff01, - COMMAND_C_GET_RSP: 0x8010, - COMMAND_C_MOVE_RSP: 0x8021, - COMMAND_C_GET_RQ: 0x10, - COMMAND_C_STORE_RQ: 0x01, - COMMAND_C_FIND_RSP: 0x8020, - COMMAND_C_MOVE_RQ: 0x21, - COMMAND_C_FIND_RQ: 0x20, - COMMAND_C_STORE_RSP: 0x8001 -}; + IMPLEM_UID : "1.2.840.0.1.3680045.8.641", + IMPLEM_VERSION : "OHIF-DCM-0.1", + DEFAULT_MAX_PACKAGE_SIZE : 32768, + APPLICATION_CONTEXT_NAME : "1.2.840.10008.3.1.1.1", + PROTOCOL_VERSION : "0001", + ITEM_TYPE_RESERVED : "00", + ITEM_TYPE_APPLICATION_CONTEXT : "10", + ITEM_TYPE_PDU_ASSOCIATE_RQ : "01", + ITEM_TYPE_PDU_ASSOCIATE_AC : "02", + ITEM_TYPE_PDU_PDATA : "04", + ITEM_TYPE_PDU_RELEASE_RQ : "05", + ITEM_TYPE_PDU_RELEASE_RP : "06", + ITEM_TYPE_PDU_AABORT : "07", + ITEM_TYPE_PRESENTATION_CONTEXT : "20", + ITEM_TYPE_PRESENTATION_CONTEXT_AC : "21", + ITEM_TYPE_ABSTRACT_CONTEXT : "30", + ITEM_TYPE_TRANSFER_CONTEXT : "40", + ITEM_TYPE_USER_INFORMATION : "50", + ITEM_TYPE_MAXIMUM_LENGTH : "51", + ITEM_TYPE_IMPLEMENTATION_UID : "52", + ITEM_TYPE_IMPLEMENTATION_VERSION : "55", + IMPLICIT_LITTLE_ENDIAN : "1.2.840.10008.1.2", + EXPLICIT_LITTLE_ENDIAN : "1.2.840.10008.1.2.1", + EXPLICIT_BIG_ENDIAN : "1.2.840.10008.1.2.2", + SOP_PATIENT_ROOT_FIND : "1.2.840.10008.5.1.4.1.2.1.1", + SOP_PATIENT_ROOT_MOVE : "1.2.840.10008.5.1.4.1.2.1.2", + SOP_PATIENT_ROOT_GET : "1.2.840.10008.5.1.4.1.2.1.3", + SOP_STUDY_ROOT_FIND : "1.2.840.10008.5.1.4.1.2.2.1", + SOP_STUDY_ROOT_MOVE : "1.2.840.10008.5.1.4.1.2.2.2", + SOP_STUDY_ROOT_GET : "1.2.840.10008.5.1.4.1.2.2.3", + SOP_VERIFICATION : "1.2.840.10008.1.1", + SOP_HANGING_PROTOCOL_FIND : "1.2.840.10008.5.1.4.38.2", + SOP_MR_IMAGE_STORAGE : "1.2.840.10008.5.1.4.1.1.4", + TYPE_ASCII : 1, + TYPE_HEX : 2, + TYPE_UINT8 : 3, + TYPE_UINT16 : 4, + TYPE_UINT32 : 5, + TYPE_COMPOSITE : 6, + TYPE_FLOAT : 7, + TYPE_DOUBLE : 8, + TYPE_INT8 : 9, + TYPE_INT16 : 10, + TYPE_INT32 : 11, + RESULT_REASON_ACCEPTANCE : 0, + RESULT_REASON_USER_REJECTION : 1, + RESULT_REASON_NO_REASON :2, + RESULT_REASON_ABSTRACT_NOT_SUPPORTED : 3, + RESULT_REASON_TRANSFER_NOT_SUPPORTED : 4, + DEFAULT_MESSAGE_ID : 1, + LITTLE_ENDIAN : 1, + BIG_ENDIAN : 2, + VM_SINGLE :1, + VM_TWO : 3, + VM_THREE : 4, + VM_FOUR : 5, + VM_1N : 6, + VM_2N :7, + VM_3N :8, + VM_6N :9, + VM_3_3N : 10, + VM_2_2N : 11, + VM_16 : 12, + VM_1_2 : 13, + VM_1_3 : 18, + VM_SIX : 14, + VM_NINE : 15, + VM_1_32 : 16, + VM_1_99 : 17, + PRIORITY_LOW : 0x2, + PRIORITY_MEDIUM : 0x0, + PRIORITY_HIGH : 0x1, + DATA_SET_PRESENT : 1, + DATE_SET_ABSENCE : 0x0101, + DATA_TYPE_COMMAND : 1, + DATA_TYPE_DATA : 0, + DATA_IS_LAST : 1, + DATA_NOT_LAST : 0, + SOURCE_SERVICE_USER : 0, + SOURCE_SERVICE_PROVIDER : 2, + QUERY_RETRIEVE_LEVEL_PATIENT : "PATIENT", + QUERY_RETRIEVE_LEVEL_STUDY : "STUDY", + QUERY_RETRIEVE_LEVEL_SERIES : "SERIES", + QUERY_RETRIEVE_LEVEL_IMAGE : "IMAGE", + VALUE_LENGTH_UNDEFINED : 0xffffffff, + STATUS_SUCCESS : 0x0000, + STATUS_CANCEL : 0xfe00, + STATUS_CFIND_CONT_OK : 0xff00, + STATUS_CFIND_CONT_WARN : 0xff01, + COMMAND_C_GET_RSP : 0x8010, + COMMAND_C_MOVE_RSP : 0x8021, + COMMAND_C_GET_RQ : 0x10, + COMMAND_C_STORE_RQ : 0x01, + COMMAND_C_FIND_RSP : 0x8020, + COMMAND_C_MOVE_RQ : 0x21, + COMMAND_C_FIND_RQ : 0x20, + COMMAND_C_STORE_RSP : 0x8001 +}; \ No newline at end of file diff --git a/Packages/dimseservice/server/methods.js b/Packages/dimseservice/server/methods.js index 3a83cb7dd..442923f84 100755 --- a/Packages/dimseservice/server/methods.js +++ b/Packages/dimseservice/server/methods.js @@ -1,3 +1,3 @@ Meteor.methods({ -}); +}); \ No newline at end of file diff --git a/Packages/dimseservice/server/require.js b/Packages/dimseservice/server/require.js index b8c620fab..8fc4d83aa 100755 --- a/Packages/dimseservice/server/require.js +++ b/Packages/dimseservice/server/require.js @@ -1 +1 @@ -util = Npm.require('util'); +util = Npm.require("util"); \ No newline at end of file diff --git a/config/orthancDIMSE.json b/config/orthancDIMSE.json index c83f47c5c..7dba45ecb 100644 --- a/config/orthancDIMSE.json +++ b/config/orthancDIMSE.json @@ -18,10 +18,10 @@ } ] }, - "dimse" : { + "dimse" : [{ "host" : "localhost", "port" : 4242, - "hostAE" : "ORTHANC" - }, + "aeTitle" : "ORTHANCLOCAL" + }], "defaultServiceType": "dimse" }