summaryrefslogtreecommitdiff
path: root/modules/hdf5/src/cpp/H5Exception.hxx
blob: b281ad998a582900ce9a3582a6c96ddcace6e76f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
 *
 * This file must be used under the terms of the CeCILL.
 * This source file is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at
 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
 *
 */

#ifndef __H5EXCEPTION_HXX__
#define __H5EXCEPTION_HXX__

extern "C"
{
#include "localization.h"
#include "backtrace_print.h"
}

#include "HDF5Objects.h"

#include <cstdlib>
#include <exception>
#include <sstream>
#include <string>
#include <cstdio>
#include <stdarg.h>

#define BUFFER_SIZE 1024

namespace org_modules_hdf5
{
class H5Exception : public std::exception
{
    std::string message;
    std::string file;
    int line;

public :

    H5Exception(const int _line, const char * _file, std::string _message, ...) : message(""), file(_file), line(_line)
    {
        char str[BUFFER_SIZE];
        va_list args;

        va_start(args, _message);
        vsnprintf(str, BUFFER_SIZE, _message.c_str(), args);
        va_end(args);

        message = getDescription(std::string(str));
    }

    H5Exception(const int _line, const char * _file, const char * _message, ...) : message(""), file(_file), line(_line)
    {
        char str[BUFFER_SIZE];
        va_list args;

        va_start(args, _message);
        vsnprintf(str, BUFFER_SIZE, _message, args);
        va_end(args);

        message = getDescription(std::string(str));
    }

    virtual ~H5Exception() throw() { }

    virtual const char * what() const throw()
    {
        return message.c_str();
    }

private:

    static std::string getHDF5ErrorMsg()
    {
        hid_t stid = H5Eget_current_stack();
        if (stid < 0)
        {
            return std::string(_("Cannot get the current stack of errors."));
        }

        ssize_t stackSize = H5Eget_num(stid);
        std::string ret;

        if (stackSize)
        {
            herr_t err = H5Ewalk2(stid, H5E_WALK_UPWARD, getStackErrorMsg, &ret);
            H5Eclear2(stid);
        }

        return ret;
    }

    static herr_t getStackErrorMsg(unsigned int n, const H5E_error2_t * eptr, void * client_data)
    {
        std::string * str = (std::string *)client_data;
        str->append(eptr->desc);

        return -1;
    }

    inline std::string getDescription(std::string m) const
    {
        std::ostringstream os;
        std::string err = getHDF5ErrorMsg();
        if (!err.empty())
        {
            os << m << std::endl
               << _("HDF5 description") << ": " << err << "." << std::flush;

            m = os.str();
            os.str("");
        }

#if defined(__HDF5OBJECTS_DEBUG__)

        if (line == -1)
        {
            return m;
        }

        const char * bt = backtrace_print(0, 1);

        os << m << std::endl
           << "DEBUG Information:" << std::endl
           << gettext("Exception thrown in file") << " " << file << " " << gettext("at line") << " " << line << std::endl
           << bt << std::flush;

        free(const_cast<char *>(bt));

        return os.str();

#else

        return m;

#endif
    }
};
}

#endif // __H5EXCEPTION_HXX__