+/**
+ * \brief This predicate, based on hopefully reasonable heuristics,
+ * decides whether or not the current header was properly parsed
+ * and contains the mandatory information for being considered as
+ * a well formed and usable DicomDir.
+ * @return true when gdcmDocument is the one of a reasonable DicomDir,
+ * false otherwise.
+ */
+bool gdcmDicomDir::IsReadable()
+{
+ if( !gdcmDocument::IsReadable() )
+ {
+ return false;
+ }
+ if( !metaElems )
+ {
+ return false;
+ }
+ if( patients.size() <= 0 )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Sets all fields to NULL
+ */
+
+void gdcmDicomDir::Initialize()
+{
+ startMethod = NULL;
+ progressMethod = NULL;
+ endMethod = NULL;
+ startMethodArgDelete = NULL;
+ progressMethodArgDelete = NULL;
+ endMethodArgDelete = NULL;
+ startArg = NULL;
+ progressArg = NULL;
+ endArg = NULL;
+
+ progress = 0.0;
+ abort = false;
+
+ metaElems = 0;
+}
+
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief fills the whole structure, starting from a root Directory
+ */
+void gdcmDicomDir::ParseDirectory()
+{
+ CreateDicomDirChainedList( GetFileName() );
+ CreateDicomDir();
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief Set the start method to call when the parsing of the directory starts
+ * @param method Method to call
+ * @param arg Argument to pass to the method
+ * @param argDelete Argument
+ * \warning In python : the arg parameter isn't considered
+ */
+void gdcmDicomDir::SetStartMethod(gdcmMethod* method, void* arg,
+ gdcmMethod* argDelete )
+{
+ if( startArg && startMethodArgDelete )
+ {
+ startMethodArgDelete( startArg );
+ }
+
+ startMethod = method;
+ startArg = arg;
+ startMethodArgDelete = argDelete;
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief Set the method to delete the argument
+ * The argument is destroyed when the method is changed or when the
+ * class is destroyed
+ * @param method Method to call to delete the argument
+ */
+void gdcmDicomDir::SetStartMethodArgDelete(gdcmMethod* method)
+{
+ startMethodArgDelete = method;
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief Set the progress method to call when the parsing of the directory progress
+ * @param method Method to call
+ * @param arg Argument to pass to the method
+ * @param argDelete Argument
+ * \warning In python : the arg parameter isn't considered
+ */
+void gdcmDicomDir::SetProgressMethod(gdcmMethod* method, void* arg,
+ gdcmMethod* argDelete )
+{
+ if( progressArg && progressMethodArgDelete )
+ {
+ progressMethodArgDelete( progressArg );
+ }
+
+ progressMethod = method;
+ progressArg = arg;
+ progressMethodArgDelete = argDelete;
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief Set the method to delete the argument
+ * The argument is destroyed when the method is changed or when the
+ * class is destroyed
+ * @param method Method to call to delete the argument
+ */
+void gdcmDicomDir::SetProgressMethodArgDelete(gdcmMethod* method)
+{
+ progressMethodArgDelete = method;
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief Set the end method to call when the parsing of the directory ends
+ * @param method Method to call
+ * @param arg Argument to pass to the method
+ * @param argDelete Argument
+ * \warning In python : the arg parameter isn't considered
+ */
+void gdcmDicomDir::SetEndMethod(gdcmMethod* method, void* arg,
+ gdcmMethod* argDelete )
+{
+ if( endArg && endMethodArgDelete )
+ {
+ endMethodArgDelete( endArg );
+ }
+
+ endMethod = method;
+ endArg = arg;
+ endMethodArgDelete = argDelete;
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief Set the method to delete the argument
+ * The argument is destroyed when the method is changed or when the class
+ * is destroyed
+ * @param method Method to call to delete the argument
+ */
+void gdcmDicomDir::SetEndMethodArgDelete(gdcmMethod* method)
+{
+ endMethodArgDelete = method;
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief writes on disc a DICOMDIR
+ * \ warning does NOT add the missing elements in the header :
+ * it's up to the user doing it !
+ * \todo : to be re-written using the DICOMDIR tree-like structure
+ * *not* the chained list
+ * (does NOT exist if the DICOMDIR is user-forged !)
+ * @param fileName file to be written to
+ * @return false only when fail to open
+ */
+
+bool gdcmDicomDir::WriteDicomDir(std::string const& fileName)
+{
+ uint16_t sq[4] = { 0x0004, 0x1220, 0xffff, 0xffff };
+ uint16_t sqt[4]= { 0xfffe, 0xe0dd, 0xffff, 0xffff };
+
+ FILE* fp = fopen(fileName.c_str(), "wb");
+ if( !fp )
+ {
+ printf("Failed to open(write) File [%s] \n", fileName.c_str());
+ return false;
+ }
+
+ uint8_t* filePreamble = new uint8_t[128];
+ memset(filePreamble, 0, 128);
+ fwrite(filePreamble,128,1,fp);
+ fwrite("DICM",4,1,fp);
+ delete[] filePreamble;
+
+ gdcmDicomDirMeta *ptrMeta = GetDicomDirMeta();
+ ptrMeta->Write(fp, gdcmExplicitVR);
+
+ // force writing 0004|1220 [SQ ], that CANNOT exist within gdcmDicomDirMeta
+ fwrite(&sq[0],8,1,fp); // 0004 1220 ffff ffff
+
+ for(ListDicomDirPatient::iterator cc = patients.begin();cc!=patients.end();++cc)
+ {
+ (*cc)->Write( fp, gdcmExplicitVR );
+ }
+
+ // force writing Sequence Delimitation Item
+ fwrite(&sqt[0],8,1,fp); // fffe e0dd ffff ffff
+
+ fclose( fp );
+ return true;
+}