1 
2 /*
3  * Copyright 2013 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #include "SkTLS.h"
10 #include "SkTypes.h"
11 #include "SkError.h"
12 #include "SkErrorInternals.h"
13 
14 #include <stdio.h>
15 #include <stdarg.h>
16 
17 namespace {
CreateThreadError()18     void *CreateThreadError() {
19         return SkNEW_ARGS(SkError, (kNoError_SkError));
20     }
DeleteThreadError(void * v)21     void DeleteThreadError(void* v) {
22         SkDELETE(reinterpret_cast<SkError*>(v));
23     }
24     #define THREAD_ERROR \
25         (*reinterpret_cast<SkError*>(SkTLS::Get(CreateThreadError, DeleteThreadError)))
26 
CreateThreadErrorCallback()27     void *CreateThreadErrorCallback() {
28         return SkNEW_ARGS(SkErrorCallbackFunction, (SkErrorInternals::DefaultErrorCallback));
29     }
DeleteThreadErrorCallback(void * v)30     void DeleteThreadErrorCallback(void* v) {
31         SkDELETE(reinterpret_cast<SkErrorCallbackFunction *>(v));
32     }
33 
34     #define THREAD_ERROR_CALLBACK                                                             \
35         *(reinterpret_cast<SkErrorCallbackFunction *>(SkTLS::Get(CreateThreadErrorCallback,   \
36                                                                  DeleteThreadErrorCallback)))
37 
CreateThreadErrorContext()38     void *CreateThreadErrorContext() {
39         return SkNEW_ARGS(void **, (NULL));
40     }
DeleteThreadErrorContext(void * v)41     void DeleteThreadErrorContext(void* v) {
42         SkDELETE(reinterpret_cast<void **>(v));
43     }
44     #define THREAD_ERROR_CONTEXT \
45         (*reinterpret_cast<void **>(SkTLS::Get(CreateThreadErrorContext, DeleteThreadErrorContext)))
46 
47     #define ERROR_STRING_LENGTH 2048
48 
CreateThreadErrorString()49     void *CreateThreadErrorString() {
50         return SkNEW_ARRAY(char, (ERROR_STRING_LENGTH));
51     }
DeleteThreadErrorString(void * v)52     void DeleteThreadErrorString(void* v) {
53         SkDELETE_ARRAY(reinterpret_cast<char *>(v));
54     }
55     #define THREAD_ERROR_STRING \
56         (reinterpret_cast<char *>(SkTLS::Get(CreateThreadErrorString, DeleteThreadErrorString)))
57 }
58 
SkGetLastError()59 SkError SkGetLastError() {
60     return SkErrorInternals::GetLastError();
61 }
SkClearLastError()62 void SkClearLastError() {
63     SkErrorInternals::ClearError();
64 }
SkSetErrorCallback(SkErrorCallbackFunction cb,void * context)65 void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context) {
66     SkErrorInternals::SetErrorCallback(cb, context);
67 }
SkGetLastErrorString()68 const char *SkGetLastErrorString() {
69     return SkErrorInternals::GetLastErrorString();
70 }
71 
72 // ------------ Private Error functions ---------
73 
SetErrorCallback(SkErrorCallbackFunction cb,void * context)74 void SkErrorInternals::SetErrorCallback(SkErrorCallbackFunction cb, void *context) {
75     if (cb == NULL) {
76         THREAD_ERROR_CALLBACK = SkErrorInternals::DefaultErrorCallback;
77     } else {
78         THREAD_ERROR_CALLBACK = cb;
79     }
80     THREAD_ERROR_CONTEXT = context;
81 }
82 
DefaultErrorCallback(SkError code,void * context)83 void SkErrorInternals::DefaultErrorCallback(SkError code, void *context) {
84     SkDebugf("Skia Error: %s\n", SkGetLastErrorString());
85 }
86 
ClearError()87 void SkErrorInternals::ClearError() {
88     SkErrorInternals::SetError( kNoError_SkError, "All is well" );
89 }
90 
GetLastError()91 SkError SkErrorInternals::GetLastError() {
92     return THREAD_ERROR;
93 }
94 
GetLastErrorString()95 const char *SkErrorInternals::GetLastErrorString() {
96     return THREAD_ERROR_STRING;
97 }
98 
SetError(SkError code,const char * fmt,...)99 void SkErrorInternals::SetError(SkError code, const char *fmt, ...) {
100     THREAD_ERROR = code;
101     va_list args;
102 
103     char *str = THREAD_ERROR_STRING;
104     const char *error_name = NULL;
105     switch( code ) {
106         case kNoError_SkError:
107             error_name = "No Error";
108             break;
109         case kInvalidArgument_SkError:
110             error_name = "Invalid Argument";
111             break;
112         case kInvalidOperation_SkError:
113             error_name = "Invalid Operation";
114             break;
115         case kInvalidHandle_SkError:
116             error_name = "Invalid Handle";
117             break;
118         case kInvalidPaint_SkError:
119             error_name = "Invalid Paint";
120             break;
121         case kOutOfMemory_SkError:
122             error_name = "Out Of Memory";
123             break;
124         case kParseError_SkError:
125             error_name = "Parse Error";
126             break;
127         default:
128             error_name = "Unknown error";
129             break;
130     }
131 
132     sprintf( str, "%s: ", error_name );
133     int string_left = SkToInt(ERROR_STRING_LENGTH - strlen(str));
134     str += strlen(str);
135 
136     va_start( args, fmt );
137     vsnprintf( str, string_left, fmt, args );
138     va_end( args );
139     SkErrorCallbackFunction fn = THREAD_ERROR_CALLBACK;
140     if (fn && code != kNoError_SkError) {
141         fn(code, THREAD_ERROR_CONTEXT);
142     }
143 }
144