internal XmlElement GetMemento(XmlDocument theDocument, StudyXmlOutputSettings settings) { if (_cachedElement != null) { return(_cachedElement); } if (_baseInstance != null) { _cachedElement = GetMementoForCollection(theDocument, _baseInstance.Collection, Collection, settings); // Only keep around the cached xml data, free the collection to reduce memory usage SwitchToCachedXml(); return(_cachedElement); } _cachedElement = GetMementoForCollection(theDocument, null, Collection, settings); return(_cachedElement); }
private XmlElement GetMementoForCollection(XmlDocument theDocument, DicomAttributeCollection baseCollection, DicomAttributeCollection collection, StudyXmlOutputSettings settings) { XmlElement instance; if (collection is DicomSequenceItem) { instance = theDocument.CreateElement("Item"); } else { instance = theDocument.CreateElement("Instance"); XmlAttribute sopInstanceUid = theDocument.CreateAttribute("UID"); sopInstanceUid.Value = _sopInstanceUid; instance.Attributes.Append(sopInstanceUid); if (_sopClass != null) { XmlAttribute sopClassAttribute = theDocument.CreateAttribute("SopClassUID"); sopClassAttribute.Value = _sopClass.Uid; instance.Attributes.Append(sopClassAttribute); } if (_transferSyntax != null && !(this is BaseInstanceXml)) { XmlAttribute transferSyntaxAttribute = theDocument.CreateAttribute("TransferSyntaxUID"); transferSyntaxAttribute.Value = _transferSyntax.UidString; instance.Attributes.Append(transferSyntaxAttribute); } if (_sourceAETitle != null) { XmlAttribute sourceAEAttribute = theDocument.CreateAttribute("SourceAETitle"); sourceAEAttribute.Value = XmlEscapeString(_sourceAETitle); instance.Attributes.Append(sourceAEAttribute); } if (_sourceFileName != null && settings.IncludeSourceFileName) { XmlAttribute sourceFileNameAttribute = theDocument.CreateAttribute("SourceFileName"); string fileName = SecurityElement.Escape(_sourceFileName); sourceFileNameAttribute.Value = fileName; instance.Attributes.Append(sourceFileNameAttribute); } if (_fileSize != 0) { XmlAttribute fileSize = theDocument.CreateAttribute("FileSize"); fileSize.Value = _fileSize.ToString(); instance.Attributes.Append(fileSize); } } IPrivateInstanceXmlDicomAttributeCollection thisCollection = null; if (collection is IPrivateInstanceXmlDicomAttributeCollection) { thisCollection = (IPrivateInstanceXmlDicomAttributeCollection)collection; foreach (DicomTag tag in thisCollection.ExcludedTags) { //Artificially seed the collection with empty attributes from this //instance and the base instance so we can add them in the right order. //Note in the case of the base instance, this will never alter //the collection because the empty attribute is already there (see ParseAttribute). DicomAttribute attribute = collection[tag]; } } IEnumerator <DicomAttribute> baseIterator = null; IPrivateInstanceXmlDicomAttributeCollection privateBaseCollection = null; if (baseCollection != null) { privateBaseCollection = baseCollection as IPrivateInstanceXmlDicomAttributeCollection; if (privateBaseCollection != null) { foreach (DicomTag tag in privateBaseCollection.ExcludedTags) { //Artificially seed the collection with empty attributes from this //instance and the base instance so we can add them in the right order. //Note in the case of the base instance, this will never alter //the collection because the empty attribute is already there (see ParseAttribute). DicomAttribute attribute = collection[tag]; } } baseIterator = baseCollection.GetEnumerator(); if (!baseIterator.MoveNext()) { baseIterator = null; } } List <DicomTag> newlyExcludedTags = new List <DicomTag>(); foreach (DicomAttribute attribute in collection) { bool isExcludedFromThisCollection = thisCollection != null && thisCollection.IsTagExcluded(attribute.Tag.TagValue); bool isExcludedFromBase = privateBaseCollection != null && privateBaseCollection.ExcludedTagsHelper.IsTagExcluded(attribute.Tag.TagValue); bool isInBase = isExcludedFromBase; bool isSameAsInBase = isExcludedFromThisCollection && isExcludedFromBase; if (baseIterator != null) { while (baseIterator != null && baseIterator.Current.Tag < attribute.Tag) { if (!baseIterator.Current.IsEmpty) { XmlElement emptyAttributeElement = CreateDicomAttributeElement(theDocument, baseIterator.Current, "EmptyAttribute"); instance.AppendChild(emptyAttributeElement); } if (!baseIterator.MoveNext()) { baseIterator = null; } } if (baseIterator != null) { if (baseIterator.Current.Tag == attribute.Tag) { isInBase = !baseIterator.Current.IsEmpty || isExcludedFromBase; bool isEmpty = attribute.IsEmpty && !isExcludedFromThisCollection; bool isEmptyInBase = baseIterator.Current.IsEmpty && !isExcludedFromBase; isSameAsInBase = (isExcludedFromThisCollection && isExcludedFromBase) || (isEmpty && isEmptyInBase); if (!baseIterator.Current.IsEmpty && !isExcludedFromBase) { if (!(attribute is DicomAttributeOB) && !(attribute is DicomAttributeOW) && !(attribute is DicomAttributeOF) && !(attribute is DicomFragmentSequence)) { if (attribute.Equals(baseIterator.Current)) { isSameAsInBase = true; } } } // Move to the next attribute for the next time through the loop if (!baseIterator.MoveNext()) { baseIterator = null; } } } } //by this point, equality has been covered for both attributes with values, empty attributes and excluded attributes. if (isSameAsInBase) { continue; } if (isExcludedFromThisCollection) { XmlElement excludedAttributeElement = CreateDicomAttributeElement(theDocument, attribute, "ExcludedAttribute"); instance.AppendChild(excludedAttributeElement); continue; } if (attribute.IsEmpty) { //Only store an empty attribute if it is in the base (either non-empty or excluded). if (isInBase) { XmlElement emptyAttributeElement = CreateDicomAttributeElement(theDocument, attribute, "EmptyAttribute"); instance.AppendChild(emptyAttributeElement); } continue; } StudyXmlTagInclusion inclusion = AttributeShouldBeIncluded(attribute, settings); if (inclusion == StudyXmlTagInclusion.IncludeTagExclusion) { newlyExcludedTags.Add(attribute.Tag); if (!isExcludedFromBase) { XmlElement excludedAttributeElement = CreateDicomAttributeElement(theDocument, attribute, "ExcludedAttribute"); instance.AppendChild(excludedAttributeElement); } continue; } if (inclusion == StudyXmlTagInclusion.IgnoreTag) { continue; } XmlElement instanceElement = CreateDicomAttributeElement(theDocument, attribute, "Attribute"); if (attribute is DicomAttributeSQ) { DicomSequenceItem[] items = (DicomSequenceItem[])attribute.Values; foreach (DicomSequenceItem item in items) { XmlElement itemElement = GetMementoForCollection(theDocument, null, item, settings); instanceElement.AppendChild(itemElement); } } else if (attribute is DicomAttributeOW || attribute is DicomAttributeUN) { byte[] val = (byte[])attribute.Values; StringBuilder str = null; foreach (byte i in val) { if (str == null) { str = new StringBuilder(i.ToString()); } else { str.AppendFormat("\\{0}", i); } } if (str != null) { instanceElement.InnerText = str.ToString(); } } else if (attribute is DicomAttributeOF) { float[] val = (float[])attribute.Values; StringBuilder str = null; foreach (float i in val) { if (str == null) { str = new StringBuilder(i.ToString()); } else { str.AppendFormat("\\{0}", i); } } if (str != null) { instanceElement.InnerText = str.ToString(); } } else { instanceElement.InnerText = XmlEscapeString(attribute); } instance.AppendChild(instanceElement); } //fill in empty attributes past the end of this collection while (baseIterator != null) { if (!baseIterator.Current.IsEmpty) { XmlElement emptyAttributeElement = CreateDicomAttributeElement(theDocument, baseIterator.Current, "EmptyAttribute"); instance.AppendChild(emptyAttributeElement); } if (!baseIterator.MoveNext()) { baseIterator = null; } } if (thisCollection != null) { //when this is the base collection, 'thisCollection' will never be null. //when this is not the base collection, we switch to 'cached xml' right after this, anyway, //so the fact that this won't occur is ok. foreach (DicomTag tag in newlyExcludedTags) { collection[tag].SetEmptyValue(); thisCollection.ExcludedTagsHelper.Add(tag); } } return(instance); }
private static StudyXmlTagInclusion AttributeShouldBeIncluded(DicomAttribute attribute, StudyXmlOutputSettings settings) { if (settings == null) { return(StudyXmlTagInclusion.IncludeTagValue); } if (attribute is DicomAttributeSQ) { if (attribute.Tag.IsPrivate) { return(settings.IncludePrivateValues); } return(StudyXmlTagInclusion.IncludeTagValue); } // private tag if (attribute.Tag.IsPrivate) { if (settings.IncludePrivateValues != StudyXmlTagInclusion.IncludeTagValue) { return(settings.IncludePrivateValues); } } // check type if (attribute is DicomAttributeUN) { if (settings.IncludeUnknownTags != StudyXmlTagInclusion.IncludeTagValue) { return(settings.IncludeUnknownTags); } } // This check isn't needed, but it bypasses the StreamLength calculation if its not needed if (settings.IncludeLargeTags == StudyXmlTagInclusion.IncludeTagValue) { return(settings.IncludeLargeTags); } // check the size ulong length = attribute.StreamLength; if (length <= settings.MaxTagLength) { return(StudyXmlTagInclusion.IncludeTagValue); } // Move here, such that we first check if the tag should be excluded if ((attribute is DicomAttributeOB) || (attribute is DicomAttributeOW) || (attribute is DicomAttributeOF) || (attribute is DicomFragmentSequence)) { return(StudyXmlTagInclusion.IncludeTagExclusion); } return(settings.IncludeLargeTags); }