    //------------------------------------------------------------------------------
    // emStd2.h
    //
    // Copyright (C) 2004-2011,2014-2015 Oliver Hamann.
    //
    // Homepage: http://eaglemode.sourceforge.net/
    //
    // This program is free software: you can redistribute it and/or modify it under
    // the terms of the GNU General Public License version 3 as published by the
    // Free Software Foundation.
    //
    // This program is distributed in the hope that it will be useful, but WITHOUT
    // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
    // more details.
    //
    // You should have received a copy of the GNU General Public License version 3
    // along with this program. If not, see <http://www.gnu.org/licenses/>.
    //------------------------------------------------------------------------------

    #ifndef emStd2_h
    #define emStd2_h

    #include <sys/stat.h>

    #ifndef emArray_h
    #include <emCore/emArray.h>
    #endif

    #ifndef emString_h
    #include <emCore/emString.h>
    #endif

    //==============================================================================
    //=========================== Host, user, process id ===========================
    //==============================================================================

    emString emGetHostName();
            // Get the name of the computer.

    emString emGetUserName();
            // Get the name of the user.

    int emGetProcessId();
            // Get the identification number of the process.

    //==============================================================================
    //=============================== Time functions ===============================
    //==============================================================================

    void emSleepMS(int millisecs);
            // Sleep for the given number of milliseconds. Less or equal zero means
            // to yield the CPU to another process.

    emUInt64 emGetClockMS();
            // Get a system clock time in milliseconds. It starts anywhere, but it
            // should never overflow.

    emUInt64 emGetCPUTSC();
            // Get the state of the time stamp counter (TSC) of the CPU.
            // IMPORTANT: This only works with certain compiler and hardware.
            // Use for debugging/development only.

    //==============================================================================
    //================================ Error texts =================================
    //==============================================================================

    emString emGetErrorText(int errorNumber);
            // This is like the C function strerror, but it is thread-safe, and on
            // Windows it also supports error codes returned by GetLastError.

    //==============================================================================
    //============================ Files & directories =============================
    //==============================================================================

    // em_stat and em_lstat are like stat and lstat from sys/stat.h, but with 64-bit
    // file size field if possible.
    #if defined(__linux__) && !defined(__SUNPRO_CC)
    #       define em_stat stat64
    #       define em_lstat lstat64
    #elif defined(_WIN32)
    #       if defined(_MSC_VER) || defined(__GNUC__) || defined(__WATCOMC__)
    #               define em_stat _stati64
    #       else
    #               define em_stat stat
    #       endif
    #       define em_lstat em_stat
    #else
    #       define em_stat stat
    #       define em_lstat lstat
    #endif

    emString emGetParentPath(const char * path);
            // Get the parent path of a path.
            // Examples:
            //  "" => ""
            //  "/" => "/"
            //  "/x" => "/"
            //  "/x/y" => "/x"
            //  "/x/y///" => "/x"

    emString emGetChildPath(const char * path, const char * name);
            // Join a path and a name.
            // Examples:
            //  "/x/y", "z" => "x/y/z"
            //  "/x/y/", "z" => "x/y/z"

    emString emGetAbsolutePath(const emString & path, const char * cwd=NULL);
            // Get the absolute path of a path. Symbolic links are not resolved. The
            // argument cwd can be used to simulate another current working
            // directory.

    const char * emGetNameInPath(const char * path);
            // Return a pointer to the last name in a path (similar to basename).

    const char * emGetExtensionInPath(const char * path);
            // Return a pointer to the extension including the dot of the last name
            // in a path.

    bool emIsExistingPath(const char * path);
    bool emIsReadablePath(const char * path);
    bool emIsWritablePath(const char * path);
    bool emIsDirectory(const char * path);
    bool emIsRegularFile(const char * path);
    bool emIsSymLinkPath(const char * path);
    bool emIsHiddenPath(const char * path);
            // Ask whether the given file path exists, whether it is readable and so
            // on.

    emUInt64 emTryGetFileSize(const char * path) throw(emException);
            // Get the size of a file.

    time_t emTryGetFileTime(const char * path) throw(emException);
            // Get the last modification time of a file.

    emString emGetCurrentDirectory();
            // Get the absolute path of the current working directory.

    typedef void * emDirHandle;
    emDirHandle emTryOpenDir(const char * path) throw(emException);
    emString emTryReadDir(emDirHandle dirHandle) throw(emException);
    void emCloseDir(emDirHandle dirHandle);
            // Read a directory step by step. An empty string indicates the end.

    emArray<emString> emTryLoadDir(const char * path) throw(emException);
            // Read a directory at once.

    emArray<char> emTryLoadFile(const char * path) throw(emException);
    void emTrySaveFile(const char * path,
                       const char * data, int len) throw(emException);
    void emTrySaveFile(const char * path,
                       const emArray<char> & data) throw(emException);
            // Read or write a file at once.

    void emTryMakeDirectories(const char * path, int mode=0777) throw(emException);
            // Create a directory and its ancestors, as far as they do not exist.
            // On Windows, the mode argument is ignored.

    void emTryRemoveFileOrTree(const char * path, bool force=false) throw(emException);
            // Delete a file or a directory recursively. force=true means to defeat
            // file permissions if possible.

    void emTryCopyFileOrTree(const char * targetPath,
                             const char * sourcePath) throw(emException);
            // Copy a file or a directory recursively. This does not copy any file
            // attributes (maybe a future version will do so).

    //==============================================================================
    //=========================== Dynamic link libraries ===========================
    //==============================================================================

    typedef void * emLibHandle;
            // Data type for a handle on an opened dynamic library.

    emLibHandle emTryOpenLib(const char * libName, bool isFilename) throw(emException);
            // Open a dynamic library.
            // Arguments:
            //   libName    - Name of the dynamic library.
            //   isFilename - false if libName is just a pure name, which has to be
            //                extended for making a file name (e.g. "Test" =>
            //                "libTest.so" or "Test.dll"). true if the name is
            //                already a file name or a file path.
            // Returns:
            //   An abstract handle for the opened library.

    void * emTryResolveSymbolFromLib(emLibHandle handle,
                                     const char * symbol) throw(emException);
            // Get the address of a symbol in a dynamic library.
            // Hint: C++ symbols have a compiler specific encoding. Best is to use
            // C symbols only.

    void emCloseLib(emLibHandle handle);
            // Close a dynamic library.

    void * emTryResolveSymbol(const char * libName, bool isFilename,
                              const char * symbol) throw(emException);
            // Similar to emTryOpenLib plus emTryResolveSymbolFromLib, but the
            // library is never closed.

    //==============================================================================
    //=========================== Pseudo random numbers ============================
    //==============================================================================

    int          emGetIntRandom   (int          minimum, int          maximum);
    unsigned int emGetUIntRandom  (unsigned int minimum, unsigned int maximum);
    emInt64      emGetInt64Random (emInt64      minimum, emInt64      maximum);
    emUInt64     emGetUInt64Random(emUInt64     minimum, emUInt64     maximum);
    double       emGetDblRandom   (double       minimum, double       maximum);
            // Get a pseudo random number within the given range.
            // Cryptographically, this is absolutely not secure.

    //==============================================================================
    //========================== Checksums and hash codes ==========================
    //==============================================================================

    emUInt32 emCalcAdler32(const char * src, int srcLen, emUInt32 start=1);
    emUInt32 emCalcCRC32(const char * src, int srcLen, emUInt32 start=0);
    emUInt64 emCalcCRC64(const char * src, int srcLen, emUInt64 start=0);
            // Calculate an Adler-32, CRC-32 or CRC-64 "checksum" from some data.
            // Cryptographically, this is absolutely not secure.
            // Arguments:
            //   src     - Pointer to source data.
            //   srcLen  - Number of bytes in the source.
            //   start   - Start value (could be the result from a previous call).
            // Returns:
            //   The CRC value.

    int emCalcHashCode(const char * str, int start=0);
            // Calculate another kind of "checksum" from a string (simple & fast).
            // Cryptographically, this is absolutely not secure.
            // Arguments:
            //   src     - The string.
            //   start   - Start value (could be the result from a previous call).
            // Returns:
            //   The hash code.

    emString emCalcHashName(const char * src, int srcLen, int hashLen);
            // Calculate an any-length hash code ("checksum") from some data. The
            // result is a character string consisting of letters and digits. It's
            // okay to ignore letter case in comparisons. Cryptographically, this is
            // absolutely not secure.
            // Arguments:
            //   src     - Pointer to source data.
            //   srcLen  - Number of bytes in the source.
            //   hashLen - Length of the resulting hash name.
            // Returns:
            //   The hash name. It has hashLen characters and consists of
            //   letters (A-Z) and digits (0-9) only.

    #endif