Home | History | Annotate | Download | only in core
      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