ohif-viewer/Packages/dimseservice/server/PDU.js

676 lines
20 KiB
JavaScript
Executable File

PDU = function() {
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;
};
PDU.prototype.is = function(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));
}
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';
}
};
PDU.prototype.read = function(stream) {
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);
};
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;
pdvs.push(pdv);
}
return pdvs;
};
PDU.prototype.loadDicomMessage = function(stream, isCommand, isLast) {
var message = readMessage(stream, isCommand, isLast);
return message;
};
PDU.prototype.stream = function() {
var stream = new WriteStream(),
fields = this.getFields();
// writing to buffer
fields.forEach(function(field) {
field.write(stream);
});
return stream;
};
PDU.prototype.buffer = function() {
return this.stream().buffer();
};
var interpretCommand = function(stream, isLast) {
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++]);
}
}
return merges;
};
pduByStream = function(stream) {
if (stream.end()) return null;
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;
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;
};
util.inherits(AssociateRQ, PDU);
AssociateRQ.prototype.setProtocolVersion = function(version) {
this.protocolVersion = version;
};
AssociateRQ.prototype.setCalledAETitle = function(title) {
this.calledAETitle = title;
};
AssociateRQ.prototype.setCallingAETitle = function(title) {
this.callingAETitle = title;
};
AssociateRQ.prototype.setApplicationContextItem = function(item) {
this.applicationContextItem = item;
};
AssociateRQ.prototype.setPresentationContextItems = function(items) {
this.presentationContextItems = items;
};
AssociateRQ.prototype.setUserInformationItem = function(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;
};
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);
};
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);
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 userItem = this.load(stream);
this.setUserInformationItem(userItem);
};
AssociateRQ.prototype.buffer = function() {
return AssociateRQ.super_.prototype.buffer.call(this);
};
AssociateAC = function() {
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);
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 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);
};
util.inherits(AssociateAbort, PDU);
AssociateAbort.prototype.setSource = function(src) {
this.source = src;
};
AssociateAbort.prototype.setReason = function(reason) {
this.reason = reason;
};
AssociateAbort.prototype.readBytes = function(stream, length) {
stream.increment(2);
var source = stream.read(C.TYPE_UINT8);
this.setSource(source);
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)
]);
};
ReleaseRQ = function() {
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) ]);
};
ReleaseRP = function() {
this.type = C.ITEM_TYPE_PDU_RELEASE_RP;
PDU.call(this);
};
util.inherits(ReleaseRP, PDU);
ReleaseRP.prototype.readBytes = function(stream, length) {
stream.increment(4);
};
ReleaseRP.prototype.getFields = function() {
return ReleaseRP.super_.prototype.getFields.call(this, [ new ReservedField(4) ]);
};
PDataTF = function() {
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 : [];
};
PDataTF.prototype.getFields = function() {
var fields = this.presentationDataValueItems;
return PDataTF.super_.prototype.getFields.call(this, fields);
};
PDataTF.prototype.readBytes = function(stream, length) {
var pdvs = this.loadPDV(stream, length);
//let merges = mergePDVs(pdvs);
this.setPresentationDataValueItems(pdvs);
};
Item = function() {
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);
};
Item.prototype.write = function(stream) {
stream.concat(this.stream());
};
Item.prototype.getFields = function(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.lengthBytes = 4;
};
util.inherits(PresentationDataValueItem, Item);
PresentationDataValueItem.prototype.setContextId = function(id) {
this.contextId = id;
};
PresentationDataValueItem.prototype.setFlag = function(flag) {
this.flag = flag;
};
PresentationDataValueItem.prototype.setPresentationDataValue = function(pdv) {
this.pdv = pdv;
};
PresentationDataValueItem.prototype.setMessage = function(msg) {
this.dataFragment = msg;
};
PresentationDataValueItem.prototype.getMessage = function() {
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;
//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));
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);
};
ApplicationContextItem = function() {
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;
};
ApplicationContextItem.prototype.getFields = function() {
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);
};
ApplicationContextItem.prototype.buffer = function() {
return ApplicationContextItem.super_.prototype.buffer.call(this);
};
PresentationContextItem = function() {
this.type = C.ITEM_TYPE_PRESENTATION_CONTEXT;
Item.call(this);
};
util.inherits(PresentationContextItem, Item);
PresentationContextItem.prototype.setPresentationContextID = function(id) {
this.presentationContextID = id;
};
PresentationContextItem.prototype.setAbstractSyntaxItem = function(item) {
this.abstractSyntaxItem = item;
};
PresentationContextItem.prototype.setTransferSyntaxesItems = function(items) {
this.transferSyntaxesItems = items;
};
PresentationContextItem.prototype.setResultReason = function(reason) {
this.resultReason = reason;
};
PresentationContextItem.prototype.accepted = function() {
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 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);
};
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);
};
PresentationContextItem.prototype.buffer = function() {
return PresentationContextItem.super_.prototype.buffer.call(this);
};
PresentationContextItemAC = function() {
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 transItem = this.load(stream);
this.setTransferSyntaxesItems([ transItem ]);
};
AbstractSyntaxItem = function() {
this.type = C.ITEM_TYPE_ABSTRACT_CONTEXT;
Item.call(this);
};
util.inherits(AbstractSyntaxItem, Item);
AbstractSyntaxItem.prototype.setAbstractSyntaxName = function(name) {
this.abstractSyntaxName = name;
};
AbstractSyntaxItem.prototype.getFields = function() {
return AbstractSyntaxItem.super_.prototype.getFields.call(this, [ new StringField(this.abstractSyntaxName) ]);
};
AbstractSyntaxItem.prototype.buffer = function() {
return AbstractSyntaxItem.super_.prototype.buffer.call(this);
};
AbstractSyntaxItem.prototype.readBytes = function(stream, length) {
var name = stream.read(C.TYPE_ASCII, length);
this.setAbstractSyntaxName(name);
};
TransferSyntaxItem = function() {
this.type = C.ITEM_TYPE_TRANSFER_CONTEXT;
Item.call(this);
};
util.inherits(TransferSyntaxItem, Item);
TransferSyntaxItem.prototype.setTransferSyntaxName = function(name) {
this.transferSyntaxName = name;
};
TransferSyntaxItem.prototype.readBytes = function(stream, length) {
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) ]);
};
TransferSyntaxItem.prototype.buffer = function() {
return TransferSyntaxItem.super_.prototype.buffer.call(this);
};
UserInformationItem = function() {
this.type = C.ITEM_TYPE_USER_INFORMATION;
Item.call(this);
};
util.inherits(UserInformationItem, Item);
UserInformationItem.prototype.setUserDataItems = function(items) {
this.userDataItems = items;
};
UserInformationItem.prototype.readBytes = function(stream, length) {
var items = [], pdu = this.load(stream);
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);
};
UserInformationItem.prototype.buffer = function() {
return UserInformationItem.super_.prototype.buffer.call(this);
};
ImplementationClassUIDItem = function() {
this.type = C.ITEM_TYPE_IMPLEMENTATION_UID;
Item.call(this);
};
util.inherits(ImplementationClassUIDItem, Item);
ImplementationClassUIDItem.prototype.setImplementationClassUID = function(id) {
this.implementationClassUID = id;
};
ImplementationClassUIDItem.prototype.readBytes = function(stream, length) {
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) ]);
};
ImplementationClassUIDItem.prototype.buffer = function() {
return ImplementationClassUIDItem.super_.prototype.buffer.call(this);
};
ImplementationVersionNameItem = function() {
this.type = C.ITEM_TYPE_IMPLEMENTATION_VERSION;
Item.call(this);
};
util.inherits(ImplementationVersionNameItem, Item);
ImplementationVersionNameItem.prototype.setImplementationVersionName = function(name) {
this.implementationVersionName = name;
};
ImplementationVersionNameItem.prototype.readBytes = function(stream, length) {
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) ]);
};
ImplementationVersionNameItem.prototype.buffer = function() {
return ImplementationVersionNameItem.super_.prototype.buffer.call(this);
};
MaximumLengthItem = function() {
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;
};
MaximumLengthItem.prototype.readBytes = function(stream, length) {
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) ]);
};
MaximumLengthItem.prototype.buffer = function() {
return MaximumLengthItem.super_.prototype.buffer.call(this);
};