1 /*
2  *
3  *  Copyright (C) 1993-2018, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmqrdb
15  *
16  *  Author:  Marco Eichelberg / Didier Lemoine / Gilles Mevel
17  *
18  *  Purpose: enums and structures used for the database index file
19  *
20  */
21 
22 #ifndef DATAPRIV_H
23 #define DATAPRIV_H
24 
25 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
26 
27 #include "dcmtk/ofstd/ofoption.h"
28 #include "dcmtk/dcmnet/dicom.h"
29 #include "dcmtk/dcmdata/dcdatset.h"
30 #include "dcmtk/dcmdata/dcuid.h"
31 #include "dcmtk/dcmdata/dcdeftag.h"
32 #include "dcmtk/dcmdata/dcspchrs.h"
33 #include "dcmtk/dcmqrdb/dcmqrdbi.h"
34 
35 BEGIN_EXTERN_C
36 #ifdef HAVE_IO_H
37 #define access my_access    // Workaround to make Visual C++ Compiler happy!
38 #include <io.h>
39 #undef access
40 #endif
41 END_EXTERN_C
42 
43 // include this file in doxygen documentation
44 
45 /** @file dcmqridx.h
46  *  @brief type definitions and constants for the database index file
47  */
48 
49 /** types of query keys
50  */
51 enum DB_KEY_TYPE
52 {
53     /// unique key
54     UNIQUE_KEY,
55     /// required key
56     REQUIRED_KEY,
57     /// optional key
58     OPTIONAL_KEY
59 };
60 
61 /** query models
62  */
63 enum DB_QUERY_CLASS
64 {
65     /// patient root Q/R model
66     PATIENT_ROOT,
67     /// study root Q/R model
68     STUDY_ROOT,
69     /// patient/study only Q/R model
70     PATIENT_STUDY
71 };
72 
73 /** Level Strings
74  */
75 
76 #define PATIENT_LEVEL_STRING    "PATIENT"
77 #define STUDY_LEVEL_STRING      "STUDY"
78 #define SERIE_LEVEL_STRING      "SERIES"
79 #define IMAGE_LEVEL_STRING      "IMAGE"
80 
81 /*
82 ** Maximum size of things to put in db records.
83 ** Some values will have vm>1 thus these maximums are
84 ** intended to leave enough space for most common uses.
85 */
86 #define AE_MAX_LENGTH   128     /* Application Entity    */
87 #define AS_MAX_LENGTH   32      /* Age String            */
88 #define AT_MAX_LENGTH   32      /* Attribute Tag         */
89 #define CS_MAX_LENGTH   128     /* Code String           */
90 #define DA_MAX_LENGTH   80      /* Date                  */
91 #define DS_MAX_LENGTH   128     /* Decimal String        */
92 #define DT_MAX_LENGTH   208     /* Date Time             */
93 #define FL_MAX_LENGTH   32      /* FLoating point single */
94 #define FD_MAX_LENGTH   64      /* Floating point Double */
95 #define IS_MAX_LENGTH   96      /* Integer String        */
96 #define LO_MAX_LENGTH   256     /* Long String           */
97 #define LT_MAX_LENGTH   40960   /* Long Text             */
98 #define PN_MAX_LENGTH   256     /* Person Name           */
99 #define SH_MAX_LENGTH   64      /* Short String          */
100 #define SL_MAX_LENGTH   32      /* Signed Long           */
101 #define SS_MAX_LENGTH   16      /* Signed Short          */
102 #define ST_MAX_LENGTH   4096    /* Short Text            */
103 #define TM_MAX_LENGTH   128     /* Time                  */
104 #define UI_MAX_LENGTH   64      /* Unique Identifier     */
105 #define UL_MAX_LENGTH   32      /* Unsigned Long         */
106 #define US_MAX_LENGTH   16      /* Unsigned Short        */
107 #define CS_LABEL_MAX_LENGTH 16  /* Code String - Presentation Label */
108 #define DESCRIPTION_MAX_LENGTH 128  /* Not related to any particular DICOM attribute */
109 
110 #define DBC_MAXSTRING           256
111 
112 #define MAX_MAX_STUDIES         DB_UpperMaxStudies
113 #define MAX_NUMBER_OF_IMAGES    10000
114 #define SIZEOF_IDXRECORD        (sizeof (IdxRecord))
115 #define SIZEOF_STUDYDESC        (sizeof (StudyDescRecord) * MAX_MAX_STUDIES)
116 
117 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
118 
119 struct DCMTK_DCMQRDB_EXPORT DB_SerializedTagKey
120 {
DB_SerializedTagKeyDB_SerializedTagKey121     inline DB_SerializedTagKey() {}
DB_SerializedTagKeyDB_SerializedTagKey122     inline DB_SerializedTagKey(const DcmTagKey& rhs) { *this = rhs; }
123     inline DB_SerializedTagKey& operator=(const DcmTagKey& tk) { key[0] = tk.getGroup(); key[1] = tk.getElement(); return *this; }
DcmTagKeyDB_SerializedTagKey124     inline operator DcmTagKey() const { return DcmTagKey( key[0], key[1] ); }
125     inline bool operator==(const DB_SerializedTagKey& rhs) const { return key[0] == rhs.key[0] && key[1] == rhs.key[1]; }
126     Uint16 key[2];
127 };
128 
129 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
130 
131 struct DCMTK_DCMQRDB_EXPORT DB_SerializedCharPtr
132 {
DB_SerializedCharPtrDB_SerializedCharPtr133     inline DB_SerializedCharPtr(char* p) { ptr.p = p; }
134     inline DB_SerializedCharPtr& operator=(char* p) { ptr.p = p; return *this; }
135     inline operator char*() const { return ptr.p; }
136     union
137     {
138         char* p;
139         Uint64 placeholder;
140     } ptr ;
141 };
142 
143 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
144 
145 /** this class provides a primitive interface for handling a flat DICOM element,
146  *  similar to DcmElement, but only for use within the database module
147  */
148 struct DCMTK_DCMQRDB_EXPORT DB_SmallDcmElmt
149 {
150 public:
151     /// default constructor
152     DB_SmallDcmElmt();
153 
154     /// pointer to the value field
155     DB_SerializedCharPtr PValueField ;
156 
157     /// value length in bytes
158     Uint32 ValueLength ;
159 
160     /// attribute tag
161     DB_SerializedTagKey XTag ;
162 
163 private:
164     /// private undefined copy constructor
165     DB_SmallDcmElmt(const DB_SmallDcmElmt& copy);
166     /// private undefined copy assignment operator
167     DB_SmallDcmElmt& operator=(const DB_SmallDcmElmt& copy);
168 };
169 
170 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
171 
172 /** this class provides a primitive interface for handling a list of flat DICOM elements,
173  *  similar to DcmItem, but only for use within the database module
174  */
175 struct DCMTK_DCMQRDB_EXPORT DB_ElementList
176 {
177     /// default constructor
DB_ElementListDB_ElementList178     DB_ElementList(): elem(), next(NULL), utf8Value() {}
179 
180     /// current list element
181     DB_SmallDcmElmt elem ;
182 
183     /// pointer to next in list
184     struct DB_ElementList *next ;
185 
186     /// UTF-8 cache
187     OFoptional<OFString> utf8Value ;
188 
189 private:
190     /// private undefined copy constructor
191     DB_ElementList(const DB_ElementList& copy);
192     /// private undefined copy assignment operator
193     DB_ElementList& operator=(const DB_ElementList& copy);
194 };
195 
196 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
197 
198 struct DCMTK_DCMQRDB_EXPORT DB_UidList
199 {
200     char *patient ;
201     char *study ;
202     char *serie ;
203     char *image ;
204     struct DB_UidList *next ;
205 };
206 
207 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
208 
209 struct DCMTK_DCMQRDB_EXPORT DB_CounterList
210 {
211     int idxCounter ;
212     struct DB_CounterList *next ;
213 };
214 
215 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
216 
217 struct DCMTK_DCMQRDB_EXPORT DB_FindAttr
218 {
219     DcmTagKey tag ;
220     DB_LEVEL level ;
221     DB_KEY_TYPE keyAttr ;
222 
223     /* to passify some C++ compilers */
DB_FindAttrDB_FindAttr224     DB_FindAttr(const DcmTagKey& t, DB_LEVEL l, DB_KEY_TYPE kt)
225         : tag(t), level(l), keyAttr(kt) { }
226 };
227 
228 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
229 
230 struct DCMTK_DCMQRDB_EXPORT DB_Private_Handle
231 {
232     int pidx ;
233     OFString findRequestCharacterSet ;
234     DcmSpecificCharacterSet findRequestConverter ;
235     DB_ElementList *findRequestList ;
236     DB_ElementList *findResponseList ;
237     DB_LEVEL queryLevel ;
238     char indexFilename[DBC_MAXSTRING+1] ;
239     char storageArea[DBC_MAXSTRING+1] ;
240     long maxBytesPerStudy ;
241     long maxStudiesAllowed ;
242     int idxCounter ;
243     DB_CounterList *moveCounterList ;
244     int NumberRemainOperations ;
245     DB_QUERY_CLASS rootLevel ;
246     DB_UidList *uidList ;
247 
DB_Private_HandleDB_Private_Handle248     DB_Private_Handle()
249     : pidx(0)
250     , findRequestCharacterSet()
251     , findRequestConverter()
252     , findRequestList(NULL)
253     , findResponseList(NULL)
254     , queryLevel(STUDY_LEVEL)
255 //  , indexFilename()
256 //  , storageArea()
257     , maxBytesPerStudy(0)
258     , maxStudiesAllowed(0)
259     , idxCounter(0)
260     , moveCounterList(NULL)
261     , NumberRemainOperations(0)
262     , rootLevel(STUDY_ROOT)
263     , uidList(NULL)
264     {
265     }
266 };
267 
268 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
269 
270 /** this struct defines the structure of each "Study Record" in the index.dat
271  *  file maintained by this module. A Study Record is a direct binary copy
272  *  of an instance of this struct.
273  */
274 struct DCMTK_DCMQRDB_EXPORT StudyDescRecord
275 {
276     /// Study Instance UID of the study described by this record
277     char StudyInstanceUID [UI_MAX_LENGTH+1] ;
278 
279     /// combined size (in bytes) of all images of this study in the database
280     Uint32 StudySize ;
281 
282     /// timestamp for last update of this study. Format: output of time(2) converted to double.
283     double LastRecordedDate ;
284 
285     /// number of images of this study in the database
286     Uint32 NumberofRegistratedImages ;
287 };
288 
289 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
290 
291 struct DCMTK_DCMQRDB_EXPORT ImagesofStudyArray
292 {
293     Uint32 idxCounter ;
294     double RecordedDate ;
295     Uint32 ImageSize ;
296 };
297 
298 
299 /* the following constants define which array element
300  * of the param[] array in the IdxRecord structure
301  * is linked to which value field in the IdxRecord.
302  * numbers must be continuous, starting with 0.
303  *
304  * The constant NBPARAMETERS must contain the number
305  * of array elements to be referenced in param[]
306  * (= highest index +1)
307  */
308 
309 #define RECORDIDX_PatientBirthDate                0
310 #define RECORDIDX_PatientSex                      1
311 #define RECORDIDX_PatientName                     2
312 #define RECORDIDX_PatientID                       3
313 #define RECORDIDX_PatientBirthTime                4
314 #define RECORDIDX_OtherPatientIDs                 5
315 #define RECORDIDX_OtherPatientNames               6
316 #define RECORDIDX_EthnicGroup                     7
317 #define RECORDIDX_StudyDate                       8
318 #define RECORDIDX_StudyTime                       9
319 #define RECORDIDX_StudyID                        10
320 #define RECORDIDX_StudyDescription               11
321 #define RECORDIDX_NameOfPhysiciansReadingStudy   12
322 #define RECORDIDX_AccessionNumber                13
323 #define RECORDIDX_ReferringPhysicianName         14
324 #define RECORDIDX_ProcedureDescription           15
325 #define RECORDIDX_AttendingPhysiciansName        16
326 #define RECORDIDX_StudyInstanceUID               17
327 #define RECORDIDX_OtherStudyNumbers              18
328 #define RECORDIDX_AdmittingDiagnosesDescription  19
329 #define RECORDIDX_PatientAge                     20
330 #define RECORDIDX_PatientSize                    21
331 #define RECORDIDX_PatientWeight                  22
332 #define RECORDIDX_Occupation                     23
333 #define RECORDIDX_SeriesNumber                   24
334 #define RECORDIDX_SeriesInstanceUID              25
335 #define RECORDIDX_Modality                       26
336 #define RECORDIDX_ImageNumber                    27
337 #define RECORDIDX_SOPInstanceUID                 28
338 #define RECORDIDX_SeriesDate                     29
339 #define RECORDIDX_SeriesTime                     30
340 #define RECORDIDX_SeriesDescription              31
341 #define RECORDIDX_ProtocolName                   32
342 #define RECORDIDX_OperatorsName                  33
343 #define RECORDIDX_PerformingPhysicianName        34
344 #define RECORDIDX_PresentationLabel              35
345 #define RECORDIDX_IssuerOfPatientID              36
346 #define RECORDIDX_SpecificCharacterSet           37
347 
348 #define NBPARAMETERS                             38
349 
350 /* ENSURE THAT DBVERSION IS INCREMENTED WHENEVER ONE OF THESE STRUCTS IS MODIFIED */
351 
352 /** this class manages an instance entry of the index file.
353  *  Each instance/image record within the index.dat file is
354  *  a direct (binary) copy of this structure.
355  */
356 struct DCMTK_DCMQRDB_EXPORT IdxRecord
357 {
358     /// default constructor
359     IdxRecord();
360 
361     char    filename                        [DBC_MAXSTRING+1] ;
362     char    SOPClassUID                     [UI_MAX_LENGTH+1] ;
363     double  RecordedDate ;
364     Uint32  ImageSize ;
365 
366     DB_SmallDcmElmt param                   [NBPARAMETERS] ;
367 
368     char    PatientBirthDate                [DA_MAX_LENGTH+1] ;
369     char    PatientSex                      [CS_MAX_LENGTH+1] ;
370     char    PatientName                     [PN_MAX_LENGTH+1] ;
371     char    PatientID                       [LO_MAX_LENGTH+1] ;
372     char    PatientBirthTime                [TM_MAX_LENGTH+1] ;
373     char    OtherPatientIDs                 [LO_MAX_LENGTH+1] ;
374     char    OtherPatientNames               [PN_MAX_LENGTH+1] ;
375     char    EthnicGroup                     [SH_MAX_LENGTH+1] ;
376 
377     char    StudyDate                       [DA_MAX_LENGTH+1] ;
378     char    StudyTime                       [TM_MAX_LENGTH+1] ;
379     char    StudyID                         [CS_MAX_LENGTH+1] ;
380     char    StudyDescription                [LO_MAX_LENGTH+1] ;
381     char    NameOfPhysiciansReadingStudy    [PN_MAX_LENGTH+1] ;
382 
383     char    AccessionNumber                 [CS_MAX_LENGTH+1] ;
384     char    ReferringPhysicianName          [PN_MAX_LENGTH+1] ;
385     char    ProcedureDescription            [LO_MAX_LENGTH+1] ;
386     char    AttendingPhysiciansName         [PN_MAX_LENGTH+1] ;
387     char    StudyInstanceUID                [UI_MAX_LENGTH+1] ;
388     char    OtherStudyNumbers               [IS_MAX_LENGTH+1] ;
389     char    AdmittingDiagnosesDescription   [LO_MAX_LENGTH+1] ;
390     char    PatientAge                      [AS_MAX_LENGTH+1] ;
391     char    PatientSize                     [DS_MAX_LENGTH+1] ;
392     char    PatientWeight                   [DS_MAX_LENGTH+1] ;
393     char    Occupation                      [SH_MAX_LENGTH+1] ;
394 
395     char    SeriesNumber                    [IS_MAX_LENGTH+1] ;
396     char    SeriesInstanceUID               [UI_MAX_LENGTH+1] ;
397     char    Modality                        [CS_MAX_LENGTH+1] ;
398 
399     char    ImageNumber                     [IS_MAX_LENGTH+1] ;
400     char    SOPInstanceUID                  [UI_MAX_LENGTH+1] ;
401 
402     char    SeriesDate                      [DA_MAX_LENGTH+1] ;
403     char    SeriesTime                      [TM_MAX_LENGTH+1] ;
404     char    SeriesDescription               [LO_MAX_LENGTH+1] ;
405     char    ProtocolName                    [LO_MAX_LENGTH+1] ;
406     char    OperatorsName                   [PN_MAX_LENGTH+1] ;
407     char    PerformingPhysicianName         [PN_MAX_LENGTH+1] ;
408     char    PresentationLabel               [CS_LABEL_MAX_LENGTH+1] ;
409     char    IssuerOfPatientID               [LO_MAX_LENGTH+1] ;
410 
411     char    hstat;
412 
413     // Not related to any particular DICOM attribute !
414     char    InstanceDescription             [DESCRIPTION_MAX_LENGTH+1] ;
415 
416     // Specific Character Set, support for VM ~ 8 (depending on the
417     // actual length of the used DTs)
418     char    SpecificCharacterSet            [CS_MAX_LENGTH*8+1] ;
419 
420 private:
421     /* undefined */ IdxRecord(const IdxRecord& copy);
422     /* undefined */ IdxRecord& operator=(const IdxRecord& copy);
423 };
424 
425 
426 #endif
427