/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "gdcmTagPath.h" #include "gdcmTag.h" #include #include // strlen #include // abort #include // sscanf namespace gdcm { /* * Implementation detail: a tag path is simply a vector. * with the following convention: * First tag is a valid tag, * Second tag is an item number (or 0) * Third tag is a valid tag * ... * and so on an so forth */ TagPath::TagPath():Path() { } TagPath::~TagPath() = default; void TagPath::Print(std::ostream &os) const { unsigned int flip = 0; std::vector::const_iterator it = Path.begin(); for(; it != Path.end(); ++it) { if( flip % 2 == 0 ) { os << *it << "/"; } else // item number { // assert( it->GetElementTag() < 255 ); // how many item max can we have ? os << it->GetElementTag() << "/"; } ++flip; } } bool TagPath::IsValid(const char *path) { TagPath tp; return tp.ConstructFromString(path); } bool TagPath::ConstructFromTagList(Tag const *l, unsigned int n) { //Path = std::vector(l,l+n); Path.clear(); for(unsigned int i = 0; i < n; ++i) { Path.push_back( l[i] ); if( i+1 < n ) { Path.emplace_back(0 ); } } return true; } bool TagPath::ConstructFromString(const char *path) { Path.clear(); if(!path) return false; unsigned int flip = 0; size_t pos = 0; const size_t len = strlen(path); if(!len) return false; // Need to start with a / if( path[pos] == '/' ) { ++pos; } else { return false; } while( pos != len ) { Tag t; if( flip % 2 == 0 ) { if( t.ReadFromCommaSeparatedString( path+pos ) ) { pos += 4 + 4 + 1; Path.push_back( t ); } else { return false; } } else { unsigned int value = 0; if( path[pos] == '*' ) { t.SetElementTag( 0 ); pos++; Path.push_back( t ); } else if( sscanf(path+pos, "%u/", &value) == 1 ) { } } ++flip; if( pos != len && path[pos] == '/' ) ++pos; //else assert(0); } return true; } bool TagPath::Push(Tag const & t) { if( Path.size() % 2 == 0 ) { Path.push_back( t ); return true; } return false; } bool TagPath::Push(unsigned int itemnum) { if( Path.size() % 2 == 1 ) { Path.emplace_back(itemnum ); return true; } return false; } }