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() { return new SkError(kNoError_SkError); }
DeleteThreadError(void * v)19 void DeleteThreadError(void *v) { delete reinterpret_cast<SkError *>(v); }
20 #define THREAD_ERROR \
21 (*reinterpret_cast<SkError*>(SkTLS::Get(CreateThreadError, DeleteThreadError)))
22
CreateThreadErrorCallback()23 void *CreateThreadErrorCallback() {
24 return new SkErrorCallbackFunction(SkErrorInternals::DefaultErrorCallback);
25 }
DeleteThreadErrorCallback(void * v)26 void DeleteThreadErrorCallback(void* v) {
27 delete reinterpret_cast<SkErrorCallbackFunction *>(v);
28 }
29
30 #define THREAD_ERROR_CALLBACK \
31 *(reinterpret_cast<SkErrorCallbackFunction *>(SkTLS::Get(CreateThreadErrorCallback, \
32 DeleteThreadErrorCallback)))
33
CreateThreadErrorContext()34 void *CreateThreadErrorContext() { return new void **(nullptr); }
DeleteThreadErrorContext(void * v)35 void DeleteThreadErrorContext(void *v) { delete reinterpret_cast<void **>(v); }
36 #define THREAD_ERROR_CONTEXT \
37 (*reinterpret_cast<void **>(SkTLS::Get(CreateThreadErrorContext, DeleteThreadErrorContext)))
38
39 #define ERROR_STRING_LENGTH 2048
40
CreateThreadErrorString()41 void *CreateThreadErrorString() { return new char[(ERROR_STRING_LENGTH)]; }
DeleteThreadErrorString(void * v)42 void DeleteThreadErrorString(void *v) { delete[] reinterpret_cast<char *>(v); }
43 #define THREAD_ERROR_STRING \
44 (reinterpret_cast<char *>(SkTLS::Get(CreateThreadErrorString, DeleteThreadErrorString)))
45 }
46
SkGetLastError()47 SkError SkGetLastError() {
48 return SkErrorInternals::GetLastError();
49 }
SkClearLastError()50 void SkClearLastError() {
51 SkErrorInternals::ClearError();
52 }
SkSetErrorCallback(SkErrorCallbackFunction cb,void * context)53 void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context) {
54 SkErrorInternals::SetErrorCallback(cb, context);
55 }
SkGetLastErrorString()56 const char *SkGetLastErrorString() {
57 return SkErrorInternals::GetLastErrorString();
58 }
59
60 // ------------ Private Error functions ---------
61
SetErrorCallback(SkErrorCallbackFunction cb,void * context)62 void SkErrorInternals::SetErrorCallback(SkErrorCallbackFunction cb, void *context) {
63 if (cb == nullptr) {
64 THREAD_ERROR_CALLBACK = SkErrorInternals::DefaultErrorCallback;
65 } else {
66 THREAD_ERROR_CALLBACK = cb;
67 }
68 THREAD_ERROR_CONTEXT = context;
69 }
70
DefaultErrorCallback(SkError code,void * context)71 void SkErrorInternals::DefaultErrorCallback(SkError code, void *context) {
72 SkDebugf("Skia Error: %s\n", SkGetLastErrorString());
73 }
74
ClearError()75 void SkErrorInternals::ClearError() {
76 SkErrorInternals::SetError( kNoError_SkError, "All is well" );
77 }
78
GetLastError()79 SkError SkErrorInternals::GetLastError() {
80 return THREAD_ERROR;
81 }
82
GetLastErrorString()83 const char *SkErrorInternals::GetLastErrorString() {
84 return THREAD_ERROR_STRING;
85 }
86
SetError(SkError code,const char * fmt,...)87 void SkErrorInternals::SetError(SkError code, const char *fmt, ...) {
88 THREAD_ERROR = code;
89 va_list args;
90
91 char *str = THREAD_ERROR_STRING;
92 const char *error_name = nullptr;
93 switch( code ) {
94 case kNoError_SkError:
95 error_name = "No Error";
96 break;
97 case kInvalidArgument_SkError:
98 error_name = "Invalid Argument";
99 break;
100 case kInvalidOperation_SkError:
101 error_name = "Invalid Operation";
102 break;
103 case kInvalidHandle_SkError:
104 error_name = "Invalid Handle";
105 break;
106 case kInvalidPaint_SkError:
107 error_name = "Invalid Paint";
108 break;
109 case kOutOfMemory_SkError:
110 error_name = "Out Of Memory";
111 break;
112 case kParseError_SkError:
113 error_name = "Parse Error";
114 break;
115 default:
116 error_name = "Unknown error";
117 break;
118 }
119
120 sprintf( str, "%s: ", error_name );
121 int string_left = SkToInt(ERROR_STRING_LENGTH - strlen(str));
122 str += strlen(str);
123
124 va_start( args, fmt );
125 vsnprintf( str, string_left, fmt, args );
126 va_end( args );
127 SkErrorCallbackFunction fn = THREAD_ERROR_CALLBACK;
128 if (fn && code != kNoError_SkError) {
129 fn(code, THREAD_ERROR_CONTEXT);
130 }
131 }
132