#include <iomanip>
static bool compfn(const char *s1, const char *s2)
{
return strcmp(s1,s2) < 0 ? true : false;
}
static const char *PDFStrings[] = {
"COILSTATE",
"HARDWARE_CONFIG",
"PDF_CONTROL_GEN_PARS",
"PDF_CONTROL_PREP_PARS",
"PDF_CONTROL_RECON_PARS",
"PDF_CONTROL_SCAN_PARS",
"PDF_EXAM_PARS",
"PDF_HARDWARE_PARS",
"PDF_PREP_PARS",
"PDF_PRESCAN_COIL_PARS",
"PDF_SPT_PARS",
};
static bool isvalidpdfstring( const char *pdfstring )
{
assert( pdfstring );
static const size_t n = sizeof( PDFStrings ) / sizeof( *PDFStrings );
static const char **begin = PDFStrings;
static const char **end = begin + n;
return std::binary_search(begin, end, pdfstring, compfn);
}
typedef enum
{
param_float = 0,
param_integer = 1,
param_string = 2,
param_3,
param_enum = 4
} param_type;
static const char *gettypenamefromtype( int i)
{
const char *ret = nullptr;
param_type e = (param_type)i;
switch( e )
{
case param_float:
ret = "float";
break;
case param_integer:
ret = "int";
break;
case param_string:
ret = "string";
break;
case param_3:
ret = "??";
break;
case param_enum:
ret = "enum";
break;
}
assert( ret );
return ret;
}
struct header
{
int32_t v1;
uint16_t nints;
uint16_t v3;
int32_t v4;
uint32_t nfloats;
int32_t v6;
uint32_t nstrings;
int32_t v8;
uint32_t numparams;
uint32_t getnints() const { return nints; }
uint32_t getnfloats() const { return nfloats; }
uint32_t getnstrings() const { return nstrings; }
uint32_t getnparams() const { return numparams; }
void read( std::istream & is )
{
is.read( (char*)&v1,sizeof(v1));
if( v1 == 0x01 ) {
nints = 0;
v3 = 0;
v4 = 0;
nfloats = 0;
v6 = 0;
nstrings = 0;
v8 = 0;
numparams = 0;
uint32_t bla;
is.read( (char*)&bla, sizeof(bla) );
assert( bla == 0x2 || bla == 0x3 );
nstrings = 1;
numparams = 1;
} else {
is.read( (char*)&nints,sizeof(nints));
is.read( (char*)&v3,sizeof(v3));
assert( v3 == 0 );
is.read( (char*)&v4,sizeof(v4));
is.read( (char*)&nfloats,sizeof(nfloats));
is.read( (char*)&v6,sizeof(v6));
is.read( (char*)&nstrings,sizeof(nstrings));
is.read( (char*)&v8,sizeof(v8));
assert( v8 == 8 );
is.read( (char*)&numparams,sizeof(numparams));
}
}
void print( std::ostream & os )
{
os << v1 << ",";
os << nints << ",";
os << v3 << ",";
os << v4 << ",";
os << nfloats << ",";
os << v6 << ",";
os << nstrings << ",";
os << v8 << ",";
os << numparams << std::endl;
}
};
struct param
{
char name[32+1];
uint8_t boolean;
int32_t type;
union {
uint32_t val;
char * ptr; } v4;
int32_t offset;
param_type gettype() const { return (param_type)type; }
uint32_t getdim()
const {
return dim; }
void read_direct_int( std::istream & is ) {
uint32_t bla;
int max = 9;
std::vector<uint32_t> v;
for( int i = 0; i < max; ++i ) {
is.read( (char*)&bla, sizeof(bla) );
v.push_back( bla );
}
is.read( (char*)&bla, sizeof(bla) );
char name0[32];
memset(name0,0,sizeof(name0));
assert( bla < sizeof(name0) );
is.read( name0, bla);
size_t l = strlen(name0);
assert( l == bla ); (void)l;
char * ptr = strdup( name0 );
v4.ptr = ptr;
type = param_string;
offset = 0;
}
void read_direct_string( std::istream & is ) {
uint32_t bla;
is.read( (char*)&bla, sizeof(bla) );
char name0[32];
memset(name0,0,sizeof(name0));
assert( bla < sizeof(name0) );
is.read( name0, bla);
size_t l = strlen(name0);
assert( l == bla ); (void)l;
memcpy( this->name, name0, bla );
is.read( (char*)&bla, sizeof(bla) );
assert( bla == 0x1 );
is.read( (char*)&bla, sizeof(bla) );
char value[32];
memset(value,0,sizeof(value));
assert( bla < sizeof(value) );
is.read( value, bla);
is.read( (char*)&bla, sizeof(bla) );
assert( bla == 0 );
is.read( (char*)&bla, sizeof(bla) );
assert( bla == 0 );
const uint32_t cur = (uint32_t)is.tellg();
std::cerr << "offset:" << cur << std::endl;
if( cur == 65 )
is.read( (char*)&bla, 1 );
else if( cur == 66 )
is.read( (char*)&bla, 1 );
else if( cur == 122 )
is.read( (char*)&bla, 2 );
else
assert(0);
type = param_string;
char * ptr = strdup( value );
v4.ptr = ptr;
offset = 0;
}
void read( std::istream & is )
{
is.read( name, 32 + 1);
assert( strlen( name ) <= 32 );
is.read( (char*)&boolean,1);
assert( boolean == 0 || boolean == 1 || boolean == 0x69 );
is.read( (char*)&type, sizeof( type ) );
assert( gettypenamefromtype( type ) );
is.read( (char*)&dim, sizeof( dim ) );
is.read( (char*)&v4.val, sizeof( v4.val ) );
const uint32_t cur = (uint32_t)is.tellg();
is.read( (char*)&offset, sizeof( offset ) );
assert( offset != 0 );
offset += cur;
}
void print( std::ostream & os ) const
{
os << name << ",";
os << (int)boolean << ",";
os << type << ",";
os << v4.val << ",";
os << offset << std::endl;
}
void printvalue( std::ostream & os, std::istream & is ) const
{
if( offset ) {
is.seekg( offset );
switch( type )
{
case param_float:
{
os.precision(2);
os << std::fixed;
for( uint32_t idx = 0; idx <
dim; ++idx )
{
if( idx ) os << ",";
float v;
is.read( (char*)&v, sizeof(v) );
os << v;
}
}
break;
case param_integer:
{
int32_t v;
for( uint32_t idx = 0; idx <
dim; ++idx )
{
if( idx ) os << ",";
is.read( (char*)&v, sizeof(v) );
os << v;
}
}
break;
case param_string:
{
int size = 81;
std::string v;
v.resize( size );
for( uint32_t idx = 0; idx <
dim; ++idx )
{
if( idx ) os << ";";
is.read( &v[0], size );
os << v.c_str();
}
}
break;
case param_enum:
{
int32_t v;
for( uint32_t idx = 0; idx <
dim; ++idx )
{
if( idx ) os << ",";
is.read( (char*)&v, sizeof(v) );
os << v;
}
}
break;
}
} else {
#if 1
assert ( type == param_string );
char * ptr = v4.ptr;
os << ptr;
#endif
}
}
void printxml( std::ostream & os, std::istream & is ) const
{
os << " <Attribute";
os << " Name=\"" << name << "\"";
os << " Type=\"" << gettypenamefromtype(type) << "\"";
if( dim != 1 )
{
os <<
" ArraySize=\"" <<
dim <<
"\"";
}
os << ">";
printvalue( os, is );
os << "</Attribute>\n";
}
void printcsv( std::ostream & os, std::istream & is ) const
{
os << std::setw(32) << std::left << name << ",";
os << std::setw(7) << std::right << gettypenamefromtype(type) << ",";
os << std::setw(4) <<
dim <<
",";
os << " ";
printvalue( os, is );
os << ",\n";
}
};
{
bool ret = false;
(void)de3;
if( s0 == "ExamCardBlob" )
{
fn += ".xml";
std::ofstream out( fn.c_str() );
out.close();
std::string::size_type pos1 = dup.find( "<ExamCardBlob>" );
std::string::size_type pos2 = dup.find( "</ExamCardBlob>" );
std::string b64( bv->
GetPointer() + pos1 + 14, pos2 - (pos1 + 14) );
std::string::iterator r_pos = std::remove(b64.begin(), b64.end(), '\r');
b64.erase(r_pos, b64.end());
std::string::iterator n_pos = std::remove(b64.begin(), b64.end(), '\n');
b64.erase(n_pos, b64.end());
#if 0
std::ofstream out2( "debug" );
out2.write( b64.c_str(), b64.size() );
out2.close();
#endif
std::string decoded;
decoded.resize( dlen );
std::ofstream f64( "soap.xml" );
f64.write( decoded.c_str(), decoded.size() );
f64.close();
ret = true;
}
else
{
if( s1 == "IEEE_PDF" )
{
std::istringstream is;
is.str( dup );
header h;
h.read( is );
#if 1
static int c = 0;
std::stringstream ss;
ss << fn0 << "_" << c++;
if( h.v1 == 0x01 )
ss << ".direct";
else
ss << ".indirect";
std::cout <<
"fn0=" << ss.str() <<
" Len= " << bv->
GetLength() << std::endl;
std::ofstream out( ss.str().c_str() );
out.close();
#endif
#if 1
std::cout << dup.c_str() << std::endl;
h.print( std::cout );
#endif
std::vector< param > params;
if( h.v1 == 0x01 ) {
for( uint32_t i = 0; i < 1 ; ++i ) {
param p;
if( s0 == "HARDWARE_CONFIG " )
{
p.read_direct_int( is );
}
else if( s0 == "COILSTATE " )
{
p.read_direct_string( is );
}
else
{
assert(0);
}
params.push_back( p );
}
} else {
assert( is.tellg() == std::streampos(0x20) );
is.seekg( 0x20 );
param p;
for( uint32_t i = 0; i < h.getnparams(); ++i )
{
p.read( is );
params.push_back( p );
}
}
bool b1 = isvalidpdfstring( fn.c_str() );
assert( b1 ); (void)b1;
fn += ".csv";
std::ofstream csv( fn.c_str() );
uint32_t nfloats = 0;
uint32_t nints = 0;
uint32_t nstrings = 0;
for( std::vector<param>::const_iterator it = params.begin();
it != params.end(); ++it )
{
param_type type = it->gettype();
switch( type )
{
case param_float:
nfloats += it->getdim();
break;
case param_integer:
nints += it->getdim();
break;
case param_string:
nstrings += it->getdim();
break;
default:
;
}
}
#if 0
std::cout << "Stats:" << std::endl;
std::cout << "nfloats:" << nfloats << std::endl;
std::cout << "nints:" << nints << std::endl;
std::cout << "nstrings:" << nstrings << std::endl;
#endif
assert( h.getnints() >= nints );
assert( h.getnfloats() >= nfloats );
assert( h.getnstrings() >= nstrings);
for( uint32_t i = 0; i < h.getnparams(); ++i )
{
params[i].printcsv( csv, is );
}
csv.close();
ret = true;
}
else if( s1 == "ASCII " )
{
#if 0
std::cerr << "ASCII is not handled" << std::endl;
fn += ".asc";
std::ofstream out( fn.c_str() );
out.close();
#endif
fn += ".sin";
std::ofstream sin( fn.c_str() );
assert( *beg == 0 );
const char *p = beg + 1;
size_t prev = 0;
for( ; p != end; ++p )
{
if( *p == 0 )
{
const char *s = beg + prev + 1;
if( *s )
{
sin << s << std::endl;
}
else
{
sin << std::endl;
}
prev = p - beg;
}
}
sin.close();
ret = true;
}
else if( s1 == "BINARY" )
{
std::cerr << "BINARY is not handled" << std::endl;
fn += ".bin";
std::ofstream out( fn.c_str() );
out.close();
#if 0
int array[ 128 ];
for( int i = 0; i < 14; ++i )
{
std::cout << array[i] << std::endl;
}
#endif
ret = true;
}
}
assert( ret );
return ret;
}
int main(int argc, char *argv[])
{
if( argc < 2 ) return 1;
const char *filename = argv[1];
{
std::cerr << "Failed to read: " << filename << std::endl;
return 1;
}
if ( !sqi ) return 1;
{
if( !ProcessNested( nestedds ) ) {
std::cerr << "Error processing Item #" << i << std::endl;
}
}
return 0;
}
static size_t Decode(char *dst, size_t dlen, const char *src, size_t slen)
Decode a base64-formatted buffer.
static size_t GetDecodeLength(const char *src, size_t len)
Class to represent binary value (array of bytes)
Definition gdcmByteValue.h:35
const char * GetPointer() const
Definition gdcmByteValue.h:110
VL GetLength() const override
Definition gdcmByteValue.h:77
Class to represent a Data Element either Implicit or Explicit.
Definition gdcmDataElement.h:59
const ByteValue * GetByteValue() const
Definition gdcmDataElement.h:133
bool IsEmpty() const
Check if Data Element is empty.
Definition gdcmDataElement.h:106
SmartPointer< SequenceOfItems > GetValueAsSQ() const
Class to represent a Data Set (which contains Data Elements)
Definition gdcmDataSet.h:56
const DataElement & GetDataElement(const Tag &t) const
Definition gdcmDataSet.h:188
bool FindDataElement(const PrivateTag &t) const
Look up if private tag 't' is present in the dataset:
Element class.
Definition gdcmElement.h:70
const VRToType< TVR >::Type & GetValue(unsigned int idx=0) const
Definition gdcmElement.h:94
void SetFromDataElement(DataElement const &de)
Definition gdcmElement.h:110
const DataSet & GetDataSet() const
Get Data Set.
Definition gdcmFile.h:57
Class to represent an Item.
Definition gdcmItem.h:46
const DataSet & GetNestedDataSet() const
Definition gdcmItem.h:80
Class to represent a Private DICOM Data Element (Attribute) Tag (Group, Element, Owner)
Definition gdcmPrivateTag.h:39
Reader ala DOM (Document Object Model)
Definition gdcmReader.h:54
const File & GetFile() const
Set/Get File.
Definition gdcmReader.h:72
virtual bool Read()
Main function to read a file.
void SetFileName(const char *filename_native)
Class to represent a Sequence Of Items.
Definition gdcmSequenceOfItems.h:40
SizeType GetNumberOfItems() const
Definition gdcmSequenceOfItems.h:86
const Item & GetItem(SizeType position) const
ItemVector::size_type SizeType
Definition gdcmSequenceOfItems.h:44
std::string Trim() const
Definition gdcmString.h:96
@ dim
Definition gdcmTerminal.h:52