Logo Search packages:      
Sourcecode: dcmtk version File versions

wlfsim.cc

/*
*
*  Copyright (C) 1996-2002, OFFIS
*
*  This software and supporting documentation were developed by
*
*    Kuratorium OFFIS e.V.
*    Healthcare Information and Communication Systems
*    Escherweg 2
*    D-26121 Oldenburg, Germany
*
*  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
*  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
*  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
*  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
*  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
*
*  Module:  dcmwlm
*
*  Author:  Thomas Wilkens
*
*  Purpose: Class for managing file system interaction.
*
*  Last Update:      $Author: wilkens $
*  Update Date:      $Date: 2004/01/07 08:32:34 $
*  Source File:      $Source: /share/dicom/cvs-depot/dcmtk/dcmwlm/libsrc/wlfsim.cc,v $
*  CVS/RCS Revision: $Revision: 1.12 $
*  Status:           $State: Exp $
*
*  CVS/RCS Log at end of file
*
*/

// ----------------------------------------------------------------------------

#include "osconfig.h"

#define INCLUDE_CLIMITS
#include "ofstdinc.h"

BEGIN_EXTERN_C
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>  // for struct DIR, opendir()
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>    // for struct DIR, opendir()
#endif
END_EXTERN_C

#include "diutil.h"
#include "ofconsol.h"
#include "ofstd.h"
#include "ofoset.h"
#include "ofsetit.h"
#include "ofdate.h"
#include "oftime.h"
#include "oftypes.h"
#include "dicom.h"
#include "dcdatset.h"
#include "dcitem.h"
#include "dcvrda.h"
#include "dcvrtm.h"
#include "wltypdef.h"
#include "dctk.h"
#include <stdio.h>
#include <stdlib.h>

#include "wlfsim.h"

// ----------------------------------------------------------------------------

00075 WlmFileSystemInteractionManager::WlmFileSystemInteractionManager()
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Constructor.
// Parameters   : none.
// Return Value : none.
  : verboseMode( OFFalse ), debugMode( OFFalse ), logStream( NULL ), dfPath( NULL ), calledApplicationEntityTitle( NULL ),
    matchingRecords( NULL ), numOfMatchingRecords( 0 )
{
}

// ----------------------------------------------------------------------------

00088 WlmFileSystemInteractionManager::~WlmFileSystemInteractionManager()
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Destructor.
// Parameters   : none.
// Return Value : none.
{
  if( dfPath != NULL ) delete dfPath;
}

// ----------------------------------------------------------------------------

00100 void WlmFileSystemInteractionManager::SetLogStream( OFConsole *value )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Set value in member variable.
// Parameters   : value - [in] The value to set.
// Return Value : none.
{
  logStream = value;
}

// ----------------------------------------------------------------------------

00112 void WlmFileSystemInteractionManager::SetVerbose( OFBool value )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Set value in member variable.
// Parameters   : value - [in] The value to set.
// Return Value : none.
{
  verboseMode = value;
}

// ----------------------------------------------------------------------------

00124 void WlmFileSystemInteractionManager::SetDebug( OFBool value )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Set value in member variable.
// Parameters   : value - [in] The value to set.
// Return Value : none.
{
  debugMode = value;
}

// ----------------------------------------------------------------------------

00136 OFCondition WlmFileSystemInteractionManager::ConnectToFileSystem( char *dfPathv )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Connects to the worklist file system database.
// Parameters   : dfPathv - [in] Path to worklist file system database.
// Return Value : Indicates if the connection could be established or not.
{
  // check parameter
  if( dfPathv == NULL )
  {
    DumpMessage("Invalid parameters, cannot connect to worklist file system database...");
    return( WLM_EC_CannotConnectToDataSource );
  }

  // copy value
  dfPath = new char[ strlen( dfPathv ) + 1 ];
  strcpy( dfPath, dfPathv );

  // check if the specified path is existent and accessible for reading
  if( !OFStandard::dirExists( OFString( dfPath ) ) || !OFStandard::isReadable( OFString( dfPath ) ) )
    return( WLM_EC_CannotConnectToDataSource );
  else
    return( EC_Normal );
}

// ----------------------------------------------------------------------------

00163 OFCondition WlmFileSystemInteractionManager::DisconnectFromFileSystem()
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Disconnects from the worklist file system database.
// Parameters   : none.
// Return Value : Indicates if the connection was disconnected successfully.
{
  return( EC_Normal );
}

// ----------------------------------------------------------------------------

00175 void WlmFileSystemInteractionManager::DumpMessage( const char *message )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : This function dumps the given information on a stream.
//                Used for dumping information in normal, debug and verbose mode.
// Parameters   : message - [in] The message to dump.
// Return Value : none.
{
  if( logStream != NULL && message != NULL )
  {
    logStream->lockCout();
    logStream->getCout() << message << endl;
    logStream->unlockCout();
  }
}

// ----------------------------------------------------------------------------

00193 OFBool WlmFileSystemInteractionManager::IsCalledApplicationEntityTitleSupported( char *calledApplicationEntityTitlev )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : Checks if the given called application entity title is supported. If this is the case,
//                OFTrue will be returned, else OFFalse.
// Parameters   : calledApplicationEntityTitlev - [in] The application entity title which shall be checked
//                                                for support. Valid pointer expected.
// Return Value : OFTrue  - The called application entity title is supported.
//                OFFalse - The called application entity title is not supported or it is not given.
{
  // copy value
  calledApplicationEntityTitle = new char[ strlen( calledApplicationEntityTitlev ) + 1 ];
  strcpy( calledApplicationEntityTitle, calledApplicationEntityTitlev );

  // Determine complete path to the files that make up the data source.
  OFString fullPath( dfPath );
  if( fullPath.length() > 0 && fullPath[fullPath.length()-1] != PATH_SEPARATOR )
    fullPath += PATH_SEPARATOR;
  fullPath += calledApplicationEntityTitle;

  // in case the path is not existent, we need to return OFFalse
  if( !( OFStandard::dirExists( OFString( fullPath ) ) ) )
    return( OFFalse );

  // if we get to here, the path is existent and we need to return OFTrue
  return( OFTrue );
}

// ----------------------------------------------------------------------------

00223 unsigned long WlmFileSystemInteractionManager::DetermineMatchingRecords( DcmDataset *searchMask )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : This function determines the records from the worklist files which match
//                the given search mask and returns the number of matching records. Also,
//                this function will store the matching records in memory in the array
//                member variable matchingRecords.
// Parameters   : searchMask - [in] The search mask.
// Return Value : Number of matching records.
{
  OFOrderedSet<OFString> worklistFiles;
  char msg[500];

  // initialize member variables
  matchingRecords = NULL;
  numOfMatchingRecords = 0;

  // determine all worklist files
  DetermineWorklistFiles( worklistFiles );

  // go through all worklist files
  for( unsigned int i=0 ; i<worklistFiles.NumberOfElements() ; i++ )
  {
    // read information from worklist file
    DcmFileFormat fileform;
    if (fileform.loadFile(worklistFiles[i].c_str()).bad())
    {
      if( verboseMode )
      {
        sprintf( msg, "  - Could not read worklist file %s properly. File will be ignored.", worklistFiles[i].c_str() );
        DumpMessage( msg );
      }
    }
    else
    {
      // determine the data set which is contained in the worklist file
      DcmDataset *dataset = fileform.getDataset();
      if( dataset == NULL )
      {
        if( verboseMode )
        {
          sprintf( msg, "  - Worklist file %s is empty. File will be ignored.", worklistFiles[i].c_str() );
          DumpMessage( msg );
        }
      }
      else
      {
        // check if the current dataset matches the matching key attribute values
        if( !DatasetMatchesSearchMask( dataset, searchMask ) )
        {
          if( verboseMode )
          {
            sprintf( msg, "Information from worklist file %s does not match query.", worklistFiles[i].c_str() );
            DumpMessage( msg );
          }
        }
        else
        {
          if( verboseMode )
          {
            sprintf( msg, "Information from worklist file %s matches query.", worklistFiles[i].c_str() );
            DumpMessage( msg );
          }

          // since the dataset matches the matching key attribute values
          // we need to insert it into the matchingRecords array
          if( numOfMatchingRecords == 0 )
          {
            matchingRecords = new DcmDataset*[1];
            matchingRecords[0] = new DcmDataset( *dataset );
          }
          else
          {
            DcmDataset **tmp = new DcmDataset*[numOfMatchingRecords + 1];
            for( unsigned long j=0 ; j<numOfMatchingRecords ; j++ )
              tmp[j] = matchingRecords[j];
            tmp[numOfMatchingRecords] = new DcmDataset( *dataset );
            delete matchingRecords;
            matchingRecords = tmp;
          }

          numOfMatchingRecords++;
        }
      }
    }
  }

  // return result
  return( numOfMatchingRecords );
}

// ----------------------------------------------------------------------------

00316 unsigned long WlmFileSystemInteractionManager::GetNumberOfSequenceItemsForMatchingRecord( DcmTagKey sequenceTag, WlmSuperiorSequenceInfoType *superiorSequenceArray, unsigned long numOfSuperiorSequences, unsigned long idx )
// Date         : January 6, 2004
// Author       : Thomas Wilkens
// Task         : For the matching record that is identified through idx, this function returns the number
//                of items that are contained in the sequence element that is referred to by sequenceTag.
//                In case this sequence element is itself contained in a certain item of another superior
//                sequence, superiorSequenceArray contains information about where to find the correct
//                sequence element.
// Parameters   : sequenceTag            - [in] The tag of the sequence element for which the number of items
//                                              shall be determined.
//                superiorSequenceArray  - [in] Array which contains information about superior sequence elements
//                                              the given sequence element is contained in.
//                numOfSuperiorSequences - [in] The number of elements in the above array.
//                idx                    - [in] Identifies the record from which the number of sequence items
//                                              shall be determined.
// Return Value : The number of items that are contained in the sequence element that is referred to by
//                sequenceTag and that can be found in sequence items which are specified in superiorSequenceArray.
{
  OFCondition cond;
  DcmSequenceOfItems *sequenceElement = NULL, *tmp = NULL;
  unsigned long i;

  // initialize result variable
  unsigned long numOfItems = 0;

  // if the sequence in question is not contained in another sequence
  if( numOfSuperiorSequences == 0 )
  {
    // simply find and get this sequence in the matching dataset (on the main level)
    cond = matchingRecords[idx]->findAndGetSequence( sequenceTag, sequenceElement, OFFalse );
  }
  else
  {
    // if it is contained in (an)other sequence(s), find it
    cond = matchingRecords[idx]->findAndGetSequence( superiorSequenceArray[0].sequenceTag, sequenceElement, OFFalse );
    for( i=1 ; i<numOfSuperiorSequences && cond.good() ; i++ )
    {
      cond = sequenceElement->getItem( superiorSequenceArray[i-1].currentItem )->findAndGetSequence( superiorSequenceArray[i].sequenceTag, tmp, OFFalse );
      if( cond.good() )
        sequenceElement = tmp;
    }

    if( cond.good() )
    {
      cond = sequenceElement->getItem( superiorSequenceArray[ numOfSuperiorSequences - 1 ].currentItem )->findAndGetSequence( sequenceTag, tmp, OFFalse );
      if( cond.good() )
        sequenceElement = tmp;
    }
  }

  // determine number of items for the sequence in question
  if( cond.good() )
    numOfItems = sequenceElement->card();

  // return result
  return( numOfItems );
}

// ----------------------------------------------------------------------------

00376 void WlmFileSystemInteractionManager::GetAttributeValueForMatchingRecord( DcmTagKey tag, WlmSuperiorSequenceInfoType *superiorSequenceArray, unsigned long numOfSuperiorSequences, unsigned long idx, char *&value )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : This function determines an attribute value of a matching record
//                and returns this value in a newly created string to the caller.
// Parameters   : tag                    - [in] Attribute tag. Specifies which attribute's value shall be returned.
//                superiorSequenceArray  - [in] Array which contains information about superior sequence elements
//                                              the given element is contained in.
//                numOfSuperiorSequences - [in] The number of elements in the above array.
//                idx                    - [in] Identifies the record from which the attribute value shall be retrieved.
//                value                  - [out] Pointer to a newly created string that contains the requested value.
//                                               If value was not found an emtpy string will be returned.
// Return Value : none.
{
  OFCondition cond;
  DcmSequenceOfItems *sequenceElement = NULL, *tmp = NULL;
  unsigned long i;
  const char *val = NULL;
  Uint16 v;

  // if the element in question is not contained in another sequence
  if( numOfSuperiorSequences == 0 )
  {
    // simply find and get this element in the matching dataset (on the main level);
    // here, we have to distinguish two cases: attribute PregnancyStatus has to be re-
    // trieved as a Uint16 value (also note for this case, that this attribute can only
    // occur on the main level, it will never be contained in a sequence), all other
    // attributes have to be retrieved as strings
    if( tag == DCM_PregnancyStatus )
    {
      cond = matchingRecords[idx]->findAndGetUint16( tag, v, 0, OFFalse );
      if( cond.good() )
      {
        value = new char[20];
        sprintf( value, "%u", v );
      }
      else
      {
        value = new char[ 2 ];
        strcpy( value, "4" );           // a value of "4" in attribute PregnancyStatus means "unknown" in DICOM
      }
    }
    else
    {
      cond = matchingRecords[idx]->findAndGetString( tag, val, OFFalse );
      if( cond.good() && val != NULL )
      {
        value = new char[ strlen( val ) + 1 ];
        strcpy( value, val );
      }
      else
      {
        value = new char[ 1 ];
        strcpy( value, "" );
      }
    }
  }
  else
  {
    // if it is contained in (an)other sequence(s), go through all corresponding sequence items
    cond = matchingRecords[idx]->findAndGetSequence( superiorSequenceArray[0].sequenceTag, sequenceElement, OFFalse );
    for( i=1 ; i<numOfSuperiorSequences && cond.good() ; i++ )
    {
      cond = sequenceElement->getItem( superiorSequenceArray[i-1].currentItem )->findAndGetSequence( superiorSequenceArray[i].sequenceTag, tmp, OFFalse );
      if( cond.good() )
        sequenceElement = tmp;
    }

    // now sequenceElement points to the sequence element in which the attribute
    // in question can be found; retrieve a value for this attribute (note that
    // all attributes in sequences can actually be retrieved as strings)
    if( cond.good() )
    {
      cond = sequenceElement->getItem( superiorSequenceArray[ numOfSuperiorSequences - 1 ].currentItem )->findAndGetString( tag, val, OFFalse );
      if( cond.good() && val != NULL )
      {
        value = new char[ strlen( val ) + 1 ];
        strcpy( value, val );
      }
      else
      {
        value = new char[ 1 ];
        strcpy( value, "" );
      }
    }
    else
    {
      value = new char[ 1 ];
      strcpy( value, "" );
    }
  }
}

// ----------------------------------------------------------------------------

00471 void WlmFileSystemInteractionManager::ClearMatchingRecords()
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : This function frees the memory which was occupied by matchingRecords.
//                It shall be called when the matching records are no longer needed.
// Parameters   : none.
// Return Value : none.
{
  for( unsigned int i=0 ; i<numOfMatchingRecords ; i++ )
    delete matchingRecords[i];
  delete matchingRecords;
  matchingRecords = NULL;
  numOfMatchingRecords = 0;
}

// ----------------------------------------------------------------------------

00488 void WlmFileSystemInteractionManager::DetermineWorklistFiles( OFOrderedSet<OFString> &worklistFiles )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : This function determines all worklist files in the directory specified by
//                dfPath and calledApplicationEntityTitle, and returns the complete path and
//                filename information in an array of strings.
// Parameters   : worklistFiles - [out] Set of strings, each specifying path and filename
//                                      to one worklist file.
// Return Value : none.
{
  // initialize out parameters
  worklistFiles.Clear();

  // determine complete path to data source files
  // (dfPath + PATH_SEPARATOR + calledApplicationEntityTitle)
  OFString path( dfPath );
  if( path.length() > 0 && path[path.length()-1] != PATH_SEPARATOR )
    path += PATH_SEPARATOR;
  path += calledApplicationEntityTitle;

  // determine worklist files in this folder
#ifdef HAVE__FINDFIRST
  OFString searchname = path + PATH_SEPARATOR + '*';
  struct _finddata_t fileData;
  int ret = 0;

  // start a loop; in each iteration another directory entry is determined
  long hFile = _findfirst( (char*)searchname.c_str(), &fileData );
  while( hFile != -1L && ret == 0 )
  {
    // if the current entry refers to a worklist file, do something
    if( strcmp( fileData.name, "." )  !=0 && strcmp( fileData.name, ".." ) !=0 && IsWorklistFile( fileData.name ) )
    {
      // Create a string that contains path and filename of the current worklist file.
      OFString subname( path );
      subname += PATH_SEPARATOR;
      subname += fileData.name;

      // Add string to the set of strings
      worklistFiles.Insert( subname );
    }
    ret = _findnext( hFile, &fileData );
  }
  _findclose( hFile );
#else
  struct dirent *dp = NULL;

  // open directory
  DIR *dirp = opendir( path.c_str() );
  if( dirp != NULL )
  {
    // start a loop; in each iteration another directory entry is determined.
#if defined(_REENTRANT) && !defined(_WIN32) && !defined(__CYGWIN__)
    unsigned char entryBuffer[sizeof(struct dirent) + _POSIX_PATH_MAX + 1];
#ifdef HAVE_OLD_READDIR_R
    for( dp = readdir_r( dirp, (struct dirent *)entryBuffer ) ; dp != NULL ; dp = readdir_r( dirp, (struct dirent *)entryBuffer ) )
#else
    for( int readResult = readdir_r( dirp, (struct dirent *)entryBuffer, &dp ) ; readResult == 0 && dp ; readResult = readdir_r( dirp, (struct dirent *)entryBuffer, &dp ) )
#endif
#else
    for( dp = readdir( dirp ) ; dp != NULL ; dp = readdir( dirp ) )
#endif
    {
      // if the current entry refers to a worklist file
      if( IsWorklistFile( dp->d_name ) )
      {
        // create a string that contains path and filename of the current worklist file.
        OFString subname( path );
        subname += PATH_SEPARATOR;
        subname += dp->d_name;

        // add string to the set of strings
        worklistFiles.Insert( subname );
      }
    }

    // close directory
    closedir( dirp );
  }
#endif

  // in case we are running in verbose mode, dump all worklist file information
  if( verboseMode )
  {
    DumpMessage("=============================");
    DumpMessage("Worklist Database Files:");
    if( worklistFiles.NumberOfElements() == 0 )
      DumpMessage("<no files found>");
    else
    {
      OFSetIterator<OFString> iter( worklistFiles );
      while( iter.Object() )
      {
        DumpMessage( iter.Object()->c_str() );
        iter.Next();
      }
    }
    DumpMessage("=============================");
  }
}

// ----------------------------------------------------------------------------

00591 OFBool WlmFileSystemInteractionManager::IsWorklistFile( const char *fname )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the given filename refers to a worklist file,
//                i.e. has an extension of ".wl".
// Parameters   : fname - [in] The name of the file.
// Return Value : OFTrue  - The given filename refers to a worklist file.
//                OFFalse - The given filename does not refer to a worklist file.
{
  // If no filename is specified, return OFFalse
  if( fname == NULL )
    return( OFFalse );

  // look for an '.' in the filename
  char *s = (char *)strrchr( fname, '.' );

  // if there was no '.' return OFFalse
  if( s == NULL )
    return( OFFalse );

  // if the extension is ".wl" return OFTrue
  if( strcmp( s, ".wl" ) == 0 )
    return( OFTrue );

  // return OFFalse in all other cases
  return( OFFalse );
}

// ----------------------------------------------------------------------------

00621 OFBool WlmFileSystemInteractionManager::DatasetMatchesSearchMask( DcmDataset *dataset, DcmDataset *searchMask )
// Date         : July 11, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue, if the matching key attribute values in the
//                dataset match the matching key attribute values in the search mask.
// Parameters   : dataset    - [in] The dataset which shall be checked.
//                searchMask - [in] The search mask.
// Return Value : OFTrue  - The dataset matches the search mask in the matching key attribute values.
//                OFFalse - The dataset does not match the search mask in the matching key attribute values.
{
  OFBool dateTimeMatchHasBeenPerformed = OFFalse;

  // initialize result variable
  OFBool matchFound = OFTrue;

  // determine matching key attribute values in the dataset
  const char **mkaValuesDataset = NULL;
  DetermineMatchingKeyAttributeValues( dataset, mkaValuesDataset );

  // determine matching key attribute values in the search mask
  const char **mkaValuesSearchMask = NULL;
  DetermineMatchingKeyAttributeValues( searchMask, mkaValuesSearchMask );

  // go through the arrays of matching key attribute values
  for( unsigned long i=0 ; i<NUMBER_OF_SUPPORTED_MATCHING_KEY_ATTRIBUTES && matchFound ; i++ )
  {
    // check if the current matching key attribute actually had a value in the search mask
    if( mkaValuesSearchMask[i] != NULL  )
    {
      // if it did, check if the values from search mask and dataset match
      switch( i )
      {
        case 0:
          // matching key attribute is DCM_ScheduledStationAETitle (AE, 1-n)
          matchFound = ScheduledStationAETitlesMatch( mkaValuesDataset[0], mkaValuesSearchMask[0] );
          break;

        case 1:
        case 2:
          // matching key attributes are DCM_ScheduledProcedureStepStartDate (DA, 1)
          // and DCM_ScheduledProcedureStepStartTime (TM, 1)
          // only do something if a date time match has not yet been performed
          if( !dateTimeMatchHasBeenPerformed )
          {
            matchFound = ScheduledProcedureStepStartDateTimesMatch( mkaValuesDataset[1], mkaValuesDataset[2], mkaValuesSearchMask[1], mkaValuesSearchMask[2] );
            dateTimeMatchHasBeenPerformed = OFTrue;
          }
          break;

        case 3:
          // matching key attribute is DCM_Modality (CS, 1)
          matchFound = ModalitiesMatch( mkaValuesDataset[3], mkaValuesSearchMask[3] );
          break;

        case 4:
          // matching key attribute is DCM_ScheduledPerformingPhysiciansName (PN, 1)
          matchFound = ScheduledPerformingPhysiciansNamesMatch( mkaValuesDataset[4], mkaValuesSearchMask[4] );
          break;

        case 5:
          // matching key attribute is DCM_PatientsName (PN, 1)
          matchFound = PatientsNamesMatch( mkaValuesDataset[5], mkaValuesSearchMask[5] );
          break;

        case 6:
          // matching key attribute is DCM_PatientID (LO, 1)
          matchFound = PatientIdsMatch( mkaValuesDataset[6], mkaValuesSearchMask[6] );
          break;

        case 7:
          // matching key attribute is DCM_AccessionNumber (SH, 2)
          matchFound = AccessionNumbersMatch( mkaValuesDataset[7], mkaValuesSearchMask[7] );
          break;

        case 8:
          // matching key attribute is DCM_RequestedProcedureID (SH, 1)
          matchFound = RequestedProcedureIdsMatch( mkaValuesDataset[8], mkaValuesSearchMask[8] );
          break;

        case 9:
          // matching key attribute is DCM_ReferringPhysiciansName (PN, 2)
          matchFound = ReferringPhysiciansNamesMatch( mkaValuesDataset[9], mkaValuesSearchMask[9] );
          break;

        case 10:
          // matching key attribute is DCM_PatientsSex (CS, 2)
          matchFound = PatientsSexesMatch( mkaValuesDataset[10], mkaValuesSearchMask[10] );
          break;

        case 11:
          // matching key attribute is DCM_RequestingPhysician (PN, 2)
          matchFound = RequestingPhysiciansMatch( mkaValuesDataset[11], mkaValuesSearchMask[11] );
          break;

        case 12:
          // matching key attribute is DCM_AdmissionID (LO, 2)
          matchFound = AdmissionIdsMatch( mkaValuesDataset[12], mkaValuesSearchMask[12] );
          break;

        case 13:
          // matching key attribute is DCM_RequestedProcedurePriority (SH, 2)
          matchFound = RequestedProcedurePrioritiesMatch( mkaValuesDataset[13], mkaValuesSearchMask[13] );
          break;

        default:
          break;
      }
    }
  }

  // return result
  return( matchFound );
}

// ----------------------------------------------------------------------------

00737 void WlmFileSystemInteractionManager::DetermineMatchingKeyAttributeValues( DcmDataset *dataset, const char **&matchingKeyAttrValues )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function determines the values of the matching key attributes in the given dataset.
// Parameters   : dataset               - [in] Dataset from which the values shall be extracted.
//                matchingKeyAttrValues - [out] Contains in the end the values of the matching key
//                                        attributes in the search mask. Is an array of pointers.
// Return Value : none.
{
  // Initialize array of strings because all currently
  // supported matching key attributes are strings
  matchingKeyAttrValues = new const char*[ NUMBER_OF_SUPPORTED_MATCHING_KEY_ATTRIBUTES ];

  // find matching key attributes in the dataset and remember their values.
  for( unsigned long i=0 ; i<NUMBER_OF_SUPPORTED_MATCHING_KEY_ATTRIBUTES ; i++ )
  {
    // initialize array field
    matchingKeyAttrValues[i] = NULL;

    // determine which matching key attribute we want to find
    DcmTagKey tag;
    switch( i )
    {
      case 0 : tag = DCM_ScheduledStationAETitle           ; break;
      case 1 : tag = DCM_ScheduledProcedureStepStartDate   ; break;
      case 2 : tag = DCM_ScheduledProcedureStepStartTime   ; break;
      case 3 : tag = DCM_Modality                          ; break;
      case 4 : tag = DCM_ScheduledPerformingPhysiciansName ; break;
      case 5 : tag = DCM_PatientsName                      ; break;
      case 6 : tag = DCM_PatientID                         ; break;
      case 7 : tag = DCM_AccessionNumber                   ; break;
      case 8 : tag = DCM_RequestedProcedureID              ; break;
      case 9 : tag = DCM_ReferringPhysiciansName           ; break;
      case 10 : tag = DCM_PatientsSex                      ; break;
      case 11 : tag = DCM_RequestingPhysician              ; break;
      case 12 : tag = DCM_AdmissionID                      ; break;
      case 13 : tag = DCM_RequestedProcedurePriority       ; break;
      default:                                               break;
    }

    // try to find matching key attribute in the dataset
    dataset->findAndGetString( tag, matchingKeyAttrValues[i], OFTrue );
  }
}

// ----------------------------------------------------------------------------

00784 OFBool WlmFileSystemInteractionManager::ScheduledStationAETitlesMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute scheduled station AE title match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // if there is a value in the dataset, perform case sensitive single value matching
  if( datasetValue != NULL )
    return( CaseSensitiveSingleValueMatch( datasetValue, searchMaskValue ) );
  else
  {
    // if datasetValue is not existent, the search mask's value has to be empty to have
    // a match (universal matching); in all other cases, we do not have a match
    if( strcmp( searchMaskValue, "" ) == 0 )
      return( OFTrue );
    else
      return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

00809 OFBool WlmFileSystemInteractionManager::ScheduledProcedureStepStartDateTimesMatch( const char *datasetDateValue, const char *datasetTimeValue, const char *searchMaskDateValue, const char *searchMaskTimeValue )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attributes scheduled procedure step start date and scheduled procedure step
//                start time match; otherwise OFFalse will be returned.
// Parameters   : datasetDateValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                datasetTimeValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskDateValue - [in] Value for the corresponding attribute in the search mask; might be NULL.
//                searchMaskTimeValue - [in] Value for the corresponding attribute in the search mask; might be NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  OFBool isMatch = OFFalse;

  // four things are of interest before matching
  OFBool dateGiven = ( searchMaskDateValue != NULL ) ? OFTrue : OFFalse;
  OFBool timeGiven = ( searchMaskTimeValue != NULL ) ? OFTrue : OFFalse;
  OFBool dateIsDateRange = ( dateGiven && strchr( searchMaskDateValue, '-' ) != NULL ) ? OFTrue : OFFalse;
  OFBool timeIsTimeRange = ( timeGiven && strchr( searchMaskTimeValue, '-' ) != NULL ) ? OFTrue : OFFalse;

  // depending on these four things perform different kinds of matching
  if( dateIsDateRange && timeIsTimeRange )
  {
    // perform range matching taking into account date and time
    isMatch = DateTimeRangeMatch( datasetDateValue, datasetTimeValue, searchMaskDateValue, searchMaskTimeValue );
  }
  else if( dateIsDateRange && !timeIsTimeRange )
  {
    // perform range matching taking into account date only
    isMatch = DateRangeMatch( datasetDateValue, searchMaskDateValue );
  }
  else if( dateGiven && !dateIsDateRange && timeIsTimeRange )
  {
    // perform a date single value match and a time range match
    isMatch = DateSingleValueMatch( datasetDateValue, searchMaskDateValue ) && TimeRangeMatch( datasetTimeValue, searchMaskTimeValue );
  }
  else if( !dateGiven && !dateIsDateRange && timeIsTimeRange )
  {
    // perform range matching taking into account time only
    isMatch = TimeRangeMatch( datasetTimeValue, searchMaskTimeValue );
  }
  else if( dateGiven && !dateIsDateRange && timeGiven && !timeIsTimeRange )
  {
    // perform single value matching taking into account date and time
    isMatch = DateTimeSingleValueMatch( datasetDateValue, datasetTimeValue, searchMaskDateValue, searchMaskTimeValue );
  }
  else if( dateGiven && !dateIsDateRange && !timeGiven && !timeIsTimeRange )
  {
    // perform single value matching taking into account date only
    isMatch = DateSingleValueMatch( datasetDateValue, searchMaskDateValue );
  }
  else if( !dateGiven && timeGiven && !timeIsTimeRange && !dateIsDateRange )
  {
    // perform single value matching taking into account time only
    isMatch = TimeSingleValueMatch( datasetTimeValue, searchMaskTimeValue );
  }
  else // if( !dateGiven && !timeGiven && !dateIsDateRange && !timeIsTimeRange ) // this case can actually never happen, because either time or date will always be given in this function
  {
    // return OFTrue
    isMatch = OFTrue;
  }

  // return result
  return( isMatch );
}

// ----------------------------------------------------------------------------

00877 OFBool WlmFileSystemInteractionManager::ModalitiesMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute modality match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // if there is a value in the dataset, perform case sensitive single value matching
  if( datasetValue != NULL )
    return( CaseSensitiveSingleValueMatch( datasetValue, searchMaskValue ) );
  else
  {
    // if datasetValue is not existent, the search mask's value has to be empty to have
    // a match (universal matching); in all other cases, we do not have a match
    if( strcmp( searchMaskValue, "" ) == 0 )
      return( OFTrue );
    else
      return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

00902 OFBool WlmFileSystemInteractionManager::ScheduledPerformingPhysiciansNamesMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute scheduled performing physician's names match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we have to perform case sensitive single value matching or wildcard matching
    else if( CaseSensitiveSingleValueMatch( datasetValue, searchMaskValue ) || WildcardMatch( datasetValue, searchMaskValue ) )
      return( OFTrue );
    else
      return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

00937 OFBool WlmFileSystemInteractionManager::PatientsNamesMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute patient's names match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we have to perform case sensitive single value matching or wildcard matching
    else if( CaseSensitiveSingleValueMatch( datasetValue, searchMaskValue ) || WildcardMatch( datasetValue, searchMaskValue ) )
      return( OFTrue );
    else
      return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

00972 OFBool WlmFileSystemInteractionManager::PatientIdsMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute patient id match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // if there is a value in the dataset, perform case sensitive single value matching
  if( datasetValue != NULL )
    return( CaseSensitiveSingleValueMatch( datasetValue, searchMaskValue ) );
  else
  {
    // if datasetValue is not existent, the search mask's value has to be empty to have
    // a match (universal matching); in all other cases, we do not have a match
    if( strcmp( searchMaskValue, "" ) == 0 )
      return( OFTrue );
    else
      return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

00997 OFBool WlmFileSystemInteractionManager::AccessionNumbersMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : December 22, 2003
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute accession number match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we want to perform wildcard matching
    else
      return( WildcardMatch( datasetValue, searchMaskValue ) );
  }
}

// ----------------------------------------------------------------------------

01030 OFBool WlmFileSystemInteractionManager::RequestedProcedureIdsMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : December 22, 2003
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute requested procedure id match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we want to perform wildcard matching
    else
      return( WildcardMatch( datasetValue, searchMaskValue ) );
  }
}

// ----------------------------------------------------------------------------

01063 OFBool WlmFileSystemInteractionManager::ReferringPhysiciansNamesMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : December 22, 2003
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute referring physician's name match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we want to perform wildcard matching
    else
      return( WildcardMatch( datasetValue, searchMaskValue ) );
  }
}

// ----------------------------------------------------------------------------

01096 OFBool WlmFileSystemInteractionManager::PatientsSexesMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : December 22, 2003
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute patient sex match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we want to perform wildcard matching
    else
      return( WildcardMatch( datasetValue, searchMaskValue ) );
  }
}

// ----------------------------------------------------------------------------

01129 OFBool WlmFileSystemInteractionManager::RequestingPhysiciansMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : December 22, 2003
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute requesting physician match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we want to perform wildcard matching
    else
      return( WildcardMatch( datasetValue, searchMaskValue ) );
  }
}

// ----------------------------------------------------------------------------

01162 OFBool WlmFileSystemInteractionManager::AdmissionIdsMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : December 22, 2003
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute admission id match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we want to perform wildcard matching
    else
      return( WildcardMatch( datasetValue, searchMaskValue ) );
  }
}

// ----------------------------------------------------------------------------

01195 OFBool WlmFileSystemInteractionManager::RequestedProcedurePrioritiesMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : December 22, 2003
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values in
//                attribute requested procedure priorities match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // copy search mask value
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  sv = DU_stripTrailingSpaces( sv );

  // if we are dealing with universal matching, there is always a match
  if( strcmp( sv, "" ) == 0 || strcmp( sv, "*" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching...
    // ...and the dataset value is not existent, there is no match
    if( datasetValue == NULL )
      return( OFFalse );
    // ...and the dataset value is existent, we want to perform wildcard matching
    else
      return( WildcardMatch( datasetValue, searchMaskValue ) );
  }
}

// ----------------------------------------------------------------------------

01228 OFBool WlmFileSystemInteractionManager::DateTimeRangeMatch( const char *datasetDateValue, const char *datasetTimeValue, const char *searchMaskDateValue, const char *searchMaskTimeValue )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function performs a date time range match and returns OFTrue if the dataset's
//                and the search mask's values in the corresponding attributes match; otherwise OFFalse
//                will be returned
// Parameters   : datasetDateValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                datasetTimeValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskDateValue - [in] Value for the corresponding attribute in the search mask; never NULL.
//                searchMaskTimeValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  char *sdvv1 = NULL, *sdvv2 = NULL, *stvv1 = NULL, *stvv2 = NULL;
  OFDate datasetDateVal, searchMaskDateVal1, searchMaskDateVal2;
  OFTime datasetTimeVal, searchMaskTimeVal1, searchMaskTimeVal2;
  OFCondition cond;

  // if values in dataset are both given, perform date time range match
  if( datasetDateValue != NULL && datasetTimeValue != NULL )
  {
    // initialize result
    OFBool isMatch = OFFalse;

    // copy values
    char *ddv = new char[ strlen( datasetDateValue ) + 1 ];     strcpy( ddv, datasetDateValue );
    char *dtv = new char[ strlen( datasetTimeValue ) + 1 ];     strcpy( dtv, datasetTimeValue );
    char *sdv = new char[ strlen( searchMaskDateValue ) + 1 ];  strcpy( sdv, searchMaskDateValue );
    char *stv = new char[ strlen( searchMaskTimeValue ) + 1 ];  strcpy( stv, searchMaskTimeValue );

    // strip trailing spaces
    ddv = DU_stripTrailingSpaces( ddv );
    dtv = DU_stripTrailingSpaces( dtv );
    sdv = DU_stripTrailingSpaces( sdv );
    stv = DU_stripTrailingSpaces( stv );

    // get actual date/time boundary values
    ExtractValuesFromRange( sdv, sdvv1, sdvv2 );
    ExtractValuesFromRange( stv, stvv1, stvv2 );

    // generate OFDate and OFTime objects from strings
    cond = DcmDate::getOFDateFromString( OFString( ddv ), datasetDateVal );
    if( cond.good() )
    {
      cond = DcmTime::getOFTimeFromString( OFString( dtv ), datasetTimeVal );
      if( cond.good() )
      {
        cond = DcmDate::getOFDateFromString( (( sdvv1 != NULL ) ? OFString( sdvv1 ) : OFString("19000101")), searchMaskDateVal1 );
        if( cond.good() )
        {
          cond = DcmDate::getOFDateFromString( (( sdvv2 != NULL ) ? OFString( sdvv2 ) : OFString("39991231")), searchMaskDateVal2 );
          if( cond.good() )
          {
            cond = DcmTime::getOFTimeFromString( (( stvv1 != NULL ) ? OFString( stvv1 ) : OFString("000000")), searchMaskTimeVal1 );
            if( cond.good() )
            {
              cond = DcmTime::getOFTimeFromString( (( stvv2 != NULL ) ? OFString( stvv2 ) : OFString("235959")), searchMaskTimeVal2 );
              if( cond.good() )
              {
                // now that we have the date and time objects we can actually
                // compare the date and time values and determine if it's a match

                // check if the lower value in the search mask is earlier
                // than or equal to the lower value in the dataset
                if( searchMaskDateVal1 < datasetDateVal ||
                    ( searchMaskDateVal1 == datasetDateVal && searchMaskTimeVal1 <= datasetTimeVal ) )
                {
                  // now check if the upper value in the search mask is later
                  // than or equal to the upper value in the dataset
                  if( searchMaskDateVal2 > datasetDateVal ||
                      ( searchMaskDateVal2 == datasetDateVal && searchMaskTimeVal2 >= datasetTimeVal ) )
                  {
                    // if all these conditions are met, then this is considered to be a match
                    isMatch = OFTrue;
                  }
                }
              }
            }
          }
        }
      }
    }

    // free memory
    delete ddv;
    delete dtv;
    delete sdv;
    delete stv;
    if( sdvv1 != NULL ) delete sdvv1;
    if( sdvv2 != NULL ) delete sdvv2;
    if( stvv1 != NULL ) delete stvv1;
    if( stvv2 != NULL ) delete stvv2;

    // return result
    return( isMatch );
  }
  else
  {
    // so at least one of the two values (date or time) or not given in
    // the dataset; in this case, since the date and time values in the
    // search mask are both non-universal, we do not have a match
    return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

01334 OFBool WlmFileSystemInteractionManager::DateRangeMatch( const char *datasetDateValue, const char *searchMaskDateValue )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function performs a date range match and returns OFTrue if the dataset's and
//                the search mask's values in the corresponding attributes match; otherwise OFFalse
//                will be returned
// Parameters   : datasetDateValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskDateValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  char *sdvv1 = NULL, *sdvv2 = NULL;
  OFDate datasetDateVal, searchMaskDateVal1, searchMaskDateVal2;
  OFCondition cond;

  // if date value in dataset is given, perform date range match
  if( datasetDateValue != NULL )
  {
    // initialize result
    OFBool isMatch = OFFalse;

    // copy values
    char *ddv = new char[ strlen( datasetDateValue ) + 1 ];     strcpy( ddv, datasetDateValue );
    char *sdv = new char[ strlen( searchMaskDateValue ) + 1 ];  strcpy( sdv, searchMaskDateValue );

    // strip trailing spaces
    ddv = DU_stripTrailingSpaces( ddv );
    sdv = DU_stripTrailingSpaces( sdv );

    // get actual date boundary values
    ExtractValuesFromRange( sdv, sdvv1, sdvv2 );

    // generate OFDate objects from strings
    cond = DcmDate::getOFDateFromString( OFString( ddv ), datasetDateVal );
    if( cond.good() )
    {
      cond = DcmDate::getOFDateFromString( (( sdvv1 != NULL ) ? OFString( sdvv1 ) : OFString("19000101")), searchMaskDateVal1 );
      if( cond.good() )
      {
        cond = DcmDate::getOFDateFromString( (( sdvv2 != NULL ) ? OFString( sdvv2 ) : OFString("39991231")), searchMaskDateVal2 );
        if( cond.good() )
        {
          // now that we have the date objects we can actually
          // compare the date values and determine if it's a match

          // check if the lower value in the search mask is earlier
          // than or equal to the lower value in the dataset
          if( searchMaskDateVal1 <= datasetDateVal )
          {
            // now check if the upper value in the search mask is later
            // than or equal to the upper value in the dataset
            if( searchMaskDateVal2 >= datasetDateVal )
            {
              // if these conditions are met, then this is considered to be a match
              isMatch = OFTrue;
            }
          }
        }
      }
    }

    // free memory
    delete ddv;
    delete sdv;
    if( sdvv1 != NULL ) delete sdvv1;
    if( sdvv2 != NULL ) delete sdvv2;

    // return result
    return( isMatch );
  }
  else
  {
    // so dataset date value is not given; in this case, since the date
    // value in the search mask is non-universal, we do not have a match
    return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

01413 OFBool WlmFileSystemInteractionManager::TimeRangeMatch( const char *datasetTimeValue, const char *searchMaskTimeValue )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function performs a time range match and returns OFTrue if the dataset's and
//                the search mask's values in the corresponding attributes match; otherwise OFFalse
//                will be returned
// Parameters   : datasetTimeValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskTimeValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  char *stvv1 = NULL, *stvv2 = NULL;
  OFTime datasetTimeVal, searchMaskTimeVal1, searchMaskTimeVal2;
  OFCondition cond;

  // if time value in dataset is given, perform date range match
  if( datasetTimeValue != NULL )
  {
    // initialize result
    OFBool isMatch = OFFalse;

    // copy values
    char *dtv = new char[ strlen( datasetTimeValue ) + 1 ];     strcpy( dtv, datasetTimeValue );
    char *stv = new char[ strlen( searchMaskTimeValue ) + 1 ];  strcpy( stv, searchMaskTimeValue );

    // strip trailing spaces
    dtv = DU_stripTrailingSpaces( dtv );
    stv = DU_stripTrailingSpaces( stv );

    // get actual time boundary values
    ExtractValuesFromRange( stv, stvv1, stvv2 );

    // generate OFTime objects from strings
    cond = DcmTime::getOFTimeFromString( OFString( dtv ), datasetTimeVal );
    if( cond.good() )
    {
      cond = DcmTime::getOFTimeFromString( (( stvv1 != NULL ) ? OFString( stvv1 ) : OFString("000000")), searchMaskTimeVal1 );
      if( cond.good() )
      {
        cond = DcmTime::getOFTimeFromString( (( stvv2 != NULL ) ? OFString( stvv2 ) : OFString("235959")), searchMaskTimeVal2 );
        if( cond.good() )
        {
          // now that we have the time objects we can actually
          // compare the time values and determine if it's a match

          // check if the lower value in the search mask is earlier
          // than or equal to the lower value in the dataset
          if( searchMaskTimeVal1 <= datasetTimeVal )
          {
            // now check if the upper value in the search mask is later
            // than or equal to the upper value in the dataset
            if( searchMaskTimeVal2 >= datasetTimeVal )
            {
              // if these conditions are met, then this is considered to be a match
              isMatch = OFTrue;
            }
          }
        }
      }
    }

    // free memory
    delete dtv;
    delete stv;
    if( stvv1 != NULL ) delete stvv1;
    if( stvv2 != NULL ) delete stvv2;

    // return result
    return( isMatch );
  }
  else
  {
    // so dataset time value is not given; in this case, since the time
    // value in the search mask is non-universal, we do not have a match
    return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

01492 OFBool WlmFileSystemInteractionManager::DateTimeSingleValueMatch( const char *datasetDateValue, const char *datasetTimeValue, const char *searchMaskDateValue, const char *searchMaskTimeValue )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function performs a date time single value match and returns OFTrue if the dataset's
//                and the search mask's values in the corresponding attributes match; otherwise OFFalse
//                will be returned
// Parameters   : datasetDateValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                datasetTimeValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskDateValue - [in] Value for the corresponding attribute in the search mask; never NULL.
//                searchMaskTimeValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  OFDate datasetDateVal, searchMaskDateVal;
  OFTime datasetTimeVal, searchMaskTimeVal;
  OFCondition cond;

  // if we are dealing with universal matching in date and time, there is a match
  if( strcmp( searchMaskDateValue, "" ) == 0 && strcmp( searchMaskTimeValue, "" ) == 0 )
  {
    return( OFTrue );
  }
  else
  {
    // so we are not dealing with universal matching in date and time, we have to check both values individually
    OFBool dateValuesMatch = OFFalse;
    OFBool timeValuesMatch = OFFalse;

    // check date values
    if( strcmp( searchMaskDateValue, "" ) == 0 )
    {
      // a universal date always matches
      dateValuesMatch = OFTrue;
    }
    else
    {
      // so we do not have a universal date
      if( datasetDateValue == NULL )
      {
        // if there is no date value in the dataset, the non-universal date is not matched
        dateValuesMatch = OFFalse;
      }
      else
      {
        // in this case that we are dealing with a non-universal date and a
        // date value in the dataset, perform the date match

        // copy values
        char *ddv = new char[ strlen( datasetDateValue ) + 1 ];     strcpy( ddv, datasetDateValue );
        char *sdv = new char[ strlen( searchMaskDateValue ) + 1 ];  strcpy( sdv, searchMaskDateValue );

        // strip trailing spaces
        ddv = DU_stripTrailingSpaces( ddv );
        sdv = DU_stripTrailingSpaces( sdv );

        // generate OFDate objects from strings
        cond = DcmDate::getOFDateFromString( OFString( ddv ), datasetDateVal );
        if( cond.good() )
        {
          cond = DcmDate::getOFDateFromString( OFString( sdv ), searchMaskDateVal );
          if( cond.good() )
          {
            // now that we have the date objects we can actually
            // compare the date values and determine if it's a match

            // check if the date value in the search mask equals the date value in the dataset
            if( searchMaskDateVal == datasetDateVal )
            {
              // if these conditions are met, then this is considered to be a match
              dateValuesMatch = OFTrue;
            }
          }
        }

        // free memory
        delete ddv;
        delete sdv;
      }
    }

    // check time values
    if( strcmp( searchMaskTimeValue, "" ) == 0 )
    {
      // a universal time always matches
      timeValuesMatch = OFTrue;
    }
    else
    {
      // so we do not have a universal time
      if( datasetTimeValue == NULL )
      {
        // if there is no time value in the dataset, the non-universal time is not matched
        timeValuesMatch = OFFalse;
      }
      else
      {
        // in this case that we are dealing with a non-universal time and a
        // time value in the dataset, perform the time match

        // copy values
        char *dtv = new char[ strlen( datasetTimeValue ) + 1 ];     strcpy( dtv, datasetTimeValue );
        char *stv = new char[ strlen( searchMaskTimeValue ) + 1 ];  strcpy( stv, searchMaskTimeValue );

        // strip trailing spaces
        dtv = DU_stripTrailingSpaces( dtv );
        stv = DU_stripTrailingSpaces( stv );

        // generate OFTime objects from strings
        cond = DcmTime::getOFTimeFromString( OFString( dtv ), datasetTimeVal );
        if( cond.good() )
        {
          cond = DcmTime::getOFTimeFromString( OFString( stv ), searchMaskTimeVal );
          if( cond.good() )
          {
            // now that we have the time objects we can actually
            // compare the time values and determine if it's a match

            // check if the time value in the search mask equals the time value in the dataset
            if( searchMaskTimeVal == datasetTimeVal )
            {
              // if these conditions are met, then this is considered to be a match
              timeValuesMatch = OFTrue;
            }
          }
        }

        // free memory
        delete dtv;
        delete stv;
      }
    }

    // in case date and time values match, we have a match
    if( dateValuesMatch && timeValuesMatch )
      return( OFTrue );
    else
      return( OFFalse );
  }
}

// ----------------------------------------------------------------------------

01633 OFBool WlmFileSystemInteractionManager::DateSingleValueMatch( const char *datasetDateValue, const char *searchMaskDateValue )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function performs a date single value match and returns OFTrue if the dataset's
//                and the search mask's values in the corresponding attributes match; otherwise OFFalse
//                will be returned
// Parameters   : datasetDateValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskDateValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  OFDate datasetDateVal, searchMaskDateVal;
  OFCondition cond;

  // if we are dealing with universal matching, there is a match
  if( strcmp( searchMaskDateValue, "" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching and there is a
    // date value in the dataset, compare the two date values
    if( datasetDateValue != NULL )
    {
      // initialize result
      OFBool isMatch = OFFalse;

      // copy values
      char *ddv = new char[ strlen( datasetDateValue ) + 1 ];     strcpy( ddv, datasetDateValue );
      char *sdv = new char[ strlen( searchMaskDateValue ) + 1 ];  strcpy( sdv, searchMaskDateValue );

      // strip trailing spaces
      ddv = DU_stripTrailingSpaces( ddv );
      sdv = DU_stripTrailingSpaces( sdv );

      // generate OFDate objects from strings
      cond = DcmDate::getOFDateFromString( OFString( ddv ), datasetDateVal );
      if( cond.good() )
      {
        cond = DcmDate::getOFDateFromString( OFString( sdv ), searchMaskDateVal );
        if( cond.good() )
        {
          // now that we have the date objects we can actually
          // compare the date values and determine if it's a match

          // check if the date value in the search mask equals the date value in the dataset
          if( searchMaskDateVal == datasetDateVal )
          {
            // if this condition is met, then this is considered to be a match
            isMatch = OFTrue;
          }
        }
      }

      // free memory
      delete ddv;
      delete sdv;

      // return result
      return( isMatch );
    }
    else
    {
      // if we are not dealing with universal matching and there
      // is no date value in the dataset, there is no match
      return( OFFalse );
    }
  }
}

// ----------------------------------------------------------------------------

01703 OFBool WlmFileSystemInteractionManager::TimeSingleValueMatch( const char *datasetTimeValue, const char *searchMaskTimeValue )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function performs a time single value match and returns OFTrue if the dataset's
//                and the search mask's values in the corresponding attributes match; otherwise OFFalse
//                will be returned
// Parameters   : datasetTimeValue    - [in] Value for the corresponding attribute in the dataset; might be NULL.
//                searchMaskTimeValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  OFTime datasetTimeVal, searchMaskTimeVal;
  OFCondition cond;

  // if we are dealing with universal matching, there is a match
  if( strcmp( searchMaskTimeValue, "" ) == 0 )
    return( OFTrue );
  else
  {
    // if we are not dealing with universal matching and there is a
    // time value in the dataset, compare the two date values
    if( datasetTimeValue != NULL )
    {
      // initialize result
      OFBool isMatch = OFFalse;

      // copy values
      char *dtv = new char[ strlen( datasetTimeValue ) + 1 ];     strcpy( dtv, datasetTimeValue );
      char *stv = new char[ strlen( searchMaskTimeValue ) + 1 ];  strcpy( stv, searchMaskTimeValue );

      // strip trailing spaces
      dtv = DU_stripTrailingSpaces( dtv );
      stv = DU_stripTrailingSpaces( stv );

      // generate OFTime objects from strings
      cond = DcmTime::getOFTimeFromString( OFString( dtv ), datasetTimeVal );
      if( cond.good() )
      {
        cond = DcmTime::getOFTimeFromString( OFString( stv ), searchMaskTimeVal );
        if( cond.good() )
        {
          // now that we have the time objects we can actually
          // compare the time values and determine if it's a match

          // check if the time value in the search mask equals the time value in the dataset
          if( searchMaskTimeVal == datasetTimeVal )
          {
            // if this condition is met, then this is considered to be a match
            isMatch = OFTrue;
          }
        }
      }

      // free memory
      delete dtv;
      delete stv;

      // return result
      return( isMatch );
    }
    else
    {
      // if we are not dealing with universal matching and there
      // is no time value in the dataset, there is no match
      return( OFFalse );
    }
  }
}

// ----------------------------------------------------------------------------

01773 OFBool WlmFileSystemInteractionManager::CaseSensitiveSingleValueMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values
//                match while performing a case sensitive single value match; otherwise OFFalse
//                will be returned
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; never NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // initialize result variable
  OFBool matchFound = OFTrue;

  // copy values
  char *dv = new char[ strlen( datasetValue ) + 1 ];
  strcpy( dv, datasetValue );
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // strip trailing spaces
  dv = DU_stripTrailingSpaces( dv );
  sv = DU_stripTrailingSpaces( sv );

  // perform match
  if( strcmp( dv, sv ) != 0 )
    matchFound = OFFalse;

  // free memory
  delete dv;
  delete sv;

  // return result
  return( matchFound );
}

// ----------------------------------------------------------------------------

01810 OFBool WlmFileSystemInteractionManager::WildcardMatch( const char *datasetValue, const char *searchMaskValue )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function returns OFTrue if the dataset's and the search mask's values
//                match while performing a wildcard match; otherwise OFFalse will be returned.
// Parameters   : datasetValue    - [in] Value for the corresponding attribute in the dataset; never NULL.
//                searchMaskValue - [in] Value for the corresponding attribute in the search mask; never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // initialize return value
  OFBool ok = OFFalse;

  // copy values
  char *dv = new char[ strlen( datasetValue ) + 1 ];
  strcpy( dv, datasetValue );
  char *sv = new char[ strlen( searchMaskValue ) + 1 ];
  strcpy( sv, searchMaskValue );

  // remember the pointers for delete
  char *dvanchor = dv;
  char *svanchor = sv;

  // strip trailing spaces
  dv = DU_stripTrailingSpaces( dv );
  sv = DU_stripTrailingSpaces( sv );

  // go through both strings character by character as long as
  // a) we do not see an EOS in sv AND
  // b) we do not see a '*' in sv AND
  // c) the current character in dv is equal to the
  //    current character in the sv, or sv contains
  //    a '?' and sv does not yet show an EOS.
  while( *sv != '\0' &&
         *sv != '*'  &&
         ( *sv == *dv || ( *sv == '?' && *dv != '\0' ) ) )
  {
    sv++;
    dv++;
  }

  // if the current pattern character equals the star symbol (wild card symbol) we need
  // to call another function. If this is not the case, ok will be set to OFTrue or
  // OFFalse, depending on if we got to the end of both strings in the above loop.
  if( *sv == '*' )
    ok = MatchStarSymbol( dv, sv+1 );
  else
  {
    if( *sv == '\0' && *dv == '\0' )
      ok = OFTrue;
    else
      ok = OFFalse;
  }

  // free memory
  delete dvanchor;
  delete svanchor;

  // return result
  return( ok );
}

// ----------------------------------------------------------------------------

01873 OFBool WlmFileSystemInteractionManager::MatchStarSymbol( const char *dv, const char *sv )
// Date         : July 12, 2002
// Author       : Thomas Wilkens
// Task         : This function is called, if the search pattern contains a star symbol. It determines
//                if dv (the dataset's value) still matches sv (the search mask's value). This function
//                takes the star symbol in sv into account. (Note that the pattern value might contain
//                more wild card symbols.) The function will return OFTrue if there is a match; if there
//                is not a match it will return OFFalse.
// Parameters   : dv - [in] Dataset's value; never NULL.
//                sv - [in] Search mask's value (may contain wild card symbols); never NULL.
// Return Value : OFTrue if the values match, OFFalse otherwise.
{
  // initialize result value
  OFBool ok = OFFalse;

  // move pointer one char to the right as long as it points to a star symbol
  while( *sv == '*' )
    sv++;

  // if we got to the end of sv, return OFTrue
  if( *sv == '\0' )
    return OFTrue;

  // if there is something else at the end of sv,
  // we need to go ahead and compare the rest of the two strings

  // as long as ok equals OFFalse and we did not get to the end of the string
  while( !ok && *dv != '\0' )
  {
    // if sv reveals a '?' or if both pointers refer to the same
    // character, we need to call WildcardMatch again, to determine a result
    if( *sv == '?' || *dv == *sv )
      ok = WildcardMatch( dv+1, sv+1 );

    // if ok still equals OFFalse, set pointer one character to the right
    if( !ok )
      dv++;
  }

  // return result
  return( ok );
}

// ----------------------------------------------------------------------------

01918 void WlmFileSystemInteractionManager::ExtractValuesFromRange( const char *range, char *&lower, char *&upper )
// Date         : July 15, 2002
// Author       : Thomas Wilkens
// Task         : This function extracts the actual lower and upper date or time values from a given
//                date or time range.
// Parameters   : range - [in] Date or time range from which lower and upper values shall be extracted.
//                lower - [out] Newly created string specifying the lower value from the date/time range;
//                        NULL if value is not specified in range.
//                upper - [out] Newly created string specifying the upper value from the date/time range;
//                        NULL if value is not specified in range.
// Return Value : none.
{
  // get lower value
  const char *tmp = strchr( range, '-' );
  int res = tmp - range;
  if( res == 0 )
    lower = NULL;
  else
  {
    lower = new char[ res + 1 ];
    strncpy( lower, range, res );
    lower[res] = '\0';
  }

  // get upper value
  int len = strlen( range );
  if( res == len - 1 )
    upper = NULL;
  else
  {
    upper = new char[ len - 1 - res + 1 ];
    strncpy( upper, tmp + 1, len - 1 - res );
    upper[len-1-res] = '\0';
  }
}

// ----------------------------------------------------------------------------

/*
** CVS Log
** $Log: wlfsim.cc,v $
** Revision 1.12  2004/01/07 08:32:34  wilkens
** Added new sequence type return key attributes to wlmscpfs. Fixed bug that for
** equally named attributes in sequences always the same value will be returned.
** Added functionality that also more than one item will be returned in sequence
** type return key attributes.
**
** Revision 1.11  2003/12/23 13:03:55  wilkens
** Integrated new matching key attributes into wlmscpfs.
** Updated matching algorithm in wlmscpfs so that universal matching key
** attributes will also lead to a match in case the corresponding attribute does
** does exist in the dataset.
**
** Revision 1.10  2003/10/13 13:28:19  meichel
** Minor code purifications, needed for Borland C++
**
** Revision 1.9  2003/08/20 14:45:15  wilkens
** Added new class OFSetIterator, an iterator class for OFxxxSet data structures.
**
** Revision 1.8  2002/12/13 12:37:08  wilkens
** Modified code to keep Sun CC 2.0.1 happy on Solaris 2.5.1 (unreachable
** statement warning).
**
** Revision 1.7  2002/12/12 16:49:40  wilkens
** Added some code to avoid compiler warning (unsigned long passed as unsigned
** int) on Sun CC 2.0.1.
**
** Revision 1.6  2002/12/11 18:10:48  joergr
** Added const type specifier to a "char*" variable declaration to avoid
** compiler error on Sun CC 5.2.
**
** Revision 1.5  2002/12/09 13:42:22  joergr
** Renamed parameter to avoid name clash with global function index().
**
** Revision 1.4  2002/11/28 11:04:47  meichel
** Adapted module dcmwlm to use of new header file ofstdinc.h
**
** Revision 1.3  2002/08/22 09:14:04  wilkens
** Adapted code to new loadFile and saveFile methods, thus removing direct
** use of the DICOM stream classes.
**
** Revision 1.2  2002/08/12 10:56:17  wilkens
** Made some modifications in in order to be able to create a new application
** which contains both wlmscpdb and ppsscpdb and another application which
** contains both wlmscpfs and ppsscpfs.
**
** Revision 1.1  2002/08/05 09:10:12  wilkens
** Modfified the project's structure in order to be able to create a new
** application which contains both wlmscpdb and ppsscpdb.
**
** Revision 1.1  2002/07/17 13:10:20  wilkens
** Corrected some minor logical errors in the wlmscpdb sources and completely
** updated the wlmscpfs so that it does not use the original wlistctn sources
** any more but standard wlm sources which are now used by all three variants
** of wlmscps.
**
**
**
*/

Generated by  Doxygen 1.6.0   Back to index