aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/common/exception.cpp
blob: dc4e6acb4e031319198ca65a55af0f6502b8416a (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
#include <stdarg.h>

#include "exception.h"

namespace JinEngine
{

    Exception::Exception(const char *fmt, ...)
    {
        va_list args;
        int size_buffer = 256, size_out;
        char *buffer;
        while (true)
        {
            buffer = new char[size_buffer];
            memset(buffer, 0, size_buffer);

            va_start(args, fmt);
            size_out = vsnprintf(buffer, size_buffer, fmt, args);
            va_end(args);

            // see http://perfec.to/vsnprintf/pasprintf.c
            // if size_out ...
            //      == -1             --> output was truncated
            //      == size_buffer    --> output was truncated
            //      == size_buffer-1  --> ambiguous, /may/ have been truncated
            //       > size_buffer    --> output was truncated, and size_out
            //                            bytes would have been written
            if (size_out == size_buffer || size_out == -1 || size_out == size_buffer - 1)
                size_buffer *= 2;
            else if (size_out > size_buffer)
                size_buffer = size_out + 2; // to avoid the ambiguous case
            else
                break;

            delete[] buffer;
        }
        mMessage = std::string(buffer);
        delete[] buffer;
    }

    Exception::~Exception() throw()
    {
    }

} // namespace JinEngine