1 /*
2  *
3  *  Copyright (C) 2000-2019, 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:  ofstd
15  *
16  *  Author:  Joerg Riesmeier, Marco Eichelberg
17  *
18  *  Purpose: Class for various helper functions
19  *
20  */
21 
22 
23 #ifndef OFSTD_H
24 #define OFSTD_H
25 
26 #include "dcmtk/config/osconfig.h"
27 
28 #include "dcmtk/ofstd/oflist.h"     /* for class OFList */
29 #include "dcmtk/ofstd/ofstring.h"   /* for class OFString */
30 #include "dcmtk/ofstd/oftypes.h"    /* for OFBool */
31 #include "dcmtk/ofstd/oftraits.h"   /* for OFenable_if, ... */
32 #include "dcmtk/ofstd/ofcond.h"     /* for OFCondition */
33 #include "dcmtk/ofstd/oflimits.h"   /* for OFnumeric_limits<T>::max() */
34 #include "dcmtk/ofstd/oferror.h"
35 
36 #define INCLUDE_CASSERT
37 #define INCLUDE_CSTDLIB
38 #define INCLUDE_CSTDIO
39 #define INCLUDE_CSTRING
40 #define INCLUDE_CSTDARG
41 #define INCLUDE_UNISTD
42 #include "dcmtk/ofstd/ofstdinc.h"
43 
44 BEGIN_EXTERN_C
45 #ifdef HAVE_SYS_TYPES_H
46 #include <sys/types.h>  /* for size_t */
47 #endif
48 END_EXTERN_C
49 
50 /* Check if we are using glibc in a version where readdir() is known to be
51  * thread-safe and where readdir_r() is deprecated.
52  */
53 #if defined(__GLIBC__) && (((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 24)) || (__GLIBC__ >= 3))
54 #define READDIR_IS_THREADSAFE
55 #endif
56 
57 /*------------------------*
58  *  forward declarations  *
59  *------------------------*/
60 
61 class OFFilename;
62 class OFSockAddr;
63 
64 /*---------------------*
65  *  class declaration  *
66  *---------------------*/
67 
68 /** A class for various helper functions.
69  *  This class is used to comprise a number of "global" helper functions.
70  */
71 class DCMTK_OFSTD_EXPORT OFStandard
72 {
73 
74  public:
75 
76     // --- type definitions ---
77 
78     /** Markup language mode
79      */
80     enum E_MarkupMode
81     {
82         /// HTML (Hyper Text Markup Language)
83         MM_HTML,
84         /// HTML 3.2 (Hyper Text Markup Language)
85         MM_HTML32,
86         /// XHTML (Extensible Hyper Text Markup Language)
87         MM_XHTML,
88         /// XML (Extensible Markup Language)
89         MM_XML
90     };
91 
92     class OFGroup;
93     class OFPasswd;
94 
95     // --- string functions ---
96 
97     /** This function copies up to size - 1 characters from the NUL-
98      *  terminated string src to dst, NUL-terminating the result. It is
99      *  designed to be a safer, more consistent, and less error-prone
100      *  replacement for strncpy(3). strlcpy takes the full size of the
101      *  buffer (not just the length) and guarantees to NUL-terminate the
102      *  result (as long as size is larger than 0). Note that you should
103      *  include a byte for the NUL in size. Also note that strlcpy only
104      *  operates on true C strings, i. e. src must be NUL-terminated.
105      *  @param dst destination buffer of size siz, must not be NULL
106      *  @param src source string, must not be NULL
107      *  @param siz size of destination buffer
108      *  @return the total length of the string the function tried to
109      *    create, i.e. strlen(src).  While this may seem somewhat
110      *    confusing it was done to make truncation detection simple.
111      */
strlcpy(char * dst,const char * src,size_t siz)112     static inline size_t strlcpy(char *dst, const char *src, size_t siz)
113     {
114 #ifdef HAVE_STRLCPY
115       return ::strlcpy(dst, src, siz);
116 #else
117       return my_strlcpy(dst, src, siz);
118 #endif
119     }
120 
121     /** This function appends the NUL-terminated string src to the end of
122      *  dst. It will append at most size - strlen(dst) - 1 bytes, NUL-
123      *  terminating the result. It is designed to be a safer, more
124      *  consistent, and less error-prone replacement for strncat(3).
125      *  strlcat takes the full size of the buffer (not just the length) and
126      *  guarantees to NUL-terminate the result (as long as size is larger
127      *  than 0). Note that you should include a byte for the NUL in size.
128      *  Also note that strlcat only operates on true C strings, i. e. dst
129      *  and src must be NUL-terminated.
130      *  @param dst destination buffer of size siz, must not be NULL
131      *  @param src source string, must not be NULL
132      *  @param siz size of destination buffer
133      *  @return the total length of the string the function tried to
134      *    create, i.e. the initial length of dst plus the length of src.
135      *    While this may seem somewhat confusing it was done to make
136      *    truncation detection simple.
137      */
strlcat(char * dst,const char * src,size_t siz)138     static inline size_t strlcat(char *dst, const char *src, size_t siz)
139     {
140 #ifdef HAVE_STRLCAT
141       return ::strlcat(dst, src, siz);
142 #else
143       return my_strlcat(dst, src, siz);
144 #endif
145     }
146 
147     /* Standard C99 formatted string output function.
148      * This is an implementation of the snprintf(3) function as defined in the
149      * C99 standard. Like all functions of the  printf() family, it produces
150      * output according to a format string. Output is written to the character
151      * array passed as parameter str. The function never writes more than size
152      * bytes and guarantees that the result will be NUL terminated, although
153      * it may be truncated if the buffer provided is too small.
154      * @param str string buffer to write to
155      * @param size size of string buffer, in bytes
156      * @param format printf() format string
157      * @param ... parameters to be formatted
158      * @return number of characters that have been written (if the buffer is
159      *   large enough) or the number of characters that would have been
160      *   written (if the buffer is too small), in both cases not including
161      *   the final NUL character.
162      */
163     static int snprintf(char *str, size_t size, const char *format, ...);
164 
165     /* Standard C99 formatted string output function.
166      * This is an implementation of the snprintf(3) function as defined in the
167      * C99 standard. Like all functions of the  printf() family, it produces
168      * output according to a format string. Output is written to the character
169      * array passed as parameter str. The function never writes more than size
170      * bytes and guarantees that the result will be NUL terminated, although
171      * it may be truncated if the buffer provided is too small.
172      * @param str string buffer to write to
173      * @param size size of string buffer, in bytes
174      * @param format printf() format string
175      * @param ap parameters to be formatted
176      * @return number of characters that have been written (if the buffer is
177      *   large enough) or the number of characters that would have been
178      *   written (if the buffer is too small), in both cases not including
179      *   the final NUL character.
180      */
181     static int vsnprintf(char *str, size_t size, const char *format, va_list ap);
182 
183     /** convert a given error code to a string. This function wraps the various
184      *  approaches found on different systems. Internally, the standard function
185      *  strerror() or strerror_r() is used.
186      *  @param errnum error code to be converted
187      *  @param buf buffer which is used to store the result string (if supported)
188      *  @param buflen size if the buffer in bytes
189      *  @return pointer to string describing the error code. Please note that depending
190      *     on the implementation of the function used, the result may or may not be a
191      *     pointer to buf. The return value can also be NULL if the buffer is invalid.
192      */
193     static const char *strerror(const int errnum,
194                                 char *buf,
195                                 const size_t buflen);
196 
197     /** returns the upper-case version of a given string
198      *  @param result string variable in which the result is stored
199      *  @param value string value to be converted to upper case
200      *  @return reference to the resulting string (same as 'result')
201      */
202     static OFString &toUpper(OFString &result,
203                              const OFString &value);
204 
205     /** returns the upper-case version of a given string.
206      *  NB: This function changes the parameter 'value'.
207      *  @param value string value to be converted to upper case
208      *  @return reference to the resulting string (same as 'value')
209      */
210     static OFString &toUpper(OFString &value);
211 
212     /** returns the lower-case version of a given string
213      *  @param result string variable in which the result is stored
214      *  @param value string value to be converted to lower case
215      *  @return reference to the resulting string (same as 'result')
216      */
217     static OFString &toLower(OFString &result,
218                              const OFString &value);
219 
220     /** returns the lower-case version of a given string.
221      *  NB: This function changes the parameter 'value'.
222      *  @param value string value to be converted to lower case
223      *  @return reference to the resulting string (same as 'value')
224      */
225     static OFString &toLower(OFString &value);
226 
227     // --- file system functions ---
228 
229     /** check whether the given path exists.
230      *  This function does not distinguish files from directories (use 'fileExists()'
231      *  or 'directoryExists()' if required).
232      *  @param pathName name of the path to be checked. This path name may contain
233      *    wide characters if support enabled. Since there are various constructors
234      *    for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also
235      *    be passed directly to this parameter.
236      *  @return OFTrue if path exists, OFFalse otherwise
237      */
238     static OFBool pathExists(const OFFilename &pathName);
239 
240     /** check whether the given file exists.
241      *  This function also checks that the specified path points to file and not to
242      *  a directory (or the like).
243      *  @param fileName name of the file to be checked. This filename may contain wide
244      *    characters if support enabled. Since there are various constructors for the
245      *    OFFilename class, a "char *", "OFString" or "wchar_t *" can also be passed
246      *    directly to this parameter.
247      *  @return OFTrue if file exists, OFFalse otherwise
248      */
249     static OFBool fileExists(const OFFilename &fileName);
250 
251     /** check whether the given directory exists.
252      *  This function also checks that the specified path points to directory and
253      *  not to a file (or the like).
254      *  @param dirName name of the directory to be checked. This directory name may
255      *    contain wide characters if support enabled. Since there are various
256      *    constructors for the OFFilename class, a "char *", "OFString" or "wchar_t *"
257      *    can also be passed directly to this parameter.
258      *  @return OFTrue if directory exists, OFFalse otherwise
259      */
260     static OFBool dirExists(const OFFilename &dirName);
261 
262     /** check whether the given path is readable.
263      *  This function works for both files and directories.
264      *  @param pathName name of the path to be checked. This path name may contain
265      *    wide characters if support enabled. Since there are various constructors
266      *    for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also
267      *    be passed directly to this parameter.
268      *  @return OFTrue if path is readable, OFFalse otherwise
269      */
270     static OFBool isReadable(const OFFilename &pathName);
271 
272     /** check whether the given path is writeable.
273      *  This function works for both files and directories.
274      *  @param pathName name of the path to be checked. This path name may contain
275      *    wide characters if support enabled. Since there are various constructors
276      *    for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also
277      *    be passed directly to this parameter.
278      *  @return OFTrue if path is writeable, OFFalse otherwise
279      */
280     static OFBool isWriteable(const OFFilename &pathName);
281 
282     /** get directory name component from given path name.
283      *  Extracts the substring before the last path separator. If there is no path
284      *  separator in the given path name, the value of 'pathName' is returned by
285      *  default; if 'assumeDirName' is OFFalse, an empty string is returned.
286      *  NB: This function neither checks whether the given 'pathName' exists nor
287      *      whether the resulting name points to a valid or existing directory.
288      *  @note This method is provided for reasons of backward compatibility. Internally,
289      *    the following method (OFFilename version) is used.
290      *  @param result string variable in which the resulting directory name is stored
291      *  @param pathName path name from which the directory name should be extracted
292      *  @param assumeDirName assume that there always is a directory name in 'pathName'
293      *  @return reference to the resulting directory name (same as 'result')
294      */
295     static OFString &getDirNameFromPath(OFString &result,
296                                         const OFString &pathName,
297                                         const OFBool assumeDirName = OFTrue);
298 
299     /** get directory name component from given path name.
300      *  Extracts the substring before the last path separator. If there is no path
301      *  separator in the given path name, the value of 'pathName' is returned by
302      *  default; if 'assumeDirName' is OFFalse, an empty string is returned.
303      *  NB: This function neither checks whether the given 'pathName' exists nor
304      *      whether the resulting name points to a valid or existing directory.
305      *  @param result string variable in which the resulting directory name is stored.
306      *    This name may contain wide characters if support is enabled and 'pathName'
307      *    contains wide characters. In any case, the resulting string is stored with
308      *    UTF-8 encoding (8-bit) as an alternative representation.
309      *  @param pathName path name from which the directory name should be extracted.
310      *    This name may contain wide characters if support is enabled. Since there are
311      *    various constructors for the OFFilename class, a "char *", "OFString" or
312      *    "wchar_t *" can also be passed directly to this parameter.
313      *  @param assumeDirName assume that there always is a directory name in 'pathName'
314      *  @return reference to the resulting directory name (same as 'result')
315      */
316     static OFFilename &getDirNameFromPath(OFFilename &result,
317                                           const OFFilename &pathName,
318                                           const OFBool assumeDirName = OFTrue);
319 
320     /** get file name component from given path name.
321      *  Extracts the substring after the last path separator. If there is no path
322      *  separator in the given path name, the value of 'pathName' is returned by
323      *  default; if 'assumeFilename' is OFFalse, an empty string is returned.
324      *  NB: This function neither checks whether the given 'pathName' exists nor
325      *      whether the resulting name points to a valid or existing file.
326      *  @note This method is provided for reasons of backward compatibility.
327      *    Internally, the following method (OFFilename version) is used.
328      *  @param result string variable in which the resulting file name is stored
329      *  @param pathName path name from which the file name should be extracted
330      *  @param assumeFilename assume that there always is a file name in 'pathName'
331      *  @return reference to the resulting file name (same as 'result')
332      */
333     static OFString &getFilenameFromPath(OFString &result,
334                                          const OFString &pathName,
335                                          const OFBool assumeFilename = OFTrue);
336 
337     /** get file name component from given path name.
338      *  Extracts the substring after the last path separator. If there is no path
339      *  separator in the given path name, the value of 'pathName' is returned by
340      *  default; if 'assumeFilename' is OFFalse, an empty string is returned.
341      *  NB: This function neither checks whether the given 'pathName' exists nor
342      *      whether the resulting name points to a valid or existing file.
343      *  @param result string variable in which the resulting file name is stored.
344      *    This name may contain wide characters if support is enabled and 'pathName'
345      *    contains wide characters. In any case, the resulting string is stored with
346      *    UTF-8 encoding (8-bit) as an alternative representation.
347      *  @param pathName path name from which the file name should be extracted.
348      *    This name may contain wide characters if support is enabled. Since there
349      *    are various constructors for the OFFilename class, a "char *", "OFString"
350      *    or "wchar_t *" can also be passed directly to this parameter.
351      *  @param assumeFilename assume that there always is a file name in 'pathName'
352      *  @return reference to the resulting file name (same as 'result')
353      */
354     static OFFilename &getFilenameFromPath(OFFilename &result,
355                                            const OFFilename &pathName,
356                                            const OFBool assumeFilename = OFTrue);
357 
358     /** normalize the given directory name.
359      *  Removes trailing path separators from the directory name. If the resulting
360      *  directory name is an empty string and the flag 'allowEmptyDirName' is OFFalse
361      *  the directory name is set to "." (current directory). If the resulting directory
362      *  name is "." and the flag 'allowEmptyDirName' is OFTrue the directory name is set
363      *  to an empty string.
364      *  @note This method is provided for reasons of backward compatibility. Internally,
365      *    the following method (OFFilename version) is used.
366      *  @param result string variable in which the resulting directory name is stored
367      *  @param dirName directory name to be normalized
368      *  @param allowEmptyDirName flag indicating whether an empty directory name is allowed
369      *  @return reference to the resulting directory name (same as 'result')
370      */
371     static OFString &normalizeDirName(OFString &result,
372                                       const OFString &dirName,
373                                       const OFBool allowEmptyDirName = OFFalse);
374 
375     /** normalize the given directory name.
376      *  Removes trailing path separators from the directory name. If the resulting
377      *  directory name is an empty string and the flag 'allowEmptyDirName' is OFFalse
378      *  the directory name is set to "." (current directory). If the resulting directory
379      *  name is "." and the flag 'allowEmptyDirName' is OFTrue the directory name is set
380      *  to an empty string.
381      *  @param result string variable in which the resulting directory name is stored.
382      *    This name may contain wide characters if support is enabled and 'dirName'
383      *    contains wide characters. In any case, the resulting string is stored with UTF-8
384      *    encoding (8-bit) as an alternative representation.
385      *  @param dirName directory name to be normalized. This name may contain wide
386      *    characters if support is enabled. Since there are various constructors for the
387      *    OFFilename class, a "char *", "OFString" or "wchar_t *" can also be passed
388      *    directly to this parameter.
389      *  @param allowEmptyDirName flag indicating whether an empty directory name is allowed
390      *  @return reference to the resulting directory name (same as 'result')
391      */
392     static OFFilename &normalizeDirName(OFFilename &result,
393                                         const OFFilename &dirName,
394                                         const OFBool allowEmptyDirName = OFFalse);
395 
396     /** combine the given directory and file name.
397      *  Normalizes the directory name and appends the file name (with a path separator)
398      *  if not empty. If both 'dirName' and 'fileName' are empty strings and the flag
399      *  'allowEmptyDirName' is OFFalse the resulting path name is set to "." (current
400      *  directory). If 'dirName' is "." and the flag 'allowEmptyDirName' is OFTrue an
401      *  empty directory name is used.
402      *  NB: This function neither checks whether the given 'dirName' exists nor whether
403      *      the resulting path name points to a valid or existing file name. Furthermore,
404      *      the value of 'dirName' is ignored if 'fileName' starts with a path separator.
405      *  @note This method is provided for reasons of backward compatibility. Internally,
406      *    the following method (OFFilename version) is used.
407      *  @param result string variable in which the resulting path name is stored
408      *  @param dirName directory name to be combined with the file name
409      *  @param fileName file name to be combined with the directory name
410      *  @param allowEmptyDirName flag indicating whether an empty directory name is allowed
411      *  @return reference to the resulting path name (same as 'result')
412      */
413     static OFString &combineDirAndFilename(OFString &result,
414                                            const OFString &dirName,
415                                            const OFString &fileName,
416                                            const OFBool allowEmptyDirName = OFFalse);
417 
418     /** combine the given directory and file name.
419      *  Normalizes the directory name and appends the file name (with a path separator)
420      *  if not empty. If both 'dirName' and 'fileName' are empty strings and the flag
421      *  'allowEmptyDirName' is OFFalse the resulting path name is set to "." (current
422      *  directory). If 'dirName' is "." and the flag 'allowEmptyDirName' is OFTrue an
423      *  empty directory name is used.
424      *  NB: This function neither checks whether the given 'dirName' exists nor whether
425      *      the resulting path name points to a valid or existing file name. Furthermore,
426      *      the value of 'dirName' is ignored if 'fileName' starts with a path separator.
427      *  @param result string variable in which the resulting path name is stored. This
428      *    name may contain wide characters if support is enabled and 'dirName' as well as
429      *    'fileName' contain wide characters. In any case, the resulting string is stored
430      *    with UTF-8 encoding (8-bit) as an alternative representation.
431      *  @param dirName directory name to be combined with the file name. This name may
432      *    contain wide characters if support is enabled. Since there are various
433      *    constructors for the OFFilename class, a "char *", "OFString" or "wchar_t *" can
434      *    also be passed directly to this parameter.
435      *  @param fileName file name to be combined with the directory name. Should contain
436      *    wide characters if and only if 'dirName' contains wide characters.
437      *  @param allowEmptyDirName flag indicating whether an empty directory name is allowed
438      *  @return reference to the resulting path name (same as 'result')
439      */
440     static OFFilename &combineDirAndFilename(OFFilename &result,
441                                              const OFFilename &dirName,
442                                              const OFFilename &fileName,
443                                              const OFBool allowEmptyDirName = OFFalse);
444 
445     /** remove root directory prefix from given path name.
446      *  In case 'pathName' starts with 'rootDir', the common prefix is removed.
447      *  Otherwise, an empty string is returned (or a cleared OFFilename in case of error).
448      *  @param result string variable in which the resulting path name is stored.
449      *    This name may contain wide characters if support is enabled and 'rootDir' as
450      *    well as 'pathName' contain wide characters. In any case, the resulting string
451      *    is stored with UTF-8 encoding (8-bit) as an alternative representation.
452      *  @param rootDir name of the root directory to be removed. This name may contain
453      *    wide characters if support is enabled. Since there are various constructors for
454      *    the OFFilename class, a "char *", "OFString" or "wchar_t *" can also be passed
455      *    directly to this parameter.
456      *  @param pathName path name from which the root directory (prefix) is removed.
457      *    Should contain wide characters if and only if 'rootDir' contains wide characters.
458      *  @param allowLeadingPathSeparator flag indicating whether a leading path separator
459      *    is allowed for the resulting path name (automatically removed otherwise)
460      *  @return status, EC_Normal if successful, an error code otherwise
461      */
462     static OFCondition removeRootDirFromPathname(OFFilename &result,
463                                                  const OFFilename &rootDir,
464                                                  const OFFilename &pathName,
465                                                  const OFBool allowLeadingPathSeparator = OFTrue);
466 
467     /** append a filename extension to the given filename
468      *  @param result string variable in which the resulting filename is stored.
469      *    This name may contain wide characters if support is enabled and 'fileName'
470      *    contains wide characters. In any case, the resulting string is stored with
471      *    UTF-8 encoding (8-bit) as an alternative representation.
472      *  @param fileName filename to which the extension should be appended. This name
473      *    may contain wide characters if support is enabled. Since there are various
474      *    constructors for the OFFilename class, a "char *", "OFString" or "wchar_t *"
475      *    can also be passed directly to this parameter.
476      *  @param fileExtension filename extension to be appended (e.g.\ ".bak"). It is
477      *    converted to wide characters if 'fileName' contains wide characters.
478      *  @return reference to the resulting path name (same as 'result')
479      */
480     static OFFilename &appendFilenameExtension(OFFilename &result,
481                                                const OFFilename &fileName,
482                                                const OFFilename &fileExtension);
483 
484     /** scan a given directory (recursively) and add all filenames found to a list
485      *  @note This method is provided for reasons of backward compatibility. Internally,
486      *    the following method (OFFilename version) is used.
487      *  @param directory name of the directory to be scanned
488      *  @param fileList list to which the filenames are added. Please note that the list
489      *    is not not cleared automatically before new entries are added.
490      *  @param pattern optional wildcard pattern used to match the filenames against.
491      *    By default all files match. In order to work under Unix the system function
492      *    fnmatch() is required.
493      *  @param dirPrefix optional prefix added to the directory name.
494      *    This prefix will, however, not be part of the filenames added to the list.
495      *  @param recurse flag indicating whether to search recursively (default) or not
496      *  @return number of new files added to the list
497      */
498     static size_t searchDirectoryRecursively(const OFString &directory,
499                                              OFList<OFString> &fileList,
500                                              const OFString &pattern = "",
501                                              const OFString &dirPrefix = "",
502                                              const OFBool recurse = OFTrue);
503 
504     /** scan a given directory (recursively) and add all filenames found to a list
505      *  @param directory name of the directory to be scanned. This name may contain
506      *    wide characters if support is enabled. Since there are various constructors
507      *    for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also be
508      *    passed directly to this parameter.
509      *  @param fileList list to which the filenames are added. These names may contain
510      *    wide characters if support is enabled and 'directory' contains wide characters.
511      *    In any case, the resulting string is stored with UTF-8 encoding (8-bit) as an
512      *    alternative representation. Please note that the list is not not cleared
513      *    automatically before new entries are added.
514      *  @param pattern wildcard pattern used to match the filenames against. Should
515      *    contain wide characters if and only if 'directory' contains wide characters.
516      *    An empty pattern matches all files. In order to work under Unix the system
517      *    function fnmatch() is required.
518      *  @param dirPrefix prefix added to the directory name. Should contain wide
519      *    characters if and only if 'directory' contains wide characters.
520      *    This prefix will, however, not be part of the filenames added to the list.
521      *  @param recurse flag indicating whether to search recursively (default) or not
522      *  @return number of new files added to the list
523      */
524     static size_t searchDirectoryRecursively(const OFFilename &directory,
525                                              OFList<OFFilename> &fileList,
526                                              const OFFilename &pattern,
527                                              const OFFilename &dirPrefix,
528                                              const OFBool recurse = OFTrue);
529 
530     /** create a directory (including sub-directories) if it does not yet exist.  In other
531      *  words, this function creates directories recursively, i.e. with all sub-components.
532      *  @param dirName name of the directory to be created. This name may contain wide
533      *    characters if support is enabled. Since there are various constructors for the
534      *    OFFilename class, a "char *", "OFString" or "wchar_t *" can also be passed
535      *    directly to this parameter.
536      *  @param rootDir optional name of a root directory (prefix of 'dirName') that already
537      *    exists and that can, therefore, be skipped during the creation of sub-directories.
538      *    Should contain wide characters if and only if 'dirName' contains wide characters.
539      *  @return status, EC_Normal if successful (directory created or already exists), an
540      *    error code otherwise
541      */
542     static OFCondition createDirectory(const OFFilename &dirName,
543                                        const OFFilename &rootDir);
544 
545     /** copy an existing file to a new file
546      *  @param sourceFilename name of the existing file (including directory) to be copied.
547      *    This filename may contain wide characters if support enabled. Since there are various
548      *    constructors for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also
549      *    be passed directly to this parameter.
550      *  @param destFilename name of the new file (including directory) to be created as a copy.
551      *    This filename may contain wide characters if support enabled. Since there are various
552      *    constructors for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also
553      *    be passed directly to this parameter.
554      *  @return OFTrue if copying the file was successful, OFFalse otherwise. On most systems,
555      *    the 'errno' variable is also set to a system-specific error code in case of failure.
556      */
557     static OFBool copyFile(const OFFilename &sourceFilename,
558                            const OFFilename &destFilename);
559 
560     /** delete given file from filesystem
561      *  @param filename name of the file (including directory) to delete. This filename may
562      *    contain wide characters if support enabled. Since there are various constructors
563      *    for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also be passed
564      *    directly to this parameter.
565      *  @return OFTrue if deleting the file was successful, OFFalse otherwise. On most systems,
566      *    the 'errno' variable is also set to a system-specific error code in case of failure.
567      */
568     static OFBool deleteFile(const OFFilename &filename);
569 
570     /** change name of a given file
571      *  @param oldFilename current name of the file (including directory) to be renamed.
572      *    This filename may contain wide characters if support enabled. Since there are various
573      *    constructors for the OFFilename class, a "char *", "OFString" or "wchar_t *" can also
574      *    be passed directly to this parameter.
575      *  @param newFilename new name of the file (including directory), i.e.\ after renaming.
576      *    Should contain wide characters if and only if 'oldFilename' contains wide characters.
577      *  @return OFTrue if changing the name was successful, OFFalse otherwise. On most systems,
578      *    the 'errno' variable is also set to a system-specific error code in case of failure.
579      */
580     static OFBool renameFile(const OFFilename &oldFilename,
581                              const OFFilename &newFilename);
582 
583     /** determine size of given file (in bytes)
584      *  @param filename name of the file to be checked. This filename may contain wide
585      *    characters if support enabled. Since there are various constructors for the
586      *    OFFilename class, a "char *", "OFString" or "wchar_t *" can also be passed
587      *    directly to this parameter.
588      *  @return size of the file in bytes (0 in case of error)
589      */
590     static size_t getFileSize(const OFFilename &filename);
591 
592     // --- other functions ---
593 
594     /** check whether conversion to a HTML/XML mnenonic string is required.
595      *  This check can be performed before convertToMarkupStream() or convertToMarkupString()
596      *  is called in order to speed up the process in case the conversion is not required.
597      ** @param sourceString source string to be checked.  May contain one or more NULL bytes.
598      *  @param convertNonASCII convert non-ASCII characters (< #32 and >= #127) to numeric
599      *    value (@&@#nnn;) if OFTrue
600      *  @param maxLength maximum number of characters from the source string to be converted.
601      *    A value of 0 means all characters.
602      ** @return OFTrue if markup conversion is required, OFFalse otherwise
603      */
604     static OFBool checkForMarkupConversion(const OFString &sourceString,
605                                            const OFBool convertNonASCII = OFFalse,
606                                            const size_t maxLength = 0);
607 
608     /** convert character string to a HTML/XHTML/XML mnenonic stream.
609      *  Characters with special meaning for HTML/XHTML/XML (e.g. '<' and '&') are replaced by the
610      *  corresponding mnenonics (e.g. "&lt;" and "&amp;").  If flag 'convertNonASCII' is OFTrue,
611      *  all characters < #32 and >= #127 are also converted (useful if only HTML 3.2 is supported
612      *  which does not allow to specify the character set).  In HTML 3.2 mode, the quotation mark
613      *  (") is converted to "&#34;" instead of "&quot;" because the latter entity is not defined.
614      *  In HTML mode, the apostrophe sign (') is converted to "&#39;" instead of "&apos;" for the
615      *  same reason.
616      *  @note This method might create invalid character entity references, such as "&#27;" for ESC,
617      *    if contained in the 'sourceString'.  An XML document with such character entities cannot
618      *    be parsed by most XML parsers.  However, removing them from the output stream would also
619      *    be no option.
620      ** @param out stream used for the HTML/XHTML/XML mnenonic output
621      *  @param sourceString source string to be converted.  May contain one or more NULL bytes.
622      *  @param convertNonASCII convert non-ASCII characters (< # 32 and >= #127) to numeric value
623      *    (@&@#nnn;) if OFTrue.  This might lead to invalid XML character entity references.
624      *  @param markupMode convert to HTML, HTML 3.2, XHTML or XML markup.
625      *    LF and CR are encoded as "&#10;" and "&#13;" in XML mode, the flag 'newlineAllowed'
626      *    has no meaning in this case.
627      *  @param newlineAllowed optional flag indicating whether newlines are allowed or not.
628      *    If they are allowed, the text "<br>" (HTML) or "<br />" (XHTML) is used, "&para;"
629      *    otherwise.  The following combinations are accepted: LF, CR, LF CR, CF LF.
630      *  @param maxLength maximum number of characters from the source string to be converted.
631      *    A value of 0 means all characters.
632      ** @return status, always returns EC_Normal
633      */
634     static OFCondition convertToMarkupStream(STD_NAMESPACE ostream &out,
635                                              const OFString &sourceString,
636                                              const OFBool convertNonASCII = OFFalse,
637                                              const E_MarkupMode markupMode = MM_XML,
638                                              const OFBool newlineAllowed = OFFalse,
639                                              const size_t maxLength = 0);
640 
641     /** convert character string to a HTML/XHTML/XML mnenonic string.
642      *  Characters with special meaning for HTML/XHTML/XML (e.g. '<' and '&') are replaced by the
643      *  corresponding mnenonics (e.g. "&lt;" and "&amp;").  If flag 'convertNonASCII' is OFTrue,
644      *  all characters < #32 and >= #127 are also converted (useful if only HTML 3.2 is supported
645      *  which does not allow to specify the character set).  In HTML 3.2 mode, the quotation mark
646      *  (") is converted to "&#34;" instead of "&quot;" because the latter entity is not defined.
647      *  In HTML mode, the apostrophe sign (') is converted to "&#39;" instead of "&apos;" for the
648      *  same reason.
649      *  @note This method might create invalid character entity references, such as "&#27;" for ESC,
650      *    if contained in the 'sourceString'.  An XML document with such character entities cannot
651      *    be parsed by most XML parsers.  However, removing them from the 'markupString' would also
652      *    be no option.
653      ** @param sourceString source string to be converted.  May also contain one or more NULL bytes.
654      *  @param markupString reference to character string where the result should be stored
655      *  @param convertNonASCII convert non-ASCII characters (< # 32 and >= #127) to numeric value
656      *    (@&@#nnn;) if OFTrue.  This might lead to invalid XML character entity references.
657      *  @param markupMode convert to HTML, HTML 3.2, XHTML or XML markup string.
658      *    LF and CR are encoded as "@&@#10;" and "@&@#13;" in XML mode, the flag 'newlineAllowed'
659      *    has no meaning in this case.
660      *  @param newlineAllowed optional flag indicating whether newlines are allowed or not.
661      *    If they are allowed, the text "<br>" (HTML) or "<br />" (XHTML) is used, "&para;"
662      *    otherwise.  The following combinations are accepted: LF, CR, LF CR, CF LF.
663      *  @param maxLength maximum number of characters from the source string to be converted.
664      *    A value of 0 means all characters.
665      ** @return reference to resulting 'markupString' (might be empty if 'sourceString' was empty)
666      */
667     static const OFString &convertToMarkupString(const OFString &sourceString,
668                                                  OFString &markupString,
669                                                  const OFBool convertNonASCII = OFFalse,
670                                                  const E_MarkupMode markupMode = MM_XML,
671                                                  const OFBool newlineAllowed = OFFalse,
672                                                  const size_t maxLength = 0);
673 
674     /** check whether conversion to an octal format is required.
675      *  This check can be performed before convertToOctalStream() or convertToOctalString()
676      *  is called in order to speed up the process in case the conversion is not required.
677      ** @param sourceString source string to be checked.  May contain one or more NULL bytes.
678      *  @param maxLength maximum number of characters from the source string to be converted.
679      *    A value of 0 means all characters.
680      ** @return OFTrue if markup conversion is required, OFFalse otherwise
681      */
682     static OFBool checkForOctalConversion(const OFString &sourceString,
683                                           const size_t maxLength = 0);
684 
685     /** convert character string to an octal format stream.
686      *  All non-ASCII and control characters (code < #32 and >= #127) are converted to their
687      *  octal representation, i.e. to '\\ooo' where 'ooo' are the three octal digits of the
688      *  character.  All other characters are output as is.  See section 6.1.2.3 in DICOM PS 3.5.
689      ** @param out stream used for the output
690      *  @param sourceString source string to be converted.  May contain one or more NULL bytes.
691      *  @param maxLength maximum number of characters from the source string to be converted.
692      *    A value of 0 means all characters.
693      ** @return status, always returns EC_Normal
694      */
695     static OFCondition convertToOctalStream(STD_NAMESPACE ostream &out,
696                                             const OFString &sourceString,
697                                             const size_t maxLength = 0);
698 
699     /** convert character string to an octal format string.
700      *  All non-ASCII and control characters (code < #32 and >= #127) are converted to their
701      *  octal representation, i.e. to '\\ooo' where 'ooo' are the three octal digits of the
702      *  character.  All other characters are output as is.  See section 6.1.2.3 in DICOM PS 3.5.
703      ** @param sourceString source string to be converted.  May contain one or more NULL bytes.
704      *  @param octalString reference to character string where the result should be stored
705      *  @param maxLength maximum number of characters from the source string to be converted.
706      *    A value of 0 means all characters.
707      ** @return reference to resulting 'octalString' (might be empty if 'sourceString' was empty)
708      */
709     static const OFString &convertToOctalString(const OFString &sourceString,
710                                                 OFString &octalString,
711                                                 const size_t maxLength = 0);
712 
713     /** encode binary data according to "Base64" as described in RFC 2045 (MIME).
714      *  Basic algorithm: groups of 3 bytes from the binary input are coded as groups of 4 bytes in
715      *  the textual output.  The input data is 'padded' with zeros to create a length that is an
716      *  even multiple of 3.  A special character ('=') is used to denote padding so that the output
717      *  can be decoded back to its exact size.
718      *  If the input data is NULL an error code (EC_IllegalParameter) is returned.
719      ** @param out output stream used for the base64 encoded data
720      *  @param data buffer with binary data to be encoded (big endian required!)
721      *  @param length length of the input data buffer (in bytes)
722      *  @param width maximum number of characters per line in the output stream
723      *    (default: 0 = no line breaks, typical for MIME = 72)
724      ** @return status, EC_Normal if successful, an error code otherwise
725      */
726     static OFCondition encodeBase64(STD_NAMESPACE ostream &out,
727                                     const unsigned char *data,
728                                     const size_t length,
729                                     const size_t width = 0);
730 
731     /** encode binary data according to "Base64" as described in RFC 2045 (MIME).
732      *  Basic algorithm: groups of 3 bytes from the binary input are coded as groups of 4 bytes in
733      *  the textual output.  The input data is 'padded' with zeros to create a length that is an
734      *  even multiple of 3.  A special character ('=') is used to denote padding so that the output
735      *  can be decoded back to its exact size.
736      *  If the input data is NULL an empty string is returned.
737      ** @param data buffer with binary data to be encoded (big endian required!)
738      *  @param length length of the input data buffer (in bytes)
739      *  @param result reference to resulting string variable (Base64 encoded)
740      *  @param width maximum number of characters per line in the output string
741      *    (default: 0 = no line breaks, typical for MIME = 72)
742      ** @return reference to the resulting string
743      */
744     static const OFString &encodeBase64(const unsigned char *data,
745                                         const size_t length,
746                                         OFString &result,
747                                         const size_t width = 0);
748 
749     /** decode "Base64" encoded string.
750      *  Any character that does not belong to the Base64 alphabet (0..9, A..Z, a..z, + and /) is
751      *  ignored when decoding the input string.  This is especially true for line breaks which are
752      *  usually contained in MIME (RFC 2045) encoded streams (see above).  The first occurrence of
753      *  a '=' character is taken as evidence that the end of the data has been reached.
754      *  NB: The memory buffer in which the binary output is stored is allocated inside this function
755      *      and has to to be freed (using "delete[]") by the caller!  Do not pass a pointer to an
756      *      already allocated buffer to this function, the caller does not know the exact size anyway.
757      ** @param data Base64 encoded input data (possibly padded with '=' at the end)
758      *  @param result receives pointer to resulting buffer with binary data (big endian encoded)
759      ** @return length of the resulting binary data (0 if an error occurred, in this case the buffer
760      *    is deleted internally)
761      */
762     static size_t decodeBase64(const OFString &data,
763                                unsigned char *&result);
764 
765     /** converts a floating-point number from an ASCII
766      *  decimal representation to internal double-precision format.
767      *  Unlike the atof() function defined in Posix, this implementation
768      *  is not affected by a locale setting, the radix character is always
769      *  assumed to be '.'
770      *  This implementation does not set errno if the input cannot be parsed
771      *  and it does not implement special handling for overflow/underflow.
772      *  It does handle "NaN" and "Inf" (case insensitive; following
773      *  characters are ignore). A return code indicates whether or not
774      *  a successful conversion could be performed.
775      *  The precision of this implementation is limited to approx. 9
776      *  decimal digits.
777      *  @note The use of this implementation can be disabled by defining
778      *    the macro DISABLE_OFSTD_ATOF at compile time; in this case,
779      *    the locale dependent Posix implementation of sscanf is used and
780      *    the application is responsible for making sure that the Posix locale
781      *    is activated at all times.
782      *  @param s
783      *    A decimal ASCII floating-point number, optionally preceded by white
784      *    space. Must have form "-I.FE-X", where I is the integer part of the
785      *    mantissa, F is the fractional part of the mantissa, and X is the
786      *    exponent.  Either of the signs may be "+", "-", or omitted.  Either I
787      *    or F may be omitted, or both.  The decimal point isn't necessary
788      *    unless F is present. The "E" may actually be an "e".  E and X may both
789      *    be omitted (but not just one).
790      *  @param success pointer to return status code, may be NULL.
791      *    if present, a status code is stored in the variable pointed to by this
792      *    parameter.  The status is OFTrue if a conversion could be performed
793      *    and OFFalse if the string does not have the expected format.
794      *  @return
795      *    floating-point equivalent of string.
796      *    If a terminating character is found before any floating-point
797      *    digits, then zero is returned.
798      */
799      static double atof(const char *s,
800                         OFBool *success = NULL);
801 
802      /** formats a floating-point number into an ASCII string.
803       *  This function works similar to sprintf(), except that this
804       *  implementation is not affected by a locale setting.
805       *  The radix character is always '.'.
806       *  This implementation guarantees that the given string size
807       *  is always respected by using strlcpy to copy the formatted
808       *  string into the target buffer.
809       *  @note The use of this implementation can be disabled by defining
810       *    the macro DISABLE_OFSTD_FTOA at compile time; in this case,
811       *    the locale dependent Posix implementation of sprintf is used and
812       *    the application is responsible for making sure that the Posix locale
813       *    is activated at all times.
814       *  @param target pointer to target string buffer
815       *  @param targetSize size of target string buffer
816       *  @param value double value to be formatted
817       *  @param flags processing flags. Any of the flags defined below
818       *    can be combined by bit-wise or.
819       *  @param width width from format (%8d), or 0
820       *  @param precision precision from format (%.3d), or -1
821       */
822      static void ftoa(char *target,
823                       size_t targetSize,
824                       double value,
825                       unsigned int flags = 0,
826                       int width = 0,
827                       int precision = -1);
828 
829      /** @name ftoa() processing flags.
830       *  These flags can be combined by bit-wise or.
831       */
832      //@{
833 
834      /// Use %e or %E conversion format instead of %g or %G
835      static const unsigned int ftoa_format_e;
836 
837      /// Use %f or %F conversion format instead of %g or %G
838      static const unsigned int ftoa_format_f;
839 
840      /// Use %E, %F or %G conversion format instead of %e, %f or %g
841      static const unsigned int ftoa_uppercase;
842 
843      /** convert value to alternate form. The result will always contain
844       *  a decimal point, even if no digits follow the point. For g and G
845       *  conversions, trailing zeroes will not be removed from the result.
846       */
847      static const unsigned int ftoa_alternate;
848 
849      /// left-justify number be within the field
850      static const unsigned int ftoa_leftadj;
851 
852      /// pad with zeroes instead of blanks
853      static const unsigned int ftoa_zeropad;
854 
855      //@}
856 
857     /** makes the current process sleep until seconds seconds have
858      *  elapsed or a signal arrives which is not ignored
859      *  @param seconds number of seconds to sleep
860      *  @return zero if the requested time has elapsed, or the number of seconds
861      *    left to sleep
862      */
sleep(unsigned int seconds)863     static inline unsigned int sleep(unsigned int seconds)
864     {
865 #if defined(HAVE_SLEEP) && !defined(HAVE_WINDOWS_H)
866       // we only use this call if HAVE_WINDOWS_H is undefined because
867       // MinGW has sleep() but no prototype
868       return ::sleep(seconds);
869 #else
870       return my_sleep(seconds);
871 #endif
872     }
873 
874     /** makes the current process sleep until the given number of milliseconds
875      *  have elapsed or a signal which is not ignored arrives
876      *  @param millisecs number of milliseconds to sleep
877      */
878     static void milliSleep(unsigned int millisecs);
879 
880     /** Determines the identification of the running process.
881      *  @return the process ID of the currently running process.
882      */
883     static long getProcessID();
884 
885     /** check whether the addition of two 32-bit integers yields in an overflow
886      *  @param summand1 first integer value to be added
887      *  @param summand2 second integer value to be added
888      *  @return OFTrue if an overflow occurred during the addition, OFFalse otherwise
889      */
check32BitAddOverflow(const Uint32 summand1,const Uint32 summand2)890     static inline OFBool check32BitAddOverflow(const Uint32 summand1,
891                                                const Uint32 summand2)
892     {
893       return (0xffffffff - summand1 < summand2);
894     }
895 
896     /** check whether subtraction is safe (i.e.\ no underflow occurs) and if so,
897      *  perform it (i.e.\ compute minuend-subtrahend=difference). Only works for
898      *  unsigned types.
899      *  @param minuend number to subtract from
900      *  @param subtrahend number to subtract from minuend
901      *  @param difference difference, if subtraction is safe, otherwise the
902      *    parameter value is not touched by the function
903      *  @return OFTrue if subtraction is safe and could be performed, OFFalse
904      *   otherwise
905      */
906     template <typename T>
907     static OFBool
safeSubtract(T minuend,T subtrahend,T & difference)908     safeSubtract(T minuend, T subtrahend, T& difference)
909     {
910         assert(!OFnumeric_limits<T>::is_signed);
911         if (minuend < subtrahend) {
912             return OFFalse;
913         } else {
914             difference = minuend - subtrahend;
915             return OFTrue;
916         }
917     }
918 
919     /** check whether addition is safe (i.e.\ no overflow occurs) and if so,
920      *  perform it (i.e.\ compute a+b=sum). Only works for unsigned types.
921      *  @param a first number to add
922      *  @param b second number to add
923      *  @param sum resulting sum of both numbers, if addition is safe, otherwise
924      *    parameter value is not touched by the function
925      *  @return OFTrue if addition is safe and could be performed, OFFalse
926      *    otherwise
927      */
928     template <typename T>
929     static OFBool
safeAdd(T a,T b,T & sum)930     safeAdd(T a, T b, T& sum)
931     {
932         assert(!OFnumeric_limits<T>::is_signed);
933         if ((OFnumeric_limits<T>::max)() - a < b) {
934             return OFFalse;
935         } else {
936             sum = a + b;
937             return OFTrue;
938         }
939     }
940 
941     /** check whether multiplication is safe (i.e.\ no overflow occurs) and if so,
942      *  perform it (i.e.\ compute a*b=product). Only works for unsigned types.
943      *  @param a first number to multiply
944      *  @param b second number to multiply
945      *  @param product resulting product of both numbers, if multiplication is
946      *    safe, otherwise parameter value is not touched by the function
947      *  @return OFTrue if multiplication is safe and could be performed, OFFalse
948      *    otherwise
949      */
950     template <typename T>
safeMult(T a,T b,T & product)951     static OFBool safeMult(T a, T b, T& product)
952     {
953         assert(!OFnumeric_limits<T>::is_signed);
954         T x = a * b;
955         if (a != 0 && x / a != b) {
956             return OFFalse;
957         }
958         product = x;
959         return OFTrue;
960     }
961 
962 #ifdef DOXYGEN
963     /** checks if a string only contains valid decimal digits, i.e.\ 0-9.
964      *  @tparam Count the number of characters (bytes) to check.
965      *  @param string a pointer to a character array to check.
966      *  @return OFTrue if all characters are valid decimal digits, OFFalse
967      *    if at least one non-digit character is encountered.
968      */
969     template<size_t Count>
970     static OFBool checkDigits(const char* string);
971 
972     /** extracts digits from a string and converts them to the given integer
973      *  number type.
974      *  The result is similar to calling atoi, but extractDigits does not
975      *  verify all characters are digits and does not require zero terminated
976      *  strings. It is meant to be used in conjunction with
977      *  OFStandard::checkDigits(). extractDigits does not handle sign
978      *  characters ('+' and '-').
979      *  @tparam T the type of the resulting value, e.g.\ unsigned int. Must
980      *    be a valid integer type, i.e.\ OFnumeric_limits<T>::is_integer must
981      *    be OFTrue.
982      *  @tparam Count the number of digits to extract. Must be greater zero
983      *    and less or equal to OFnumeric_limits<T>::digits10
984      *  @param string a pointer to a character array to extract digits from.
985      *  @return a value of type T that is equivalent to the number represented
986      *    by the digits.
987      *  @details
988      *  @warning The results are unspecified if the given string contains
989      *    non-digit characters.
990      */
991     template<typename T,size_t Count>
992     static T extractDigits(const char*);
993 #else
994     template<size_t Count>
995     static OFTypename OFenable_if<!Count,OFBool>::type
checkDigits(const char *)996     checkDigits(const char* /*string*/)
997     {
998         return OFTrue;
999     }
1000 
1001     template<size_t Count>
1002     static OFTypename OFenable_if<!!Count,OFBool>::type
checkDigits(const char * string)1003     checkDigits(const char* string)
1004     {
1005         return *string >= '0' && *string <= '9' &&
1006             checkDigits<Count-1>( string + 1 );
1007     }
1008 
1009     template<typename T,size_t Count>
1010     static OFTypename OFenable_if
1011     <
1012         OFnumeric_limits<T>::is_integer && Count == 1,
1013         T
extractDigits(const char * string)1014     >::type extractDigits(const char* string)
1015     {
1016         return *string - '0';
1017     }
1018 
1019     template<typename T,size_t Count>
1020     static OFTypename OFenable_if
1021     <
1022         OFnumeric_limits<T>::is_integer && ( Count > 1 ) &&
1023              OFnumeric_limits<T>::digits10 >= Count,
1024         T
1025     >::type extractDigits(const char* string)
1026     {
1027         return extractDigits<T,Count-1>( string ) * 10
1028             + extractDigits<T,1>( string + Count - 1 );
1029     }
1030 #endif
1031 
1032     /** An utility function that finds a substring within a string that does
1033      *  not contain leading and trailing spaces and null bytes, effectively
1034      *  trimming the string without unnecessary copies.
1035      *  @param pBegin a reference to a pointer to the beginning of the string.
1036      *  @param pEnd a reference to a pointer to the end of the string (the
1037      *    first byte behind the string).
1038      *  @details
1039      *  @pre pBegin <= pEnd
1040      *  @details
1041      *  trimString() increments pBegin and decrements pEnd until either both
1042      *  point to a non-null and non-space character (the position after it in
1043      *  case of pEnd) or both become equal (in case the string only contains
1044      *  spaces and null bytes).
1045      */
1046     static void trimString( const char*& pBegin, const char*& pEnd );
1047 
1048     /** An utility function that finds a substring within a string that does
1049      *  not contain leading and trailing spaces and null bytes, effectively
1050      *  trimming the string without unnecessary copies.
1051      *  @param str a reference to a pointer to the beginning of the string.
1052      *  @param size a reference to a size_t variable containing the number of
1053      *    bytes in the string referenced by str.
1054      *  @details
1055      *  This overload is implemented using the other overload of the function
1056      *  operating on two character pointers.
1057      */
1058     static void trimString( const char*& str, size_t& size );
1059 
1060     /** This function performs a reverse DNS lookup of a hostname.
1061      *  The parameters are identical to those passed to gethostbyaddr().
1062      *  If the lookup fails, an empty string is returned.
1063      *  @param addr IP address, actually a pointer to a struct in_addr or a struct in6_addr object
1064      *  @param len length of the struct pointed to by addr
1065      *  @param type address type, either AF_INET or AF_INET6
1066      *  @return hostname for the IP address
1067      */
1068     static OFString getHostnameByAddress(const char* addr, int len, int type);
1069 
1070     /** This function performs a DNS lookup of an IP address based on a hostname.
1071      *  If a DNS lookup yields multiple IP addresses, only the first one is returned.
1072      *  @param name hostname
1073      *  @param result a OFSockAddr instance in which the result is stored
1074      */
1075     static void getAddressByHostname(const char *name, OFSockAddr& result);
1076 
1077     /** Thread-safe version of getgrnam.
1078      *  @param name the group name.
1079      *  @return a OFStandard::OFGroup object.
1080      */
1081     static OFGroup getGrNam( const char* name );
1082 
1083     /** Thread-safe version of getpwnam.
1084      *  @param name the username.
1085      *  @return a OFStandard::OFPasswd object.
1086      */
1087     static OFPasswd getPwNam( const char* name );
1088 
1089     /** On Posix-like platform, this method executes setuid(getuid()),
1090      *  which causes the application to revert from root privileges to
1091      *  those of the calling user when the program is installed as
1092      *  setuid root. DCMTK command line tools that open a socket for
1093      *  incoming DICOM network connections will call this method immediately
1094      *  after opening the socket. Since DICOM by default operates on
1095      *  port 104, which on Posix platforms requires root privileges to open,
1096      *  this ensures that the socket can be opened, yet operation continues
1097      *  with the (hopefully) limited rights of the calling user.
1098      *  On non-Posix platforms, this method does nothing and returns success.
1099      *
1100      *  @return success or failure. This method can fail if the kernel has
1101      *    been configured to only permit a certain number of processes
1102      *    to be created for each user, and the calling user already has the
1103      *    maximum number of processes running. In this case, the application
1104      *    should terminate since otherwise it would continue to run with
1105      *    full root privileges.
1106      */
1107     static OFCondition dropPrivileges();
1108 
1109     /** Retrieve the name of the user that started the current process.
1110      *  @return the user name as an OFString value.
1111      */
1112     static OFString getUserName();
1113 
1114     /** Retrieve the local domain name, e. g. 'localhost'.
1115      *  @return the host name as an OFString value.
1116      */
1117     static OFString getHostName();
1118 
1119     /** Initialize the network API (if necessary), e.g.\ Winsock.
1120      *  Calls the appropriate network initialization routines for the current
1121      *  platform, e.g.\ WSAStartup().
1122      *  @note This function must be called by an application before any
1123      *    network related functions are used, be it listening on a socket or
1124      *    just retrieving the current host name. Not all platforms require
1125      *    calling a network initialization routine, therefore testing if it
1126      *    works to determine if this method must be called is not an option
1127      *    -- just always ensure to call it at program startup if the
1128      *    application does something network related!
1129      */
1130     static void initializeNetwork();
1131 
1132     /** Shutdown the network API (if necessary), e.g.\ Winsock.
1133      *  Calls the appropriate network shutdown routines to free used resources
1134      *  (e.g.\ WSACleanup()).
1135      */
1136     static void shutdownNetwork();
1137 
1138     /** Retrieve the last operating system error code that was emitted in the
1139      *  calling thread.
1140      *  The current implementation uses errno on POSIX-like platforms and
1141      *  GetLastError() on Windows.
1142      *  @return the last error code as OFerror_code object.
1143      */
1144     static OFerror_code getLastSystemErrorCode();
1145 
1146     /** Retrieve the last network specific error code that was emitted in the
1147      *  calling thread.
1148      *  The current implementation uses errno on POSIX-like platforms and
1149      *  WSAGetLastError() on Windows.
1150      *  @return the last error code as OFerror_code object.
1151      */
1152     static OFerror_code getLastNetworkErrorCode();
1153 
1154  private:
1155 
1156     /** private implementation of strlcpy. Called when strlcpy
1157      *  is not available in the standard library.
1158      *  @param dst destination buffer of size siz, must not be NULL
1159      *  @param src source string, must not be NULL
1160      *  @param siz size of destination buffer
1161      *  @return the total length of the string the function tried to
1162      *    create, i.e. strlen(src)
1163      */
1164     static size_t my_strlcpy(char *dst, const char *src, size_t siz);
1165 
1166     /** private implementation of strlcat. Called when strlcat
1167      *  is not available in the standard library.
1168      *  @param dst destination buffer of size siz, must not be NULL
1169      *  @param src source string, must not be NULL
1170      *  @param siz size of destination buffer
1171      *  @return the total length of the string the function tried to
1172      *    create, i.e. the initial length of dst plus the length of src
1173      */
1174     static size_t my_strlcat(char *dst, const char *src, size_t siz);
1175 
1176     /** makes the current process sleep until seconds seconds have
1177      *  elapsed or a signal arrives which is not ignored
1178      *  @param seconds number of seconds to sleep
1179      *  @return zero if the requested time has elapsed, or the number of seconds left to sleep
1180      */
1181     static unsigned int my_sleep(unsigned int seconds);
1182 };
1183 
1184 /** simple but thread safe random number generator. The interface is derived
1185  *  from the Posix rand_r function. Uses a multiplicative congruential
1186  *  random-number generator with period 2**32 that returns successive
1187  *  pseudo-random numbers in the range of 0 to OFrandr_max (0x7fffffff).
1188  *  @param seed pointer to seed of random number generator, must not be NULL.
1189  *  @return pseudo-random number in the range of 0 to OFrandr_max.
1190  */
1191 int DCMTK_OFSTD_EXPORT OFrand_r(unsigned int &seed);
1192 
1193 /// maximum value that can be returned by OFrand_r()
1194 extern DCMTK_OFSTD_EXPORT const unsigned int OFrandr_max;
1195 
1196 #endif
1197