| /* | |
| * Copyright 2013 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "SkTLS.h" | |
| #include "SkTypes.h" | |
| #include "SkError.h" | |
| #include "SkErrorInternals.h" | |
| #include <stdio.h> | |
| #include <stdarg.h> | |
| namespace { | |
| void *CreateThreadError() { | |
| return SkNEW_ARGS(SkError, (kNoError_SkError)); | |
| } | |
| void DeleteThreadError(void* v) { | |
| SkDELETE(reinterpret_cast<SkError*>(v)); | |
| } | |
| #define THREAD_ERROR \ | |
| (*reinterpret_cast<SkError*>(SkTLS::Get(CreateThreadError, DeleteThreadError))) | |
| void *CreateThreadErrorCallback() { | |
| return SkNEW_ARGS(SkErrorCallbackFunction, (SkErrorInternals::DefaultErrorCallback)); | |
| } | |
| void DeleteThreadErrorCallback(void* v) { | |
| SkDELETE(reinterpret_cast<SkErrorCallbackFunction *>(v)); | |
| } | |
| #define THREAD_ERROR_CALLBACK \ | |
| *(reinterpret_cast<SkErrorCallbackFunction *>(SkTLS::Get(CreateThreadErrorCallback, \ | |
| DeleteThreadErrorCallback))) | |
| void *CreateThreadErrorContext() { | |
| return SkNEW_ARGS(void **, (NULL)); | |
| } | |
| void DeleteThreadErrorContext(void* v) { | |
| SkDELETE(reinterpret_cast<void **>(v)); | |
| } | |
| #define THREAD_ERROR_CONTEXT \ | |
| (*reinterpret_cast<void **>(SkTLS::Get(CreateThreadErrorContext, DeleteThreadErrorContext))) | |
| #define ERROR_STRING_LENGTH 2048 | |
| void *CreateThreadErrorString() { | |
| return SkNEW_ARRAY(char, (ERROR_STRING_LENGTH)); | |
| } | |
| void DeleteThreadErrorString(void* v) { | |
| SkDELETE_ARRAY(reinterpret_cast<char *>(v)); | |
| } | |
| #define THREAD_ERROR_STRING \ | |
| (reinterpret_cast<char *>(SkTLS::Get(CreateThreadErrorString, DeleteThreadErrorString))) | |
| } | |
| SkError SkGetLastError() { | |
| return SkErrorInternals::GetLastError(); | |
| } | |
| void SkClearLastError() { | |
| SkErrorInternals::ClearError(); | |
| } | |
| void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context) { | |
| SkErrorInternals::SetErrorCallback(cb, context); | |
| } | |
| const char *SkGetLastErrorString() { | |
| return SkErrorInternals::GetLastErrorString(); | |
| } | |
| // ------------ Private Error functions --------- | |
| void SkErrorInternals::SetErrorCallback(SkErrorCallbackFunction cb, void *context) { | |
| if (cb == NULL) { | |
| THREAD_ERROR_CALLBACK = SkErrorInternals::DefaultErrorCallback; | |
| } else { | |
| THREAD_ERROR_CALLBACK = cb; | |
| } | |
| THREAD_ERROR_CONTEXT = context; | |
| } | |
| void SkErrorInternals::DefaultErrorCallback(SkError code, void *context) { | |
| SkDebugf("Skia Error: %s\n", SkGetLastErrorString()); | |
| } | |
| void SkErrorInternals::ClearError() { | |
| SkErrorInternals::SetError( kNoError_SkError, "All is well" ); | |
| } | |
| SkError SkErrorInternals::GetLastError() { | |
| return THREAD_ERROR; | |
| } | |
| const char *SkErrorInternals::GetLastErrorString() { | |
| return THREAD_ERROR_STRING; | |
| } | |
| void SkErrorInternals::SetError(SkError code, const char *fmt, ...) { | |
| THREAD_ERROR = code; | |
| va_list args; | |
| char *str = THREAD_ERROR_STRING; | |
| const char *error_name = NULL; | |
| switch( code ) { | |
| case kNoError_SkError: | |
| error_name = "No Error"; | |
| break; | |
| case kInvalidArgument_SkError: | |
| error_name = "Invalid Argument"; | |
| break; | |
| case kInvalidOperation_SkError: | |
| error_name = "Invalid Operation"; | |
| break; | |
| case kInvalidHandle_SkError: | |
| error_name = "Invalid Handle"; | |
| break; | |
| case kInvalidPaint_SkError: | |
| error_name = "Invalid Paint"; | |
| break; | |
| case kOutOfMemory_SkError: | |
| error_name = "Out Of Memory"; | |
| break; | |
| case kParseError_SkError: | |
| error_name = "Parse Error"; | |
| break; | |
| default: | |
| error_name = "Unknown error"; | |
| break; | |
| } | |
| sprintf( str, "%s: ", error_name ); | |
| int string_left = SkToInt(ERROR_STRING_LENGTH - strlen(str)); | |
| str += strlen(str); | |
| va_start( args, fmt ); | |
| vsnprintf( str, string_left, fmt, args ); | |
| va_end( args ); | |
| SkErrorCallbackFunction fn = THREAD_ERROR_CALLBACK; | |
| if (fn && code != kNoError_SkError) { | |
| fn(code, THREAD_ERROR_CONTEXT); | |
| } | |
| } |