1 /** 2 * Orthanc - A Lightweight, RESTful DICOM Store 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics 4 * Department, University Hospital of Liege, Belgium 5 * Copyright (C) 2017-2021 Osimis S.A., Belgium 6 * 7 * This program is free software: you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public License 9 * as published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this program. If not, see 19 * <http://www.gnu.org/licenses/>. 20 **/ 21 22 23 #include "../PrecompiledHeaders.h" 24 #include "DicomValue.h" 25 26 #include "../OrthancException.h" 27 #include "../SerializationToolbox.h" 28 #include "../Toolbox.h" 29 30 #include <boost/lexical_cast.hpp> 31 32 namespace Orthanc 33 { DicomValue()34 DicomValue::DicomValue() : 35 type_(Type_Null) 36 { 37 } 38 39 DicomValue(const DicomValue & other)40 DicomValue::DicomValue(const DicomValue& other) : 41 type_(other.type_), 42 content_(other.content_) 43 { 44 } 45 46 DicomValue(const std::string & content,bool isBinary)47 DicomValue::DicomValue(const std::string& content, 48 bool isBinary) : 49 type_(isBinary ? Type_Binary : Type_String), 50 content_(content) 51 { 52 } 53 54 DicomValue(const char * data,size_t size,bool isBinary)55 DicomValue::DicomValue(const char* data, 56 size_t size, 57 bool isBinary) : 58 type_(isBinary ? Type_Binary : Type_String) 59 { 60 content_.assign(data, size); 61 } 62 63 GetContent() const64 const std::string& DicomValue::GetContent() const 65 { 66 if (type_ == Type_Null) 67 { 68 throw OrthancException(ErrorCode_BadParameterType); 69 } 70 else 71 { 72 return content_; 73 } 74 } 75 IsNull() const76 bool DicomValue::IsNull() const 77 { 78 return type_ == Type_Null; 79 } 80 IsBinary() const81 bool DicomValue::IsBinary() const 82 { 83 return type_ == Type_Binary; 84 } 85 86 Clone() const87 DicomValue* DicomValue::Clone() const 88 { 89 return new DicomValue(*this); 90 } 91 92 93 #if ORTHANC_ENABLE_BASE64 == 1 FormatDataUriScheme(std::string & target,const std::string & mime) const94 void DicomValue::FormatDataUriScheme(std::string& target, 95 const std::string& mime) const 96 { 97 Toolbox::EncodeBase64(target, GetContent()); 98 target.insert(0, "data:" + mime + ";base64,"); 99 } 100 FormatDataUriScheme(std::string & target) const101 void DicomValue::FormatDataUriScheme(std::string& target) const 102 { 103 FormatDataUriScheme(target, MIME_BINARY); 104 } 105 #endif 106 ParseInteger32(int32_t & result) const107 bool DicomValue::ParseInteger32(int32_t& result) const 108 { 109 if (IsBinary() || 110 IsNull()) 111 { 112 return false; 113 } 114 else 115 { 116 return SerializationToolbox::ParseInteger32(result, GetContent()); 117 } 118 } 119 ParseInteger64(int64_t & result) const120 bool DicomValue::ParseInteger64(int64_t& result) const 121 { 122 if (IsBinary() || 123 IsNull()) 124 { 125 return false; 126 } 127 else 128 { 129 return SerializationToolbox::ParseInteger64(result, GetContent()); 130 } 131 } 132 ParseUnsignedInteger32(uint32_t & result) const133 bool DicomValue::ParseUnsignedInteger32(uint32_t& result) const 134 { 135 if (IsBinary() || 136 IsNull()) 137 { 138 return false; 139 } 140 else 141 { 142 return SerializationToolbox::ParseUnsignedInteger32(result, GetContent()); 143 } 144 } 145 ParseUnsignedInteger64(uint64_t & result) const146 bool DicomValue::ParseUnsignedInteger64(uint64_t& result) const 147 { 148 if (IsBinary() || 149 IsNull()) 150 { 151 return false; 152 } 153 else 154 { 155 return SerializationToolbox::ParseUnsignedInteger64(result, GetContent()); 156 } 157 } 158 ParseFloat(float & result) const159 bool DicomValue::ParseFloat(float& result) const 160 { 161 if (IsBinary() || 162 IsNull()) 163 { 164 return false; 165 } 166 else 167 { 168 return SerializationToolbox::ParseFloat(result, GetContent()); 169 } 170 } 171 ParseDouble(double & result) const172 bool DicomValue::ParseDouble(double& result) const 173 { 174 if (IsBinary() || 175 IsNull()) 176 { 177 return false; 178 } 179 else 180 { 181 return SerializationToolbox::ParseDouble(result, GetContent()); 182 } 183 } 184 ParseFirstFloat(float & result) const185 bool DicomValue::ParseFirstFloat(float& result) const 186 { 187 if (IsBinary() || 188 IsNull()) 189 { 190 return false; 191 } 192 else 193 { 194 return SerializationToolbox::ParseFirstFloat(result, GetContent()); 195 } 196 } 197 ParseFirstUnsignedInteger(unsigned int & result) const198 bool DicomValue::ParseFirstUnsignedInteger(unsigned int& result) const 199 { 200 uint64_t value; 201 202 if (IsBinary() || 203 IsNull()) 204 { 205 return false; 206 } 207 else if (SerializationToolbox::ParseFirstUnsignedInteger64(value, GetContent())) 208 { 209 result = static_cast<unsigned int>(value); 210 return (static_cast<uint64_t>(result) == value); // Check no overflow 211 } 212 else 213 { 214 return false; 215 } 216 } 217 CopyToString(std::string & result,bool allowBinary) const218 bool DicomValue::CopyToString(std::string& result, 219 bool allowBinary) const 220 { 221 if (IsNull()) 222 { 223 return false; 224 } 225 else if (IsBinary() && !allowBinary) 226 { 227 return false; 228 } 229 else 230 { 231 result.assign(content_); 232 return true; 233 } 234 } 235 236 237 static const char* KEY_TYPE = "Type"; 238 static const char* KEY_CONTENT = "Content"; 239 Serialize(Json::Value & target) const240 void DicomValue::Serialize(Json::Value& target) const 241 { 242 target = Json::objectValue; 243 244 switch (type_) 245 { 246 case Type_Null: 247 target[KEY_TYPE] = "Null"; 248 break; 249 250 case Type_String: 251 target[KEY_TYPE] = "String"; 252 target[KEY_CONTENT] = content_; 253 break; 254 255 case Type_Binary: 256 { 257 target[KEY_TYPE] = "Binary"; 258 259 std::string base64; 260 Toolbox::EncodeBase64(base64, content_); 261 target[KEY_CONTENT] = base64; 262 break; 263 } 264 265 default: 266 throw OrthancException(ErrorCode_InternalError); 267 } 268 } 269 Unserialize(const Json::Value & source)270 void DicomValue::Unserialize(const Json::Value& source) 271 { 272 std::string type = SerializationToolbox::ReadString(source, KEY_TYPE); 273 274 if (type == "Null") 275 { 276 type_ = Type_Null; 277 content_.clear(); 278 } 279 else if (type == "String") 280 { 281 type_ = Type_String; 282 content_ = SerializationToolbox::ReadString(source, KEY_CONTENT); 283 } 284 else if (type == "Binary") 285 { 286 type_ = Type_Binary; 287 288 const std::string base64 =SerializationToolbox::ReadString(source, KEY_CONTENT); 289 Toolbox::DecodeBase64(content_, base64); 290 } 291 else 292 { 293 throw OrthancException(ErrorCode_BadFileFormat); 294 } 295 } 296 } 297