# ReadGEMSSDO.cxx

    /*=========================================================================

      Program: GDCM (Grassroots DICOM). A DICOM library
      Module:  $URL$

      Copyright (c) 2006-2010 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 "gdcmReader.h"
    #include "gdcmDataElement.h"
    #include "gdcmPrivateTag.h"

    #include <iostream>
    #include <string>

    using namespace gdcm;

    struct SDOElement
    {
      typedef std::vector<std::string>::size_type SizeType;
      const char *GetData(SizeType index) const {
        return Data[index].c_str();
      }
      SizeType GetNumberOfData() const {
        return Data.size();
      }
      void SetData(SizeType index, const char *data) {
        Data[index] = data;
      }
      const char *GetDataFormat() const {
        return DataFormat.c_str();
      }
      void SetDataFormat(const char *dataformat, SizeType num) {
        DataFormat = dataformat;
        Data.resize( num );
      }
      void Print( std::ostream &os ) const {
        os << DataFormat << ":" << std::endl;
        std::vector<std::string>::const_iterator it = Data.begin();
        size_t s = 0;
        for( ; it != Data.end(); ++it )
          {
          os << "  (" << s++ << ") " << *it << std::endl;
          }
      }
    private:
      std::string DataFormat;
      std::vector<std::string> Data;
    };

    class SDOHeader
    {
    public:
      typedef std::vector<SDOElement> SDOElements;
      typedef SDOElements::size_type SizeType;
      SizeType GetNumberOfSDOElements() const {
      return InternalSDODataSet.size();
      }
      void AddSDOElement(SDOElement const &sdoelement) {
      InternalSDODataSet.push_back( sdoelement );
      }
      const SDOElement &GetSDOElement(SizeType index) const {
      return InternalSDODataSet[index];
      }
      const SDOElement &GetSDOElementByName(const char *name) const {
      return InternalSDODataSet[0];
      }
      void LoadFromAttributes(std::string const &s1, std::string const &s2)
        {
      std::string tok;
      std::string tok2;
      std::stringstream strstr(s1);
      std::stringstream strstr2(s2);

      SDOElement element;
      // Do format
      size_t count = 0;
      while ( std::getline ( strstr2, tok, '\\' ) )
        {
        //std::cout << tok << " ";
        std::getline ( strstr2, tok2, '\\' );
        //std::cout << tok2 << std::endl;
        count += atoi( tok2.c_str() );
        element.SetDataFormat( tok.c_str(), atoi( tok2.c_str() ) );
        for( size_t t = 0; t < element.GetNumberOfData(); ++t )
          {
          std::getline ( strstr, tok, '\\' );
          element.SetData(t, tok.c_str() );
          }
        AddSDOElement( element );
        }
      //while ( std::getline ( strstr, tok, '^' ) )
    //  while ( std::getline ( strstr, tok, '\\' ) )
    //    {
    //    std::cout << tok << std::endl;
    //    count++;
    //    }
    //  std::cout << "Count: " << count << std::endl;
    //  count = 0;

    //  std::cout << "Count: " << count << std::endl;

        }
      void Print( std::ostream &os ) const {
        SDOElements::const_iterator it = InternalSDODataSet.begin();
        for( ; it != InternalSDODataSet.end(); ++it )
          {
          it->Print ( os );
          }
      }
    private:
      SDOElements InternalSDODataSet;
    };

    bool sdo_decode( DataElement const &stringdata, DataElement const &stringdataformat )
    {
      const char *sd = stringdata.GetByteValue()->GetPointer();
      const size_t len_sd = stringdata.GetByteValue()->GetLength();

      std::string s1 = std::string( sd, len_sd );

      const char *sdf = stringdataformat.GetByteValue()->GetPointer();
      const size_t len_sdf = stringdataformat.GetByteValue()->GetLength();

      std::string s2 = std::string( sdf, len_sdf );

    //  std::cout << s1 << std::endl;
    //  std::cout << s2 << std::endl;

      SDOHeader header;
      header.LoadFromAttributes( s1, s2 );

      header.Print( std::cout );

      return true;
    }

    int main(int argc, char *argv[])
    {
      if( argc < 2 )
        {
        std::cerr << argv[0] << " input.dcm" << std::endl;
        return 1;
        }
      const char *filename = argv[1];
      Reader reader;
      reader.SetFileName( filename );
      if( !reader.Read() )
        {
        return 1;
        }

      File &file = reader.GetFile();
      DataSet &ds = file.GetDataSet();

      // StringData (0033,xx1F) 3 "GEMS_GENIE_1" List of SDO parameters stored as
      // list of strings
      const PrivateTag tstringdata(0x33,0x1f,"GEMS_GENIE_1");
      // StringDataFormat (0033,xx23) 3 "GEMS_GENIE_1" Format of string parameters;
      // contains information about name and number of strings in list
      const PrivateTag tstringdataformat(0x33,0x23,"GEMS_GENIE_1");

      if( !ds.FindDataElement( tstringdata ) ) return 1;
      const DataElement& stringdata = ds.GetDataElement( tstringdata );
      if( !ds.FindDataElement( tstringdataformat ) ) return 1;
      const DataElement& stringdataformat = ds.GetDataElement( tstringdataformat );

      sdo_decode( stringdata, stringdataformat );

      return 0;
    }