#include <sstream>
#include <fstream>
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "gdcmFile.h"
#include "gdcmDataSet.h"
#include "gdcmFileMetaInformation.h"
#include "gdcmSmartPointer.h"
#include "gdcmReader.h"
#include "gdcmWriter.h"
#include "gdcmSystem.h"
#include "gdcmTesting.h"
#include "gdcmAttribute.h"
#if 0#endif
class membuf : public std::streambuf
{
public:
membuf(char* mem, size_t length)
{
setg(mem, mem, mem + length);
setp(mem, mem + length);
}
std::streampos seekpos(std::streampos pos, std::ios_base::openmode) override
{
char *p = eback() + pos;
if(p>=eback() && p <=egptr())
{
setg(eback(),p,egptr());
return pos;
}
else
return -1;
}
std::streampos seekoff(std::streamoff off,
std::ios_base::seekdir dir, std::ios_base::openmode) override
{
char *p;
switch(dir)
{
case std::ios_base::beg:
p = eback() + off;
break;
case std::ios_base::cur:
p = gptr() + off;
break;
case std::ios_base::end:
p = egptr() + off;
break;
default:
p = nullptr;
break;
}
if(p>=eback() && p <= egptr())
{
setg(eback(),p,egptr());
return {p-egptr()};
}
else
return -1;
}
};
std::istream & DoTheMMapRead(std::istream &is)
{
gdcm::Reader reader;
reader.SetStream(is);
reader.Read();
return is;
}
int TestRead3(const char *subdir, const char * filename)
{
gdcm::Reader r;
r.SetFileName( filename );
if( !r.Read() )
{
return 1;
}
const char * tmpdir = gdcm::Testing::GetTempDirectory( subdir );
if( !gdcm::System::FileIsDirectory( tmpdir ) )
{
gdcm::System::MakeDirectory( tmpdir );
}
const char * outfilename = gdcm::Testing::GetTempFilename( filename, subdir );
gdcm::DataSet &ds = r.GetFile().GetDataSet();
gdcm::Attribute<0x0008,0x0018> at;
if( !ds.FindDataElement( at.GetTag() ) || ds.GetDataElement( at.GetTag() ).IsEmpty() )
{
const gdcm::UIComp dummyuid = "1.2.3.4.5.6.7.8.9.0";
at.SetValue( dummyuid );
ds.Replace( at.GetAsDataElement() );
}
gdcm::Writer w;
w.SetFile( r.GetFile() );
w.SetFileName( outfilename );
if( !w.Write() )
{
return 1;
}
const char *path = outfilename;
bool readonly = true;
int flags = (readonly ? O_RDONLY : O_RDWR);
int handle = ::open(path, flags, S_IRWXU);
struct stat info;
const bool success = ::fstat(handle, &info) != -1;
if( !success ) return 1;
off_t size = info.st_size;
off_t offset = 0;
char* hint = nullptr;
void* data = ::mmap( hint, size,
readonly ? PROT_READ : (PROT_READ | PROT_WRITE),
readonly ? MAP_PRIVATE : MAP_SHARED,
handle, offset );
if (data == MAP_FAILED) {
return 1;
}
char *chardata = reinterpret_cast<char*>(data);
membuf mb( chardata, size );
std::istream is(&mb) ;
DoTheMMapRead(is);
gdcm_assert( handle );
bool error = false;
error = ::munmap(data, size) != 0 || error;
error = ::close(handle) != 0 || error;
handle = 0;
if ( error ) return 1;
return 0;
}
int TestReader3(int argc, char *argv[])
{
if( argc == 2 )
{
const char *filename = argv[1];
return TestRead3(argv[0], filename);
}
gdcm::Trace::DebugOff();
gdcm::Trace::WarningOff();
int r = 0, i = 0;
const char *filename;
const char * const *filenames = gdcm::Testing::GetFileNames();
while( (filename = filenames[i]) )
{
if( strstr(filename, "IllegalGroup2ImplicitTS.dcm" ) == nullptr )
r += TestRead3( argv[0], filename );
++i;
}
return r;
}