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() {
     19         return SkNEW_ARGS(SkError, (kNoError_SkError));
     20     }
     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 
     27     void *CreateThreadErrorCallback() {
     28         return SkNEW_ARGS(SkErrorCallbackFunction, (SkErrorInternals::DefaultErrorCallback));
     29     }
     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 
     38     void *CreateThreadErrorContext() {
     39         return SkNEW_ARGS(void **, (NULL));
     40     }
     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 
     49     void *CreateThreadErrorString() {
     50         return SkNEW_ARRAY(char, (ERROR_STRING_LENGTH));
     51     }
     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 
     59 SkError SkGetLastError() {
     60     return SkErrorInternals::GetLastError();
     61 }
     62 void SkClearLastError() {
     63     SkErrorInternals::ClearError();
     64 }
     65 void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context) {
     66     SkErrorInternals::SetErrorCallback(cb, context);
     67 }
     68 const char *SkGetLastErrorString() {
     69     return SkErrorInternals::GetLastErrorString();
     70 }
     71 
     72 // ------------ Private Error functions ---------
     73 
     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 
     83 void SkErrorInternals::DefaultErrorCallback(SkError code, void *context) {
     84     SkDebugf("Skia Error: %s\n", SkGetLastErrorString());
     85 }
     86 
     87 void SkErrorInternals::ClearError() {
     88     SkErrorInternals::SetError( kNoError_SkError, "All is well" );
     89 }
     90 
     91 SkError SkErrorInternals::GetLastError() {
     92     return THREAD_ERROR;
     93 }
     94 
     95 const char *SkErrorInternals::GetLastErrorString() {
     96     return THREAD_ERROR_STRING;
     97 }
     98 
     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