#include <iomanip>
static bool compfn(const char *s1, const char *s2)
{
return strcmp(s1,s2) < 0 ? true : false;
}
static const char *PDFStrings[] = {
"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_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,
param_string,
param_3,
param_enum,
} param_type;
static const char *gettypenamefromtype( int i)
{
const char *ret = NULL;
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));
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];
int8_t boolean;
int32_t type;
uint32_t v4;
std::streamoff offset;
param_type gettype() const { return (param_type)type; }
uint32_t getdim()
const {
return dim; }
void read( std::istream & is )
{
is.read( name, 32 + 1);
assert( strlen( name ) <= 32 );
is.read( (char*)&boolean,1);
assert( boolean == 0 || boolean == 1 );
is.read( (char*)&type, sizeof( type ) );
assert( gettypenamefromtype( type ) );
is.read( (char*)&dim, sizeof( dim ) );
is.read( (char*)&v4, sizeof( v4 ) );
const std::streamoff cur = is.tellg();
is.read( (char*)&offset, sizeof( offset ) );
offset += cur;
}
void print( std::ostream & os ) const
{
os << name << ",";
os << (int)boolean << ",";
os << type << ",";
os << dim << ",";
os << v4 << ",";
os << offset << std::endl;
}
void printvalue( std::ostream & os, std::istream & is ) const
{
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:
{
for( uint32_t idx = 0; idx <
dim; ++idx )
{
if( idx ) os << ",";
int32_t v;
is.read( (char*)&v, sizeof(v) );
os << v;
}
}
break;
case param_string:
{
std::string v;
v.resize( dim );
is.read( &v[0], dim );
os << v;
}
break;
case param_enum:
{
for( uint32_t idx = 0; idx <
dim; ++idx )
{
if( idx ) os << ",";
int32_t v;
is.read( (char*)&v, sizeof(v) );
os << v;
}
}
break;
}
}
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;
if( s0 == "ExamCardBlob" )
{
std::string fn = gdcm::LOComp::Trim( s0.c_str() );
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" )
{
#if 0
std::string fn = gdcm::LOComp::Trim( s.c_str() );
std::ofstream out( fn.c_str() );
out.close();
#endif
std::istringstream is;
is.str( dup );
header h;
h.read( is );
#if 0
std::cout << s0.c_str() << std::endl;
h.print( std::cout );
#endif
assert( is.tellg() == std::streampos(0x20) );
is.seekg( 0x20 );
std::vector< param > params;
param p;
for( uint32_t i = 0; i < h.getnparams(); ++i )
{
p.read( is );
params.push_back( p );
}
std::string fn = gdcm::LOComp::Trim( s0.c_str() );
assert( isvalidpdfstring( fn.c_str() ) );
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;
std::string fn = gdcm::LOComp::Trim( s0.c_str() );
fn += ".asc";
std::ofstream out( fn.c_str() );
out.close();
#endif
std::string fn = gdcm::LOComp::Trim( s0.c_str() );
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;
std::string fn = gdcm::LOComp::Trim( s0.c_str() );
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 ) ) return 1;
}
return 0;
}