1 /* 2 * 3 * Copyright (C) 2000-2002, OFFIS 4 * 5 * This software and supporting documentation were developed by 6 * 7 * Kuratorium OFFIS e.V. 8 * Healthcare Information and Communication Systems 9 * Escherweg 2 10 * D-26121 Oldenburg, Germany 11 * 12 * THIS SOFTWARE IS MADE AVAILABLE, AS IS, AND OFFIS MAKES NO WARRANTY 13 * REGARDING THE SOFTWARE, ITS PERFORMANCE, ITS MERCHANTABILITY OR 14 * FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES OR 15 * ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND 16 * PERFORMANCE OF THE SOFTWARE IS WITH THE USER. 17 * 18 * Module: ofstd 19 * 20 * Author: Joerg Riesmeier, Marco Eichelberg 21 * 22 * Purpose: Class for various helper functions 23 * 24 */ 25 26 27 #ifndef __OFSTD_H 28 #define __OFSTD_H 29 30 #include "osconfig.h" 31 #include "ofstring.h" /* for class OFString */ 32 33 #define INCLUDE_CSTRING 34 #define INCLUDE_CSTDIO 35 #include "ofstdinc.h" 36 37 BEGIN_EXTERN_C 38 #ifdef HAVE_SYS_TYPES_H 39 #include <sys/types.h> /* for size_t */ 40 #endif 41 END_EXTERN_C 42 43 44 /*---------------------* 45 * class declaration * 46 *---------------------*/ 47 48 /** A class for various helper functions. 49 * This class is used to comprise a number of "global" helper functions. 50 */ 51 class OFStandard 52 { 53 public: 54 55 // --- string functions --- 56 57 /** This function copies up to size - 1 characters from the NUL- 58 * terminated string src to dst, NUL-terminating the result. It is 59 * designed to be a safer, more consistent, and less error-prone 60 * replacement for strncpy(3). strlcpy takes the full size of the 61 * buffer (not just the length) and guarantees to NUL-terminate the 62 * result (as long as size is larger than 0). Note that you should 63 * include a byte for the NUL in size. Also note that strlcpy only 64 * operates on true C strings, i. e. src must be NUL-terminated. 65 * @param dst destination buffer of size siz, must not be NULL 66 * @param src source string, must not be NULL 67 * @param siz size of destination buffer 68 * @return the total length of the string the function tried to 69 * create, i.e. strlen(src). While this may seem somewhat 70 * confusing it was done to make truncation detection simple. 71 */ strlcpy(char * dst,const char * src,size_t siz)72 static inline size_t strlcpy(char *dst, const char *src, size_t siz) 73 { 74 #ifdef HAVE_STRLCPY 75 return ::strlcpy(dst, src, siz); 76 #else 77 return my_strlcpy(dst, src, siz); 78 #endif 79 } 80 81 /** This function appends the NUL-terminated string src to the end of 82 * dst. It will append at most size - strlen(dst) - 1 bytes, NUL- 83 * terminating the result. It is designed to be a safer, more 84 * consistent, and less error-prone replacement for strncat(3). 85 * strlcat takes the full size of the buffer (not just the length) and 86 * guarantees to NUL-terminate the result (as long as size is larger 87 * than 0). Note that you should include a byte for the NUL in size. 88 * Also note that strlcat only operates on true C strings, i. e. dst 89 * and src must be NUL-terminated. 90 * @param dst destination buffer of size siz, must not be NULL 91 * @param src source string, must not be NULL 92 * @param siz size of destination buffer 93 * @return the total length of the string the function tried to 94 * create, i.e. the initial length of dst plus the length of src. 95 * While this may seem somewhat confusing it was done to make 96 * truncation detection simple. 97 */ strlcat(char * dst,const char * src,size_t siz)98 static inline size_t strlcat(char *dst, const char *src, size_t siz) 99 { 100 #ifdef HAVE_STRLCAT 101 return ::strlcat(dst, src, siz); 102 #else 103 return my_strlcat(dst, src, siz); 104 #endif 105 } 106 107 // --- file system functions --- 108 109 /** check whether the given path exists. 110 * This function does not distinguish files from directories (use 'fileExists()' 111 * or 'directoryExists()' if required). 112 * @param pathName name of the path to be checked 113 * @return OFTrue if path exists, OFFalse otherwise 114 */ 115 static OFBool pathExists(const OFString &pathName); 116 117 /** check whether the given file exists. 118 * This function also checks that the specified path points to file and not to 119 * a directory (or the like). 120 * @param fileName name of the file to be checked 121 * @return OFTrue if file exists, OFFalse otherwise 122 */ 123 static OFBool fileExists(const OFString &fileName); 124 125 /** check whether the given directory exists. 126 * This function also checks that the specified path points to directory and 127 * not to a file (or the like). 128 * @param dirName name of the directory to be checked 129 * @return OFTrue if directory exists, OFFalse otherwise 130 */ 131 static OFBool dirExists(const OFString &dirName); 132 133 /** check whether the given path is readable. 134 * This function works for both files and directories. 135 * @param pathName name of the path to be checked 136 * @return OFTrue if path is readable, OFFalse otherwise 137 */ 138 static OFBool isReadable(const OFString &pathName); 139 140 /** check whether the given path is writeable. 141 * This function works for both files and directories. 142 * @param pathName name of the path to be checked 143 * @return OFTrue if path is writeable, OFFalse otherwise 144 */ 145 static OFBool isWriteable(const OFString &pathName); 146 147 /** normalize the given directory name. 148 * Removes trailing path separators from the directory name. If the resulting 149 * directory name is an empty string and the flag 'allowEmptyDirName' is OFFalse 150 * the directory name is to "." (current directory). 151 * @param result string variable in which the resulting directory name is stored 152 * @param dirName directory name to be normalized 153 * @param allowEmptyDirName flag indicating whether an empty directory name is allowed 154 * @return reference to the resulting directory name (same as 'result') 155 */ 156 static OFString &normalizeDirName(OFString &result, 157 const OFString &dirName, 158 const OFBool allowEmptyDirName = OFFalse); 159 160 /** combine the given directory and file name. 161 * Normalizes the directory name and appends the file name (with a path separator) 162 * if not empty. If both 'dirName' and 'fileName' are empty strings and the flag 163 * 'allowEmptyDirName' is OFFalse the resulting path name is set "." (current 164 * directory). 165 * NB: This function neither checks whether the given 'dirName' exists nor whether 166 * the resulting path name points to a valid or existing file name. 167 * @param result string variable in which the resulting path name is stored 168 * @param dirName directory name to be combined with the file name 169 * @param fileName file name to be combined with the directory name 170 * @param allowEmptyDirName flag indicating whether an empty directory name is allowed 171 * @return reference to the resulting path name (same as 'result') 172 */ 173 static OFString &combineDirAndFilename(OFString &result, 174 const OFString &dirName, 175 const OFString &fileName, 176 const OFBool allowEmptyDirName = OFFalse); 177 178 // --- other functions --- 179 180 /** convert character string to HTML/XML mnenonic string. 181 * Characters with special meaning for HTML/XML (e.g. '<' and '&') are replace by the 182 * corresponding mnenonics (e.g. "<" and "&"). If flag 'convertNonASCII' is OFTrue 183 * all characters > #127 are also converted (useful if only HTML 3.2 is supported which does 184 * not allow to specify the character set). 185 ** @param sourceString source string to be converted 186 * @param markupString reference to character string where the result should be stored 187 * @param convertNonASCII convert non-ASCII characters (> #127) to numeric value (&#nnn;) 188 * if OFTrue 189 * @param xmlMode convert to XML markup string if OFTrue, HTML string otherwise. 190 * Newlines are always encoded as "¶" in XML mode, the flag 'newlineAllowed' has no 191 * meaning in this case. 192 * @param newlineAllowed optional flag indicating whether newlines are allowed or not. 193 * If they are allowed the text "<br>" is used, "¶" otherwise. The following 194 * combinations are accepted: LF, CR, LF CR, CF LF. 195 ** @return reference to resulting 'markupString' (might be empty if 'sourceString' was empty) 196 */ 197 static const OFString &convertToMarkupString(const OFString &sourceString, 198 OFString &markupString, 199 const OFBool convertNonASCII = OFFalse, 200 const OFBool xmlMode = OFTrue, 201 const OFBool newlineAllowed = OFFalse); 202 203 /** encode binary data according to "Base64" as described in RFC 2045 (MIME). 204 * Basic algorithm: groups of 3 bytes from the binary input are coded as groups of 4 bytes in 205 * the textual output. The input data is 'padded' with zeros to create a length that is an 206 * even multiple of 3. A special character ('=') is used to denote padding so that the output 207 * can be decoded back to its exact size. 208 * If the input data is NULL an empty string is returned. 209 ** @param data buffer with binary data to be encoded (big endian required!) 210 * @param length length of the input data buffer (in bytes) 211 * @param result reference to resulting string variable (Base64 encoded) 212 * @param width maximum number of characters per line in the output string 213 * (default: 0 = no line breaks, typical for MIME = 72) 214 ** @return reference to the resulting string 215 */ 216 static const OFString &encodeBase64(const unsigned char *data, 217 const size_t length, 218 OFString &result, 219 const size_t width = 0); 220 221 /** decode "Base64" encoded string. 222 * Any character that does not belong to the Base64 alphabet (0..9, A..Z, a..z, + and /) is 223 * ignored when decoding the input string. This is especially true for line breaks which are 224 * usually contained in MIME (RFC 2045) encoded streams (see above). The first occurrence of 225 * a '=' character is taken as evidence that the end of the data has been reached. 226 * NB: The memory buffer in which the binary output is stored is allocated inside this function 227 * and has to to be freed (using "delete[]") by the caller! Do not pass a pointer to an 228 * already allocated buffer to this function, the caller does not know the exact size anyway. 229 ** @param data Base64 encoded input data (possibly padded with '=' at the end) 230 * @param result receives pointer to resulting buffer with binary data (big endian encoded) 231 ** @return length of the resulting binary data (0 if an error occurred, in this case the buffer 232 * is deleted internally) 233 */ 234 static size_t decodeBase64(const OFString &data, 235 unsigned char *&result); 236 237 /** converts a floating-point number from an ASCII 238 * decimal representation to internal double-precision format. 239 * Unlike the std::stod() function defined in Posix, this implementation 240 * is not affected by a locale setting, the radix character is always 241 * assumed to be '.' 242 * This implementation does not set errno if the input cannot be parsed 243 * and it does not implement special handling for overflow/underflow 244 * or NaN values. However, a return code indicates whether or not 245 * a successful conversion could be performed. 246 * The precision of this implementation is limited to approx. 9 247 * decimal digits. 248 * The use of this implementation can be disabled by defining 249 * the macro DISABLE_OFSTD_ATOF at compile time; in this case, 250 * the locale dependent Posix implementation of sscanf is used and 251 * the application is responsible for making sure that the Posix locale 252 * is activated at all times. 253 * 254 * @param s 255 * A decimal ASCII floating-point number, optionally preceded by white 256 * space. Must have form "-I.FE-X", where I is the integer part of the 257 * mantissa, F is the fractional part of the mantissa, and X is the 258 * exponent. Either of the signs may be "+", "-", or omitted. Either I 259 * or F may be omitted, or both. The decimal point isn't necessary 260 * unless F is present. The "E" may actually be an "e". E and X may both 261 * be omitted (but not just one). 262 * @param success pointer to return status code, may be NULL. 263 * if present, a status code is stored in the variable pointed to by this 264 * parameter. The status is OFTrue if a conversion could be performed 265 * and OFFalse if the string does not have the expected format. 266 * @return 267 * floating-point equivalent of string. 268 * If a terminating character is found before any floating-point 269 * digits, then zero is returned. 270 */ 271 static double atof(const char *s, 272 OFBool *success = NULL); 273 274 /** formats a floating-point number into an ASCII string. 275 * This function works similar to sprintf(), except that this 276 * implementation is not affected by a locale setting. 277 * The radix character is always '.'. 278 * 279 * This implementation guarantees that the given string size 280 * is always respected by using strlcpy to copy the formatted 281 * string into the target buffer. 282 * 283 * The use of this implementation can be disabled by defining 284 * the macro DISABLE_OFSTD_FTOA at compile time; in this case, 285 * the locale dependent Posix implementation of sprintf is used and 286 * the application is responsible for making sure that the Posix locale 287 * is activated at all times. 288 * 289 * @param target pointer to target string buffer 290 * @param siz size of target string buffer 291 * @param val double value to be formatted 292 * @param flags processing flags. Any of the flags defined below 293 * can be combined by bit-wise or. 294 * @param width width from format (%8d), or 0 295 * @param precision precision from format (%.3d), or -1 296 */ 297 static void ftoa(char *target, 298 size_t targetSize, 299 double value, 300 unsigned int flags = 0, 301 int width = 0, 302 int precision = -1); 303 304 /** @name ftoa() processing flags. 305 * These flags can be combined by bit-wise or. 306 */ 307 //@{ 308 309 /// Use %e or %E conversion format instead of %g or %G 310 static const unsigned int ftoa_format_e; 311 312 /// Use %f or %F conversion format instead of %g or %G 313 static const unsigned int ftoa_format_f; 314 315 /// Use %E, %F or %G conversion format instead of %e, %f or %g 316 static const unsigned int ftoa_uppercase; 317 318 /** convert value to alternate form. The result will always contain 319 * a decimal point, even if no digits follow the point. For g and G 320 * conversions, trailing zeroes will not be removed from the result. 321 */ 322 static const unsigned int ftoa_alternate; 323 324 /// left-justify number be within the field 325 static const unsigned int ftoa_leftadj; 326 327 /// pad with zeroes instead of blanks 328 static const unsigned int ftoa_zeropad; 329 330 //@} 331 332 /** Checks if a given string consists only of characters which are specified in a 333 * given charset. Note that in case one of the parameters equals NULL, OFTrue will 334 * be returned. 335 * @param str String which shall be checked. 336 * @param charset Possible character set for s. 337 * @return OFTrue if the given string consists only of characters which are specified 338 * in the given charset; OFFalse otherwise. 339 */ 340 static OFBool stringMatchesCharacterSet( const char *str, const char *charset ); 341 342 private: 343 344 /** private implementation of strlcpy. Called when strlcpy 345 * is not available in the standard library. 346 * @param dst destination buffer of size siz, must not be NULL 347 * @param src source string, must not be NULL 348 * @param siz size of destination buffer 349 * @return the total length of the string the function tried to 350 * create, i.e. strlen(src). 351 */ 352 static size_t my_strlcpy(char *dst, const char *src, size_t siz); 353 354 /** private implementation of strlcat. Called when strlcat 355 * is not available in the standard library. 356 * @param dst destination buffer of size siz, must not be NULL 357 * @param src source string, must not be NULL 358 * @param siz size of destination buffer 359 * @return the total length of the string the function tried to 360 * create, i.e. the initial length of dst plus the length of src. 361 */ 362 static size_t my_strlcat(char *dst, const char *src, size_t siz); 363 }; 364 365 366 #endif 367