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 { 18 void *CreateThreadError() { return new SkError(kNoError_SkError); } 19 void DeleteThreadError(void *v) { delete reinterpret_cast<SkError *>(v); } 20 #define THREAD_ERROR \ 21 (*reinterpret_cast<SkError*>(SkTLS::Get(CreateThreadError, DeleteThreadError))) 22 23 void *CreateThreadErrorCallback() { 24 return new SkErrorCallbackFunction(SkErrorInternals::DefaultErrorCallback); 25 } 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 34 void *CreateThreadErrorContext() { return new void **(nullptr); } 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 41 void *CreateThreadErrorString() { return new char[(ERROR_STRING_LENGTH)]; } 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 47 SkError SkGetLastError() { 48 return SkErrorInternals::GetLastError(); 49 } 50 void SkClearLastError() { 51 SkErrorInternals::ClearError(); 52 } 53 void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context) { 54 SkErrorInternals::SetErrorCallback(cb, context); 55 } 56 const char *SkGetLastErrorString() { 57 return SkErrorInternals::GetLastErrorString(); 58 } 59 60 // ------------ Private Error functions --------- 61 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 71 void SkErrorInternals::DefaultErrorCallback(SkError code, void *context) { 72 SkDebugf("Skia Error: %s\n", SkGetLastErrorString()); 73 } 74 75 void SkErrorInternals::ClearError() { 76 SkErrorInternals::SetError( kNoError_SkError, "All is well" ); 77 } 78 79 SkError SkErrorInternals::GetLastError() { 80 return THREAD_ERROR; 81 } 82 83 const char *SkErrorInternals::GetLastErrorString() { 84 return THREAD_ERROR_STRING; 85 } 86 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