+2004-11-05 Mathieu Malaterre <Mathieu.Malaterre@creatis.insa-lyon.fr>
+ * Improve string manipulation. I now inforce the notion of 'DicomString'
+ A DicomString can contain as many \0 as they want
+ and it is *always* of even length.
+ We only support odd length for very rare case.
+ And in the near future this should be removed.
+
2004-11-03 Mathieu Malaterre <Mathieu.Malaterre@creatis.insa-lyon.fr>
* /binary_write/ gdcm source. Now even on big endian we are writting
little endian. This should -heopfully- fix some tests
imageElem 0028 0030 "1.0\1.0 " // Pixel Spacing
imageElem 0050 0004 "0" // Calibration Image
imageElem fffe e00d "" // Item delimitation : length to be set to ZERO later
+
TestHash.cxx
TestTS.cxx
TestVR.cxx
+ TestDicomString.cxx
)
# add tests that require data
std::string testedValue = tested->GetEntryByNumber(group, element);
if ( testedValue != j->second )
{
- std::cout << Indent << "Uncorrect value for key " << key << std::endl
- << Indent << " read value [" << testedValue << "]" << std::endl
- << Indent << " reference value [" << j->second << "]"
- << std::endl;
+ // Oops make sure this is only the \0 that differ
+ if( testedValue[j->second.size()] != '\0' ||
+ strncmp(testedValue.c_str(),
+ j->second.c_str(), j->second.size()) != 0)
+ {
+ std::cout << Indent << "Uncorrect value for key "
+ << key << std::endl
+ << Indent << " read value ["
+ << testedValue << "]" << std::endl
+ << Indent << " reference value ["
+ << j->second << "]" << std::endl;
return false;
+ }
}
}
delete tested;
--- /dev/null
+#include "gdcmUtil.h"
+
+int TestDicomString(int , char* [])
+{
+ int i;
+ const char *s = "\0\0";
+ std::string a(s,s+2); // will copy 2 '\0'
+ assert( a.size() == 2 );
+ for(i=0;i<2;i++)
+ {
+ assert( a.c_str()[i] == '\0' );
+ assert( a.data()[i] == '\0' );
+ }
+ assert( a.c_str()[3] == '\0' );
+
+/*
+std::string zeros(x, 0);
+char s1[] = "\0";
+char s2[] = "\0\0";
+char s3[] = "\0\0\0";
+char s4[] = "\0abc";*/
+
+ return 0;
+}
Program: gdcm
Module: $RCSfile: gdcmDocument.cxx,v $
Language: C++
- Date: $Date: 2004/11/04 18:14:34 $
- Version: $Revision: 1.116 $
+ Date: $Date: 2004/11/05 20:23:14 $
+ Version: $Revision: 1.117 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
if (filetype == ImplicitVR)
{
- std::string ts = TransferSyntaxStrings[ImplicitVRLittleEndian];
+ std::string ts =
+ Util::DicomString( TransferSyntaxStrings[ImplicitVRLittleEndian] );
ReplaceOrCreateByNumber(ts, 0x0002, 0x0010);
/// \todo Refer to standards on page 21, chapter 6.2
if (filetype == ExplicitVR)
{
- std::string ts = TransferSyntaxStrings[ExplicitVRLittleEndian];
+ std::string ts =
+ Util::DicomString( TransferSyntaxStrings[ExplicitVRLittleEndian] );
ReplaceOrCreateByNumber(ts, 0x0002, 0x0010);
/// \todo Refer to standards on page 21, chapter 6.2
return false;
}
// Non even content must be padded with a space (020H)...
- std::string finalContent = content;
- if( finalContent.length() % 2 )
- {
- finalContent += '\0'; // ... therefore we padd with (000H) .!?!
- }
+ std::string finalContent = Util::DicomString( content.c_str() );
+ assert( !(finalContent.size() % 2) );
valEntry->SetValue(finalContent);
-
+
// Integers have a special treatement for their length:
l = finalContent.length();
}
// to be sure we are at the end of the value ...
- Fp->seekg((long)entry->GetOffset()+(long)entry->GetLength(),std::ios_base::beg);
+ Fp->seekg((long)entry->GetOffset()+(long)entry->GetLength(),
+ std::ios_base::beg);
return;
}
return;
}
- // We need an additional byte for storing \0 that is not on disk
+ // FIXME: We need an additional byte for storing \0 that is not on disk
char *str = new char[length+1];
Fp->read(str, (size_t)length);
- str[length] = '\0';
- std::string newValue = str;
+ str[length] = '\0'; //this is only useful when length is odd
+ // Special DicomString call to properly handle \0 and even length
+ std::string newValue;
+ if( length % 2 )
+ {
+ newValue = Util::DicomString(str, length+1);
+ //dbg.Verbose(0, "Warning: bad length: ", length );
+ dbg.Verbose(0, "For string :", newValue.c_str());
+ // Since we change the length of string update it length
+ entry->SetReadLength(length+1);
+ }
+ else
+ {
+ newValue = Util::DicomString(str, length);
+ }
delete[] str;
if ( ValEntry* valEntry = dynamic_cast<ValEntry* >(entry) )
- {
+ {
if ( Fp->fail() || Fp->eof())//Fp->gcount() == 1
{
dbg.Verbose(1, "Document::LoadDocEntry",
{
uint16_t element = entry->GetElement();
uint16_t group = entry->GetGroup();
- std::string vr = entry->GetVR();
+ const std::string & vr = entry->GetVR();
uint32_t length = entry->GetLength();
// When we have some semantics on the element we just read, and if we
Program: gdcm
Module: $RCSfile: gdcmHeader.cxx,v $
Language: C++
- Date: $Date: 2004/11/04 15:59:37 $
- Version: $Revision: 1.197 $
+ Date: $Date: 2004/11/05 20:23:14 $
+ Version: $Revision: 1.198 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
if (i_lgPix != -2)
{
// no (GrPixel, NumPixel) element
- std::string s_lgPix;
- s_lgPix = Util::Format("%d", i_lgPix+12);
+ std::string s_lgPix = Util::Format("%d", i_lgPix+12);
+ s_lgPix = Util::DicomString( s_lgPix.c_str() );
ReplaceOrCreateByNumber(s_lgPix,GrPixel, 0x0000);
}
ImageDataSize += 8;
car = Util::Format("%d", ImageDataSize);
+ car = Util::DicomString( car.c_str() );
SetEntryByNumber(car, GrPixel, NumPixel);
}
Program: gdcm
Module: $RCSfile: gdcmUtil.cxx,v $
Language: C++
- Date: $Date: 2004/11/03 20:52:13 $
- Version: $Revision: 1.59 $
+ Date: $Date: 2004/11/05 20:23:14 $
+ Version: $Revision: 1.60 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
}
/**
- * \ingroup Globals
+ * \ingroup Util
* \brief Get the (last) name of a full path file name
* @param fullName file/directory name to extract end name from
*/
}
}
+/**
+ * \ingroup Util
+ * \brief Create a /DICOM/ string:
+ * It should a of even lenght (no odd length ever)
+ * It can contains as many \0 as you want.
+ * This function is similar to DicomString(const char*),
+ * except it doesn't take a lenght.
+ * It only pad with a null character if length is odd
+ */
+std::string Util::DicomString(const char* s)
+{
+ size_t l = strlen(s);
+ if( l%2 )
+ {
+ l++;
+ }
+ std::string r(s, s+l);
+ assert( !(r.size() % 2) );
+ return r;
+}
+
+/**
+ * \ingroup Util
+ * \brief Create a /DICOM/ string:
+ * It should a of even length (no odd length ever)
+ * It can contains as many \0 as you want.
+ */
+std::string Util::DicomString(const char* s, size_t l)
+{
+ std::string r(s, s+l);
+ assert( !(r.size() % 2) );
+ return r;
+}
template <class T>
std::ostream& binary_write(std::ostream& os, const T& val)
Program: gdcm
Module: $RCSfile: gdcmUtil.h,v $
Language: C++
- Date: $Date: 2004/11/03 20:52:13 $
- Version: $Revision: 1.39 $
+ Date: $Date: 2004/11/05 20:23:14 $
+ Version: $Revision: 1.40 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
static std::string GetPath(std::string const &fullName);
static std::string GetName(std::string const &fullName);
+ static std::string DicomString(const char* s, size_t l);
+ static std::string DicomString(const char* s);
};
+
template <class T>
std::ostream& binary_write(std::ostream& os, const T& val);
std::ostream& binary_write(std::ostream& os, const uint16_t& val);
Program: gdcm
Module: $RCSfile: gdcmValEntry.cxx,v $
Language: C++
- Date: $Date: 2004/11/03 20:52:13 $
- Version: $Revision: 1.32 $
+ Date: $Date: 2004/11/05 20:23:14 $
+ Version: $Revision: 1.33 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
tokens.clear();
return;
}
-
- fp->write (GetValue().c_str(), (size_t)lgr ); // Elem value
-// assert( lgr == GetValue().size() ); // FIXME ?????
-// dbg.Assert(2, lgr == strlen(GetValue().c_str()), "Should be equal" );
+
+ //Due to seriously broken Theralys images I cannot put that here.
+ //assert( lgr == GetValue().size() );
+ binary_write(*fp, GetValue());
}
//-----------------------------------------------------------------------------
Program: gdcm
Module: $RCSfile: gdcmValEntry.h,v $
Language: C++
- Date: $Date: 2004/10/28 03:10:58 $
- Version: $Revision: 1.29 $
+ Date: $Date: 2004/11/05 20:23:14 $
+ Version: $Revision: 1.30 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
std::string const & GetValue() const { return Value; };
/// Sets the value (string) of the current Dicom Document Entry
- void SetValue(std::string const & val) { Value = val; };
+ void SetValue(std::string const & val) { Value = val; };
virtual void Print(std::ostream &os = std::cout);
virtual void Write(std::ofstream *fp, FileType filetype);