blob: 9e4385b4894dd2cc2448df2fb40bef6de149e909 [file] [log] [blame]
/*
* 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 new SkError(kNoError_SkError); }
void DeleteThreadError(void *v) { delete reinterpret_cast<SkError *>(v); }
#define THREAD_ERROR \
(*reinterpret_cast<SkError*>(SkTLS::Get(CreateThreadError, DeleteThreadError)))
void *CreateThreadErrorCallback() {
return new SkErrorCallbackFunction(SkErrorInternals::DefaultErrorCallback);
}
void DeleteThreadErrorCallback(void* v) {
delete reinterpret_cast<SkErrorCallbackFunction *>(v);
}
#define THREAD_ERROR_CALLBACK \
*(reinterpret_cast<SkErrorCallbackFunction *>(SkTLS::Get(CreateThreadErrorCallback, \
DeleteThreadErrorCallback)))
void *CreateThreadErrorContext() { return new void **(nullptr); }
void DeleteThreadErrorContext(void *v) { delete reinterpret_cast<void **>(v); }
#define THREAD_ERROR_CONTEXT \
(*reinterpret_cast<void **>(SkTLS::Get(CreateThreadErrorContext, DeleteThreadErrorContext)))
#define ERROR_STRING_LENGTH 2048
void *CreateThreadErrorString() { return new char[(ERROR_STRING_LENGTH)]; }
void DeleteThreadErrorString(void *v) { delete[] 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 == nullptr) {
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 = nullptr;
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);
}
}