Updates for Timepoint assocation (LT-60) and Conformance Checks (LT-92, LT-93, LT-94)
This commit is contained in:
1 parent
6c4eae3699
commit
beaa56c0b3
144 files changed
+5050
-2416
No files matched your search
Executable
+964
@@ -0,0 +1,964 @@
|
||||
function paddingLeft(paddingValue, string) {
|
||||
return String(paddingValue + string).slice(-paddingValue.length);
|
||||
};
|
||||
|
||||
function rtrim(str) {
|
||||
return str.replace(/\s*$/g, '');
|
||||
}
|
||||
|
||||
function ltrim(str) {
|
||||
return str.replace(/^\s*/g, '');
|
||||
}
|
||||
|
||||
function fieldsLength(fields) {
|
||||
var length = 0;
|
||||
fields.forEach(function(field) {
|
||||
length += field.length();
|
||||
});
|
||||
return length;
|
||||
};
|
||||
|
||||
Tag = function(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;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
ValueRepresentation.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_ASCII, length);
|
||||
};
|
||||
|
||||
ValueRepresentation.prototype.readNullPaddedString = function(stream, length) {
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
ApplicationEntity = function() {
|
||||
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();
|
||||
};
|
||||
|
||||
ApplicationEntity.prototype.getFields = function(value) {
|
||||
return ApplicationEntity.super_.prototype.getFields.call(this, [ new FilledField(value, 16) ]);
|
||||
};
|
||||
|
||||
CodeString = function() {
|
||||
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();
|
||||
};
|
||||
|
||||
CodeString.prototype.getFields = function(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 = '';
|
||||
};
|
||||
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
AttributeTag.prototype.getFields = function(value) {
|
||||
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 = '';
|
||||
};
|
||||
|
||||
util.inherits(DateValue, ValueRepresentation);
|
||||
|
||||
DateValue.prototype.readBytes = function(stream, length) {
|
||||
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);
|
||||
};
|
||||
|
||||
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 = '';
|
||||
}
|
||||
|
||||
return DateValue.super_.prototype.getFields.call(this, [ new StringField(str) ]);
|
||||
};
|
||||
|
||||
DecimalString = function() {
|
||||
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();
|
||||
};
|
||||
|
||||
DecimalString.prototype.getFields = function(value) {
|
||||
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';
|
||||
};
|
||||
|
||||
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());
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
util.inherits(FloatingPointSingle, ValueRepresentation);
|
||||
|
||||
FloatingPointSingle.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_FLOAT);
|
||||
};
|
||||
|
||||
FloatingPointSingle.prototype.getFields = function(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;
|
||||
};
|
||||
|
||||
util.inherits(FloatingPointDouble, ValueRepresentation);
|
||||
|
||||
FloatingPointDouble.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_DOUBLE);
|
||||
};
|
||||
|
||||
FloatingPointDouble.prototype.getFields = function(value) {
|
||||
return FloatingPointDouble.super_.prototype.getFields.call(this, [ new DoubleField(value) ]);
|
||||
};
|
||||
|
||||
IntegerString = function() {
|
||||
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();
|
||||
};
|
||||
|
||||
IntegerString.prototype.getFields = function(value) {
|
||||
return IntegerString.super_.prototype.getFields.call(this, [ new StringField(value.toString()) ]);
|
||||
};
|
||||
|
||||
LongString = function() {
|
||||
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();
|
||||
};
|
||||
|
||||
LongString.prototype.getFields = function(value) {
|
||||
return LongString.super_.prototype.getFields.call(this, [ new StringField(value ? value : '') ]);
|
||||
};
|
||||
|
||||
LongText = function() {
|
||||
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);
|
||||
};
|
||||
|
||||
LongText.prototype.getFields = function(value) {
|
||||
return LongText.super_.prototype.getFields.call(this, [ new StringField(value) ]);
|
||||
};
|
||||
|
||||
PersonName = function() {
|
||||
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;
|
||||
};
|
||||
|
||||
PersonName.prototype.readBytes = function(stream, length) {
|
||||
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 || '';
|
||||
|
||||
str = [ fName, gName, middle, prefix, suffix ].join('^');
|
||||
} else str = '';
|
||||
|
||||
return PersonName.super_.prototype.getFields.call(this, [ new StringField(str) ]);
|
||||
};
|
||||
|
||||
ShortString = function() {
|
||||
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();
|
||||
};
|
||||
|
||||
ShortString.prototype.getFields = function(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;
|
||||
};
|
||||
|
||||
util.inherits(SignedLong, ValueRepresentation);
|
||||
|
||||
SignedLong.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_INT32);
|
||||
};
|
||||
|
||||
SignedLong.prototype.getFields = function(value) {
|
||||
return SignedLong.super_.prototype.getFields.call(this, [ new Int32Field(value) ]);
|
||||
};
|
||||
|
||||
SequenceOfItems = function() {
|
||||
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;
|
||||
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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(0xe0dd));
|
||||
fields.push(new UInt32Field(0x00000000));
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
util.inherits(SignedShort, ValueRepresentation);
|
||||
|
||||
SignedShort.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_INT16);
|
||||
};
|
||||
|
||||
SignedShort.prototype.getFields = function(value) {
|
||||
return SignedShort.super_.prototype.getFields.call(this, [ new Int16Field(value) ]);
|
||||
};
|
||||
|
||||
ShortText = function() {
|
||||
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);
|
||||
};
|
||||
|
||||
ShortText.prototype.getFields = function(value) {
|
||||
return ShortText.super_.prototype.getFields.call(this, [ new StringField(value) ]);
|
||||
};
|
||||
|
||||
TimeValue = function() {
|
||||
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));
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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';
|
||||
};
|
||||
|
||||
util.inherits(UnlimitedCharacters, ValueRepresentation);
|
||||
|
||||
UnlimitedCharacters.prototype.readBytes = function(stream, length) {
|
||||
return rtrim(stream.read(C.TYPE_ASCII, length));
|
||||
};
|
||||
|
||||
UnlimitedCharacters.prototype.getFields = function(value) {
|
||||
return UnlimitedCharacters.super_.prototype.getFields.call(this, [ new StringField(value) ]);
|
||||
};
|
||||
|
||||
UnlimitedText = function() {
|
||||
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);
|
||||
};
|
||||
|
||||
UnlimitedText.prototype.getFields = function(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;
|
||||
};
|
||||
|
||||
util.inherits(UnsignedShort, ValueRepresentation);
|
||||
|
||||
UnsignedShort.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_UINT16);
|
||||
};
|
||||
|
||||
UnsignedShort.prototype.getFields = function(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;
|
||||
};
|
||||
|
||||
util.inherits(UnsignedLong, ValueRepresentation);
|
||||
|
||||
UnsignedLong.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_UINT32);
|
||||
};
|
||||
|
||||
UnsignedLong.prototype.getFields = function(value) {
|
||||
return UnsignedLong.super_.prototype.getFields.call(this, [ new UInt32Field(value) ]);
|
||||
};
|
||||
|
||||
UniqueIdentifier = function() {
|
||||
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);
|
||||
};
|
||||
|
||||
UniqueIdentifier.prototype.getFields = function(value) {
|
||||
return UniqueIdentifier.super_.prototype.getFields.call(this, [ new StringField(value) ]);
|
||||
};
|
||||
|
||||
UniversalResource = function() {
|
||||
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));
|
||||
};
|
||||
|
||||
UniversalResource.prototype.getFields = function(value) {
|
||||
return UniversalResource.super_.prototype.getFields.call(this, [ new StringField(value) ]);
|
||||
};
|
||||
|
||||
UnknownValue = function() {
|
||||
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);
|
||||
};
|
||||
|
||||
UnknownValue.prototype.getFields = function(value) {
|
||||
return UnknownValue.super_.prototype.getFields.call(this, [ new StringField(value) ]);
|
||||
};
|
||||
|
||||
OtherWordString = function() {
|
||||
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);
|
||||
};
|
||||
|
||||
OtherWordString.prototype.getFields = function(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)
|
||||
value.forEach(function(el) {
|
||||
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);
|
||||
}
|
||||
} 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));
|
||||
};
|
||||
|
||||
elementKeywordByTag = function(tag) {
|
||||
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;
|
||||
|
||||
return vr;
|
||||
};
|
||||
|
||||
readElements = function(stream, syntax) {
|
||||
if (stream.end()) return false;
|
||||
|
||||
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);
|
||||
|
||||
stream.setEndian(oldEndian);
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
DataElement.prototype.setOptions = function(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;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
DataElement.prototype.singleValue = function() {
|
||||
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;
|
||||
};
|
||||
|
||||
DataElement.prototype.isBinaryNumber = function() {
|
||||
return binaryVRs.indexOf(this.vr.type) != -1;
|
||||
};
|
||||
|
||||
DataElement.prototype.length = function(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 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;
|
||||
|
||||
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 {
|
||||
length = stream.read(C.TYPE_UINT16);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
//} catch (e) { console.log('error', vr, length); }
|
||||
|
||||
stream.setEndian(oldEndian);
|
||||
};
|
||||
|
||||
DataElement.prototype.write = function(stream) {
|
||||
var oldEndian = stream.endian;
|
||||
stream.setEndian(this.endian);
|
||||
|
||||
var fields = this.getFields();
|
||||
fields.forEach(function(field) {
|
||||
field.write(stream);
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
if (vrType == 'SQ') {
|
||||
valueLength = 0xffffffff;
|
||||
}
|
||||
|
||||
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 {
|
||||
fields.push(new StringField(vrType), new UInt16Field(valueLength));
|
||||
}
|
||||
}
|
||||
|
||||
fields = fields.concat(valueFields);
|
||||
return fields;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user