# HG changeset patch # User Sebastien Jodogne # Date 1445493144 -7200 # Node ID ec66a16aa39878ba45a63cc80b183d3f4d558ca8 # Parent b953c6eef28d8f103c6e3c5764546302da06a0bd removal of DicomStringValue and DicomNullValue diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomArray.cpp --- a/Core/DicomFormat/DicomArray.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/Core/DicomFormat/DicomArray.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -63,7 +63,8 @@ for (size_t i = 0; i < elements_.size(); i++) { DicomTag t = elements_[i]->GetTag(); - std::string s = elements_[i]->GetValue().AsString(); + const DicomValue& v = elements_[i]->GetValue(); + std::string s = v.IsNull() ? "(null)" : v.GetContent(); printf("0x%04x 0x%04x [%s]\n", t.GetGroup(), t.GetElement(), s.c_str()); } } diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomImageInformation.cpp --- a/Core/DicomFormat/DicomImageInformation.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/Core/DicomFormat/DicomImageInformation.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -54,7 +54,7 @@ try { - std::string p = values.GetValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION).AsString(); + std::string p = values.GetValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION).GetContent(); Toolbox::ToUpperCase(p); if (p == "RGB") @@ -114,13 +114,13 @@ photometric_ = PhotometricInterpretation_Unknown; } - width_ = boost::lexical_cast(values.GetValue(DICOM_TAG_COLUMNS).AsString()); - height_ = boost::lexical_cast(values.GetValue(DICOM_TAG_ROWS).AsString()); - bitsAllocated_ = boost::lexical_cast(values.GetValue(DICOM_TAG_BITS_ALLOCATED).AsString()); + width_ = boost::lexical_cast(values.GetValue(DICOM_TAG_COLUMNS).GetContent()); + height_ = boost::lexical_cast(values.GetValue(DICOM_TAG_ROWS).GetContent()); + bitsAllocated_ = boost::lexical_cast(values.GetValue(DICOM_TAG_BITS_ALLOCATED).GetContent()); try { - samplesPerPixel_ = boost::lexical_cast(values.GetValue(DICOM_TAG_SAMPLES_PER_PIXEL).AsString()); + samplesPerPixel_ = boost::lexical_cast(values.GetValue(DICOM_TAG_SAMPLES_PER_PIXEL).GetContent()); } catch (OrthancException&) { @@ -129,7 +129,7 @@ try { - bitsStored_ = boost::lexical_cast(values.GetValue(DICOM_TAG_BITS_STORED).AsString()); + bitsStored_ = boost::lexical_cast(values.GetValue(DICOM_TAG_BITS_STORED).GetContent()); } catch (OrthancException&) { @@ -138,7 +138,7 @@ try { - highBit_ = boost::lexical_cast(values.GetValue(DICOM_TAG_HIGH_BIT).AsString()); + highBit_ = boost::lexical_cast(values.GetValue(DICOM_TAG_HIGH_BIT).GetContent()); } catch (OrthancException&) { @@ -147,7 +147,7 @@ try { - pixelRepresentation = boost::lexical_cast(values.GetValue(DICOM_TAG_PIXEL_REPRESENTATION).AsString()); + pixelRepresentation = boost::lexical_cast(values.GetValue(DICOM_TAG_PIXEL_REPRESENTATION).GetContent()); } catch (OrthancException&) { @@ -160,7 +160,7 @@ // https://www.dabsoft.ch/dicom/3/C.7.6.3.1.3/ try { - planarConfiguration = boost::lexical_cast(values.GetValue(DICOM_TAG_PLANAR_CONFIGURATION).AsString()); + planarConfiguration = boost::lexical_cast(values.GetValue(DICOM_TAG_PLANAR_CONFIGURATION).GetContent()); } catch (OrthancException&) { @@ -179,9 +179,9 @@ try { - numberOfFrames_ = boost::lexical_cast(values.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).AsString()); + numberOfFrames_ = boost::lexical_cast(values.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent()); } - catch (OrthancException) + catch (OrthancException&) { // If the tag "NumberOfFrames" is absent, assume there is a single frame numberOfFrames_ = 1; diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomInstanceHasher.cpp --- a/Core/DicomFormat/DicomInstanceHasher.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/Core/DicomFormat/DicomInstanceHasher.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -60,10 +60,10 @@ { const DicomValue* patientId = instance.TestAndGetValue(DICOM_TAG_PATIENT_ID); - Setup(patientId == NULL ? "" : patientId->AsString(), - instance.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString(), - instance.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).AsString(), - instance.GetValue(DICOM_TAG_SOP_INSTANCE_UID).AsString()); + Setup(patientId == NULL ? "" : patientId->GetContent(), + instance.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent(), + instance.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).GetContent(), + instance.GetValue(DICOM_TAG_SOP_INSTANCE_UID).GetContent()); } const std::string& DicomInstanceHasher::HashPatient() diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomMap.cpp --- a/Core/DicomFormat/DicomMap.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/Core/DicomFormat/DicomMap.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -35,7 +35,6 @@ #include #include -#include "DicomString.h" #include "DicomArray.h" #include "../OrthancException.h" diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomMap.h --- a/Core/DicomFormat/DicomMap.h Wed Oct 21 16:52:23 2015 +0200 +++ b/Core/DicomFormat/DicomMap.h Thu Oct 22 07:52:24 2015 +0200 @@ -34,7 +34,6 @@ #include "DicomTag.h" #include "DicomValue.h" -#include "DicomString.h" #include "../Enumerations.h" #include @@ -105,14 +104,14 @@ void SetValue(const DicomTag& tag, const std::string& str) { - SetValue(tag, new DicomString(str)); + SetValue(tag, new DicomValue(str, false)); } void SetValue(uint16_t group, uint16_t element, const std::string& str) { - SetValue(group, element, new DicomString(str)); + SetValue(group, element, new DicomValue(str, false)); } bool HasTag(uint16_t group, uint16_t element) const diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomNullValue.h --- a/Core/DicomFormat/DicomNullValue.h Wed Oct 21 16:52:23 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * In addition, as a special exception, the copyright holders of this - * program give permission to link the code of its release with the - * OpenSSL project's "OpenSSL" library (or with modified versions of it - * that use the same license as the "OpenSSL" library), and distribute - * the linked executables. You must obey the GNU General Public License - * in all respects for all of the code used other than "OpenSSL". If you - * modify file(s) with this exception, you may extend this exception to - * your version of the file(s), but you are not obligated to do so. If - * you do not wish to do so, delete this exception statement from your - * version. If you delete this exception statement from all source files - * in the program, then also delete it here. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "DicomValue.h" - -namespace Orthanc -{ - class DicomNullValue : public DicomValue - { - public: - DicomNullValue() - { - } - - virtual DicomValue* Clone() const - { - return new DicomNullValue(); - } - - virtual std::string AsString() const - { - return "(null)"; - } - - virtual bool IsNull() const - { - return true; - } - }; -} diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomString.h --- a/Core/DicomFormat/DicomString.h Wed Oct 21 16:52:23 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * In addition, as a special exception, the copyright holders of this - * program give permission to link the code of its release with the - * OpenSSL project's "OpenSSL" library (or with modified versions of it - * that use the same license as the "OpenSSL" library), and distribute - * the linked executables. You must obey the GNU General Public License - * in all respects for all of the code used other than "OpenSSL". If you - * modify file(s) with this exception, you may extend this exception to - * your version of the file(s), but you are not obligated to do so. If - * you do not wish to do so, delete this exception statement from your - * version. If you delete this exception statement from all source files - * in the program, then also delete it here. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "DicomValue.h" - -namespace Orthanc -{ - class DicomString : public DicomValue - { - private: - std::string value_; - - public: - DicomString(const std::string& v) : value_(v) - { - } - - DicomString(const char* v) - { - if (v) - value_ = v; - else - value_ = ""; - } - - virtual DicomValue* Clone() const - { - return new DicomString(value_); - } - - virtual std::string AsString() const - { - return value_; - } - }; -} diff -r b953c6eef28d -r ec66a16aa398 Core/DicomFormat/DicomValue.h --- a/Core/DicomFormat/DicomValue.h Wed Oct 21 16:52:23 2015 +0200 +++ b/Core/DicomFormat/DicomValue.h Thu Oct 22 07:52:24 2015 +0200 @@ -32,22 +32,77 @@ #pragma once -#include "../IDynamicObject.h" +#include "../OrthancException.h" #include +#include namespace Orthanc { - class DicomValue : public IDynamicObject + class DicomValue : public boost::noncopyable { - public: - virtual DicomValue* Clone() const = 0; + private: + enum Type + { + Type_Null, + Type_String, + Type_Binary + }; + + Type type_; + std::string content_; + + DicomValue(const DicomValue& other) : + type_(other.type_), + content_(other.content_) + { + } - virtual std::string AsString() const = 0; + public: + DicomValue() : type_(Type_Null) + { + } + + DicomValue(const std::string& content, + bool isBinary) : + type_(isBinary ? Type_Binary : Type_String), + content_(content) + { + } + + DicomValue(const char* data, + size_t size, + bool isBinary) : + type_(isBinary ? Type_Binary : Type_String) + { + content_.assign(data, size); + } + + const std::string& GetContent() const + { + if (type_ == Type_Null) + { + throw OrthancException(ErrorCode_BadParameterType); + } + else + { + return content_; + } + } - virtual bool IsNull() const + bool IsNull() const + { + return type_ == Type_Null; + } + + bool IsBinary() const { - return false; + return type_ == Type_Binary; + } + + DicomValue* Clone() const + { + return new DicomValue(*this); } }; } diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/DicomFindQuery.cpp --- a/OrthancServer/DicomFindQuery.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/DicomFindQuery.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -349,9 +349,15 @@ for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) { + const DicomValue& value = mainTags.GetValue(*it); + if (value.IsBinary() || value.IsNull()) + { + return false; + } + Constraints::const_iterator constraint = constraints_.find(*it); if (constraint != constraints_.end() && - !constraint->second->Apply(mainTags.GetValue(*it).AsString())) + !constraint->second->Apply(value.GetContent())) { return false; } diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/DicomProtocol/DicomUserConnection.cpp --- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -457,7 +457,8 @@ const DicomValue* value = fix->TestAndGetValue(*it); if (value != NULL && - value->AsString() == "*") + !value->IsNull() && + value->GetContent() == "*") { fix->SetValue(*it, ""); } @@ -948,7 +949,7 @@ throw OrthancException(ErrorCode_InternalError); } - const std::string tmp = findResult.GetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL).AsString(); + const std::string tmp = findResult.GetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL).GetContent(); ResourceType level = StringToResourceType(tmp.c_str()); DicomMap move; diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/FromDcmtkBridge.cpp --- a/OrthancServer/FromDcmtkBridge.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/FromDcmtkBridge.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -47,8 +47,6 @@ #include "../Core/OrthancException.h" #include "../Core/Images/PngWriter.h" #include "../Core/Uuid.h" -#include "../Core/DicomFormat/DicomString.h" -#include "../Core/DicomFormat/DicomNullValue.h" #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h" #include @@ -380,18 +378,18 @@ { if (c == NULL) // This case corresponds to the empty string { - return new DicomString(""); + return new DicomValue("", false); } else { std::string s(c); std::string utf8 = Toolbox::ConvertToUtf8(s, encoding); - return new DicomString(utf8); + return new DicomValue(utf8, false); } } else { - return new DicomNullValue; + return new DicomValue; } } @@ -409,7 +407,7 @@ case EVR_OF: // other float case EVR_OW: // other word case EVR_UN: // unknown value representation - return new DicomNullValue; + return new DicomValue; /** * String types, should never happen at this point because of @@ -431,7 +429,7 @@ case EVR_UT: // unlimited text case EVR_PN: // person name case EVR_UI: // unique identifier - return new DicomNullValue; + return new DicomValue; /** @@ -442,54 +440,54 @@ { Sint32 f; if (dynamic_cast(element).getSint32(f).good()) - return new DicomString(boost::lexical_cast(f)); + return new DicomValue(boost::lexical_cast(f), false); else - return new DicomNullValue; + return new DicomValue; } case EVR_SS: // signed short { Sint16 f; if (dynamic_cast(element).getSint16(f).good()) - return new DicomString(boost::lexical_cast(f)); + return new DicomValue(boost::lexical_cast(f), false); else - return new DicomNullValue; + return new DicomValue; } case EVR_UL: // unsigned long { Uint32 f; if (dynamic_cast(element).getUint32(f).good()) - return new DicomString(boost::lexical_cast(f)); + return new DicomValue(boost::lexical_cast(f), false); else - return new DicomNullValue; + return new DicomValue; } case EVR_US: // unsigned short { Uint16 f; if (dynamic_cast(element).getUint16(f).good()) - return new DicomString(boost::lexical_cast(f)); + return new DicomValue(boost::lexical_cast(f), false); else - return new DicomNullValue; + return new DicomValue; } case EVR_FL: // float single-precision { Float32 f; if (dynamic_cast(element).getFloat32(f).good()) - return new DicomString(boost::lexical_cast(f)); + return new DicomValue(boost::lexical_cast(f), false); else - return new DicomNullValue; + return new DicomValue; } case EVR_FD: // float double-precision { Float64 f; if (dynamic_cast(element).getFloat64(f).good()) - return new DicomString(boost::lexical_cast(f)); + return new DicomValue(boost::lexical_cast(f), false); else - return new DicomNullValue; + return new DicomValue; } @@ -503,11 +501,11 @@ if (dynamic_cast(element).getTagVal(tag, 0).good()) { DicomTag t(tag.getGroup(), tag.getElement()); - return new DicomString(t.Format()); + return new DicomValue(t.Format(), false); } else { - return new DicomNullValue; + return new DicomValue; } } @@ -518,7 +516,7 @@ **/ case EVR_SQ: // sequence of items - return new DicomNullValue; + return new DicomValue; /** @@ -542,7 +540,7 @@ case EVR_PixelData: // used internally for uncompressed pixeld data case EVR_OverlayData: // used internally for overlay data case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR - return new DicomNullValue; + return new DicomValue; /** @@ -550,16 +548,16 @@ **/ default: - return new DicomNullValue; + return new DicomValue; } } catch (boost::bad_lexical_cast) { - return new DicomNullValue; + return new DicomValue; } catch (std::bad_cast) { - return new DicomNullValue; + return new DicomValue; } } @@ -625,8 +623,6 @@ DicomToJsonFormat format, unsigned int maxStringLength) { - std::string content = value.AsString(); - switch (format) { case DicomToJsonFormat_Short: @@ -636,9 +632,9 @@ if (!value.IsNull() && (maxStringLength == 0 || - content.size() <= maxStringLength)) + value.GetContent().size() <= maxStringLength)) { - target = content; + target = value.GetContent(); } break; @@ -656,10 +652,10 @@ else { if (maxStringLength == 0 || - content.size() <= maxStringLength) + value.GetContent().size() <= maxStringLength) { target["Type"] = "String"; - target["Value"] = content; + target["Value"] = value.GetContent(); } else { @@ -866,18 +862,6 @@ } - void FromDcmtkBridge::Print(FILE* fp, const DicomMap& m) - { - for (DicomMap::Map::const_iterator - it = m.map_.begin(); it != m.map_.end(); ++it) - { - DicomTag t = it->first; - std::string s = it->second->AsString(); - fprintf(fp, "0x%04x 0x%04x (%s) [%s]\n", t.GetGroup(), t.GetElement(), GetName(t).c_str(), s.c_str()); - } - } - - void FromDcmtkBridge::ToJson(Json::Value& result, const DicomMap& values, bool simplify) @@ -894,7 +878,15 @@ { if (simplify) { - result[GetName(it->first)] = it->second->AsString(); + if (it->second->IsNull()) + { + result[GetName(it->first)] = Json::nullValue; + } + else + { + // TODO IsBinary + result[GetName(it->first)] = it->second->GetContent(); + } } else { @@ -909,8 +901,9 @@ } else { + // TODO IsBinary value["Type"] = "String"; - value["Value"] = it->second->AsString(); + value["Value"] = it->second->GetContent(); } result[it->first.Format()] = value; diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/FromDcmtkBridge.h --- a/OrthancServer/FromDcmtkBridge.h Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/FromDcmtkBridge.h Thu Oct 22 07:52:24 2015 +0200 @@ -109,9 +109,6 @@ target.SetValue(ParseTag(tagName), value); } - static void Print(FILE* fp, - const DicomMap& m); - static void ToJson(Json::Value& result, const DicomMap& values, bool simplify); diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/OrthancFindRequestHandler.cpp --- a/OrthancServer/OrthancFindRequestHandler.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/OrthancFindRequestHandler.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -240,12 +240,14 @@ **/ const DicomValue* levelTmp = input.TestAndGetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL); - if (levelTmp == NULL) + if (levelTmp == NULL || + levelTmp->IsNull() || + levelTmp->IsBinary()) { throw OrthancException(ErrorCode_BadRequest); } - ResourceType level = StringToResourceType(levelTmp->AsString().c_str()); + ResourceType level = StringToResourceType(levelTmp->GetContent().c_str()); if (level != ResourceType_Patient && level != ResourceType_Study && @@ -265,7 +267,7 @@ { LOG(INFO) << " " << query.GetElement(i).GetTag() << " " << FromDcmtkBridge::GetName(query.GetElement(i).GetTag()) - << " = " << query.GetElement(i).GetValue().AsString(); + << " = " << query.GetElement(i).GetValue().GetContent(); } } @@ -288,7 +290,7 @@ continue; } - std::string value = query.GetElement(i).GetValue().AsString(); + std::string value = query.GetElement(i).GetValue().GetContent(); if (value.size() == 0) { // An empty string corresponds to a "*" wildcard constraint, so we ignore it diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/OrthancMoveRequestHandler.cpp --- a/OrthancServer/OrthancMoveRequestHandler.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/OrthancMoveRequestHandler.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -138,10 +138,17 @@ return false; } - std::string value = input.GetValue(tag).AsString(); + const DicomValue& value = input.GetValue(tag); + if (value.IsNull() || + value.IsBinary()) + { + return false; + } + + const std::string& content = value.GetContent(); std::list ids; - context_.GetIndex().LookupIdentifier(ids, tag, value, level); + context_.GetIndex().LookupIdentifier(ids, tag, content, level); if (ids.size() != 1) { @@ -170,7 +177,7 @@ { LOG(INFO) << " " << query.GetElement(i).GetTag() << " " << FromDcmtkBridge::GetName(query.GetElement(i).GetTag()) - << " = " << query.GetElement(i).GetValue().AsString(); + << " = " << query.GetElement(i).GetValue().GetContent(); } } } @@ -183,7 +190,9 @@ const DicomValue* levelTmp = input.TestAndGetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL); - if (levelTmp == NULL) + if (levelTmp == NULL || + levelTmp->IsNull() || + levelTmp->IsBinary()) { // The query level is not present in the C-Move request, which // does not follow the DICOM standard. This is for instance the @@ -208,7 +217,7 @@ } assert(levelTmp != NULL); - ResourceType level = StringToResourceType(levelTmp->AsString().c_str()); + ResourceType level = StringToResourceType(levelTmp->GetContent().c_str()); /** diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -198,8 +198,8 @@ return; } - if (fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && - fields.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) + if (fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).GetContent().size() <= 2 && + fields.GetValue(DICOM_TAG_PATIENT_ID).GetContent().size() <= 2) { return; } @@ -228,9 +228,9 @@ return; } - if ((fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && - fields.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) || - fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString().size() <= 2) + if ((fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).GetContent().size() <= 2 && + fields.GetValue(DICOM_TAG_PATIENT_ID).GetContent().size() <= 2) || + fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent().size() <= 2) { return; } @@ -259,10 +259,10 @@ return; } - if ((fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && - fields.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) || - fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString().size() <= 2 || - fields.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).AsString().size() <= 2) + if ((fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).GetContent().size() <= 2 && + fields.GetValue(DICOM_TAG_PATIENT_ID).GetContent().size() <= 2) || + fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent().size() <= 2 || + fields.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).GetContent().size() <= 2) { return; } diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/ParsedDicomFile.cpp --- a/OrthancServer/ParsedDicomFile.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/ParsedDicomFile.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -90,8 +90,6 @@ #include "../Core/Images/ImageBuffer.h" #include "../Core/Images/PngWriter.h" #include "../Core/Uuid.h" -#include "../Core/DicomFormat/DicomString.h" -#include "../Core/DicomFormat/DicomNullValue.h" #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h" #include "../Core/Images/PngReader.h" @@ -766,13 +764,15 @@ std::auto_ptr v(FromDcmtkBridge::ConvertLeafElement (*element, DicomToJsonFlags_Default, GetEncoding())); - if (v.get() == NULL) + if (v.get() == NULL || + v->IsNull()) { value = ""; } else { - value = v->AsString(); + // TODO v->IsBinary() + value = v->GetContent(); } return true; diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/ParsedDicomFile.h --- a/OrthancServer/ParsedDicomFile.h Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/ParsedDicomFile.h Thu Oct 22 07:52:24 2015 +0200 @@ -37,6 +37,7 @@ #include "ServerEnumerations.h" #include "../Core/Images/ImageAccessor.h" #include "../Core/Images/ImageBuffer.h" +#include "../Core/IDynamicObject.h" namespace Orthanc { diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/ServerIndex.cpp --- a/OrthancServer/ServerIndex.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/ServerIndex.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -394,8 +394,8 @@ (value2 = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS)) != NULL) { // Patch for series with temporal positions thanks to Will Ryder - int64_t imagesInAcquisition = boost::lexical_cast(value->AsString()); - int64_t countTemporalPositions = boost::lexical_cast(value2->AsString()); + int64_t imagesInAcquisition = boost::lexical_cast(value->GetContent()); + int64_t countTemporalPositions = boost::lexical_cast(value2->GetContent()); std::string expected = boost::lexical_cast(imagesInAcquisition * countTemporalPositions); db.SetMetadata(series, MetadataType_Series_ExpectedNumberOfInstances, expected); } @@ -404,18 +404,21 @@ (value2 = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_TIME_SLICES)) != NULL) { // Support of Cardio-PET images - int64_t numberOfSlices = boost::lexical_cast(value->AsString()); - int64_t numberOfTimeSlices = boost::lexical_cast(value2->AsString()); + int64_t numberOfSlices = boost::lexical_cast(value->GetContent()); + int64_t numberOfTimeSlices = boost::lexical_cast(value2->GetContent()); std::string expected = boost::lexical_cast(numberOfSlices * numberOfTimeSlices); db.SetMetadata(series, MetadataType_Series_ExpectedNumberOfInstances, expected); } else if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES)) != NULL) { - db.SetMetadata(series, MetadataType_Series_ExpectedNumberOfInstances, value->AsString()); + db.SetMetadata(series, MetadataType_Series_ExpectedNumberOfInstances, value->GetContent()); } } - catch (boost::bad_lexical_cast) + catch (OrthancException&) + { + } + catch (boost::bad_lexical_cast&) { } } @@ -768,8 +771,12 @@ if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL || (value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGE_INDEX)) != NULL) { - db_.SetMetadata(instance, MetadataType_Instance_IndexInSeries, value->AsString()); - instanceMetadata[MetadataType_Instance_IndexInSeries] = value->AsString(); + if (!value->IsNull() && + !value->IsBinary()) + { + db_.SetMetadata(instance, MetadataType_Instance_IndexInSeries, value->GetContent()); + instanceMetadata[MetadataType_Instance_IndexInSeries] = value->GetContent(); + } } // Check whether the series of this new instance is now completed @@ -1197,22 +1204,22 @@ switch (currentType) { case ResourceType_Patient: - patientId = map.GetValue(DICOM_TAG_PATIENT_ID).AsString(); + patientId = map.GetValue(DICOM_TAG_PATIENT_ID).GetContent(); done = true; break; case ResourceType_Study: - studyInstanceUid = map.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString(); + studyInstanceUid = map.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent(); currentType = ResourceType_Patient; break; case ResourceType_Series: - seriesInstanceUid = map.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).AsString(); + seriesInstanceUid = map.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).GetContent(); currentType = ResourceType_Study; break; case ResourceType_Instance: - sopInstanceUid = map.GetValue(DICOM_TAG_SOP_INSTANCE_UID).AsString(); + sopInstanceUid = map.GetValue(DICOM_TAG_SOP_INSTANCE_UID).GetContent(); currentType = ResourceType_Series; break; diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/ServerIndexChange.h --- a/OrthancServer/ServerIndexChange.h Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/ServerIndexChange.h Thu Oct 22 07:52:24 2015 +0200 @@ -33,6 +33,7 @@ #pragma once #include "ServerEnumerations.h" +#include "../Core/IDynamicObject.h" #include "../Core/Toolbox.h" #include diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/ServerToolbox.cpp --- a/OrthancServer/ServerToolbox.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/ServerToolbox.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -91,6 +91,21 @@ } + static std::string ValueAsString(const DicomMap& summary, + const DicomTag& tag) + { + const DicomValue& value = summary.GetValue(tag); + if (value.IsNull()) + { + return "(null)"; + } + else + { + return value.GetContent(); + } + } + + void LogMissingRequiredTag(const DicomMap& summary) { std::string s, t; @@ -99,7 +114,7 @@ { if (t.size() > 0) t += ", "; - t += "PatientID=" + summary.GetValue(DICOM_TAG_PATIENT_ID).AsString(); + t += "PatientID=" + ValueAsString(summary, DICOM_TAG_PATIENT_ID); } else { @@ -112,7 +127,7 @@ { if (t.size() > 0) t += ", "; - t += "StudyInstanceUID=" + summary.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString(); + t += "StudyInstanceUID=" + ValueAsString(summary, DICOM_TAG_STUDY_INSTANCE_UID); } else { @@ -125,7 +140,7 @@ { if (t.size() > 0) t += ", "; - t += "SeriesInstanceUID=" + summary.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).AsString(); + t += "SeriesInstanceUID=" + ValueAsString(summary, DICOM_TAG_SERIES_INSTANCE_UID); } else { @@ -138,7 +153,7 @@ { if (t.size() > 0) t += ", "; - t += "SOPInstanceUID=" + summary.GetValue(DICOM_TAG_SOP_INSTANCE_UID).AsString(); + t += "SOPInstanceUID=" + ValueAsString(summary, DICOM_TAG_SOP_INSTANCE_UID); } else { @@ -168,7 +183,12 @@ { const DicomElement& element = flattened.GetElement(i); const DicomTag& tag = element.GetTag(); - database.SetMainDicomTag(resource, tag, element.GetValue().AsString()); + const DicomValue& value = element.GetValue(); + if (!value.IsNull() && + !value.IsBinary()) + { + database.SetMainDicomTag(resource, tag, element.GetValue().GetContent()); + } } } @@ -180,9 +200,10 @@ { const DicomValue* value = tags.TestAndGetValue(tag); if (value != NULL && - !value->IsNull()) + !value->IsNull() && + !value->IsBinary()) { - std::string s = value->AsString(); + std::string s = value->GetContent(); if (tag != DICOM_TAG_PATIENT_ID && tag != DICOM_TAG_STUDY_INSTANCE_UID && diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/SliceOrdering.cpp --- a/OrthancServer/SliceOrdering.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/SliceOrdering.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -82,13 +82,14 @@ const DicomValue* value = map.TestAndGetValue(tag); if (value == NULL || - value->IsNull()) + value->IsNull() || + value->IsBinary()) { return false; } else { - return TokenizeVector(result, value->AsString(), expectedSize); + return TokenizeVector(result, value->GetContent(), expectedSize); } } @@ -117,11 +118,12 @@ const DicomValue* frames = instance.TestAndGetValue(DICOM_TAG_NUMBER_OF_FRAMES); if (frames != NULL && - !frames->IsNull()) + !frames->IsNull() && + !frames->IsBinary()) { try { - framesCount_ = boost::lexical_cast(frames->AsString()); + framesCount_ = boost::lexical_cast(frames->GetContent()); } catch (boost::bad_lexical_cast&) { diff -r b953c6eef28d -r ec66a16aa398 OrthancServer/ToDcmtkBridge.cpp --- a/OrthancServer/ToDcmtkBridge.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/OrthancServer/ToDcmtkBridge.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -52,8 +52,11 @@ for (DicomMap::Map::const_iterator it = map.map_.begin(); it != map.map_.end(); ++it) { - std::string s = it->second->AsString(); - DU_putStringDOElement(result.get(), Convert(it->first), s.c_str()); + if (!it->second->IsNull()) + { + std::string s = it->second->GetContent(); + DU_putStringDOElement(result.get(), Convert(it->first), s.c_str()); + } } return result.release(); diff -r b953c6eef28d -r ec66a16aa398 UnitTestsSources/DicomMapTests.cpp --- a/UnitTestsSources/DicomMapTests.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/UnitTestsSources/DicomMapTests.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -36,7 +36,6 @@ #include "../Core/Uuid.h" #include "../Core/OrthancException.h" #include "../Core/DicomFormat/DicomMap.h" -#include "../Core/DicomFormat/DicomNullValue.h" #include "../OrthancServer/FromDcmtkBridge.h" #include @@ -103,7 +102,7 @@ m.SetValue(DICOM_TAG_PATIENT_ID, "PatientID"); ASSERT_TRUE(m.HasTag(0x0010, 0x0020)); m.SetValue(DICOM_TAG_PATIENT_ID, "PatientID2"); - ASSERT_EQ("PatientID2", m.GetValue(0x0010, 0x0020).AsString()); + ASSERT_EQ("PatientID2", m.GetValue(0x0010, 0x0020).GetContent()); m.GetTags(s); ASSERT_EQ(2u, s.size()); @@ -116,14 +115,14 @@ ASSERT_EQ(DICOM_TAG_PATIENT_NAME, *s.begin()); std::auto_ptr mm(m.Clone()); - ASSERT_EQ("PatientName", mm->GetValue(DICOM_TAG_PATIENT_NAME).AsString()); + ASSERT_EQ("PatientName", mm->GetValue(DICOM_TAG_PATIENT_NAME).GetContent()); m.SetValue(DICOM_TAG_PATIENT_ID, "Hello"); ASSERT_THROW(mm->GetValue(DICOM_TAG_PATIENT_ID), OrthancException); mm->CopyTagIfExists(m, DICOM_TAG_PATIENT_ID); - ASSERT_EQ("Hello", mm->GetValue(DICOM_TAG_PATIENT_ID).AsString()); + ASSERT_EQ("Hello", mm->GetValue(DICOM_TAG_PATIENT_ID).GetContent()); - DicomNullValue v; + DicomValue v; ASSERT_TRUE(v.IsNull()); } diff -r b953c6eef28d -r ec66a16aa398 UnitTestsSources/ServerIndexTests.cpp --- a/UnitTestsSources/ServerIndexTests.cpp Wed Oct 21 16:52:23 2015 +0200 +++ b/UnitTestsSources/ServerIndexTests.cpp Thu Oct 22 07:52:24 2015 +0200 @@ -33,7 +33,6 @@ #include "PrecompiledHeadersUnitTests.h" #include "gtest/gtest.h" -#include "../Core/DicomFormat/DicomNullValue.h" #include "../Core/FileStorage/FilesystemStorage.h" #include "../Core/Logging.h" #include "../Core/Uuid.h"