diff --git a/Platform/Android/Android.mk b/Platform/Android/Android.mk
index 66a5fc5ea..d320d7053 100644
--- a/Platform/Android/Android.mk
+++ b/Platform/Android/Android.mk
@@ -1,17 +1,17 @@
# Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Licensed under Gnu Affero General Public License Version 3 (provided, notwithstanding this
-# notice, Readium Foundation reserves the right to license this material under a different
-# separate license, and if you have done so, the terms of that separate license control and
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Licensed under Gnu Affero General Public License Version 3 (provided, notwithstanding this
+# notice, Readium Foundation reserves the right to license this material under a different
+# separate license, and if you have done so, the terms of that separate license control and
# the following references to GPL do not apply).
-#
-# This program is free software: you can redistribute it and/or modify it under the terms
-# of the GNU Affero General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version. You should have
-# received a copy of the GNU Affero General Public License along with this program. If not,
+#
+# This program is free software: you can redistribute it and/or modify it under the terms
+# of the GNU Affero General Public License as published by the Free Software Foundation,
+# either version 3 of the License, or (at your option) any later version. You should have
+# received a copy of the GNU Affero General Public License along with this program. If not,
# see .
LOCAL_PATH := $(call my-dir)/../..
@@ -277,6 +277,7 @@ LOCAL_SRC_FILES := \
ePub3/ePub/filter_chain_byte_stream_range.cpp \
ePub3/ePub/filter_manager_impl.cpp \
ePub3/ePub/filter_manager.cpp \
+ ePub3/ePub/filter.cpp \
ePub3/ePub/PassThroughFilter.cpp \
ePub3/ePub/font_obfuscation.cpp \
ePub3/ePub/glossary.cpp \
diff --git a/Platform/Android/jni/epub3.cpp b/Platform/Android/jni/epub3.cpp
index 816989782..e1dc780f5 100644
--- a/Platform/Android/jni/epub3.cpp
+++ b/Platform/Android/jni/epub3.cpp
@@ -25,6 +25,7 @@
#include
#include
+#include
#include
#include
@@ -70,6 +71,9 @@ static const char *javaEPub3_appendBytesToBufferSignature = "(Ljava/nio/ByteBuff
static const char *javaEPub3_handleSdkErrorMethodName = "handleSdkError";
static const char *javaEPub3_handleSdkErrorSignature = "(Ljava/lang/String;Z)Z";
+static const char *javaEPub3_handleContentFilterErrorMethodName = "handleContentFilterError";
+static const char *javaEPub3_handleContentFilterErrorSignature = "(Ljava/lang/String;JLjava/lang/String;)V";
+
/*
* Exported variables
@@ -95,6 +99,11 @@ jmethodID createManifestItem_ID;
jmethodID addManifestItemToList_ID;
+// Global variable to store the current Java virtual machine.
+// This will be needed by the ContentFilterErrorHandler() function.
+JavaVM *g_vm = NULL;
+
+
/*
* Internal variables
**************************************************/
@@ -110,7 +119,7 @@ static jmethodID addStringToList_ID;
static jmethodID createBuffer_ID;
static jmethodID appendBytesToBuffer_ID;
static jmethodID handleSdkError_ID;
-
+static jmethodID handleContentFilterError_ID;
/*
* Exported functions
@@ -190,6 +199,10 @@ jboolean javaEPub3_handleSdkError(JNIEnv *env, jstring message, jboolean isSever
return b;
}
+void javaEPub3_handleContentFilterError(JNIEnv *env, jstring filterId, jlong errorCode, jstring message) {
+ env->CallStaticVoidMethod(javaEPub3Class, handleContentFilterError_ID, filterId, errorCode, message);
+}
+
/*
* Internal functions
**************************************************/
@@ -211,11 +224,13 @@ static int onLoad_cacheJavaElements_epub3(JNIEnv *env) {
javaEPub3_appendBytesToBufferMethodName, javaEPub3_appendBytesToBufferSignature, ONLOAD_ERROR);
INIT_STATIC_METHOD_ID_RETVAL(handleSdkError_ID, javaEPub3Class, javaEPub3ClassName,
javaEPub3_handleSdkErrorMethodName, javaEPub3_handleSdkErrorSignature, ONLOAD_ERROR);
+ INIT_STATIC_METHOD_ID_RETVAL(handleContentFilterError_ID, javaEPub3Class, javaEPub3ClassName,
+ javaEPub3_handleContentFilterErrorMethodName, javaEPub3_handleContentFilterErrorSignature, ONLOAD_ERROR);
// Return JNI_VERSION for OK, if not one of the lines above already returned ONLOAD_ERROR
return JNI_VERSION;
}
-// needed only for the LauncherErrorHandler() C++ callback,
+// needed only for the following C++ callbacks,
// set by initializeReadiumSDK()
static JNIEnv* m_env = nullptr;
@@ -238,6 +253,30 @@ static bool LauncherErrorHandler(const ePub3::error_details& err)
//return ePub3::DefaultErrorHandler(err);
}
+/**
+ * Callback to be invoked when any ContentFilter has an error.
+ */
+
+static void ContentFilterErrorHandler(const std::string &filterId, unsigned int errorCode, const std::string &message)
+{
+ // Making sure that we have the right JNI environment pointer for every thread.
+ // This function may be called in different threads, and you must have the right
+ // JNI environment pointer for the current thread, otherwise it will crash the app.
+ JNIEnv *env;
+ if (g_vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) {
+ LOGE("ContentFilterErrorHandler: failed to get environment. VM doesn't support JNI version 1.6");
+ return;
+ }
+
+ jstring jFilterId = env->NewStringUTF(filterId.c_str());
+ jstring jMessage = env->NewStringUTF(message.c_str());
+
+ javaEPub3_handleContentFilterError(env, jFilterId, (jlong)errorCode, jMessage);
+
+ env->DeleteLocalRef(jFilterId);
+ env->DeleteLocalRef(jMessage);
+}
+
/**
* Initializes the Readium SDK.
*/
@@ -249,6 +288,9 @@ static void initializeReadiumSDK(JNIEnv* env)
ePub3::ErrorHandlerFn launcherErrorHandler = LauncherErrorHandler;
ePub3::SetErrorHandler(launcherErrorHandler);
+
+ ePub3::ContentFilterErrorHandlerFn contentFilterErrorHandler = ContentFilterErrorHandler;
+ ePub3::ContentFilter::ResetContentFilterErrorHandler(contentFilterErrorHandler);
ePub3::InitializeSdk();
ePub3::PopulateFilterManager();
@@ -266,6 +308,8 @@ static void initializeReadiumSDK(JNIEnv* env)
*/
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
+ g_vm = vm;
+
// Get the JNI Environment to be able to initialize the cached the java elements
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) {
diff --git a/Platform/Android/jni/epub3.h b/Platform/Android/jni/epub3.h
index e62d37d04..ab23493be 100644
--- a/Platform/Android/jni/epub3.h
+++ b/Platform/Android/jni/epub3.h
@@ -111,6 +111,8 @@ void javaEPub3_appendBytesToBuffer(JNIEnv *env, jobject buffer, jbyteArray data)
jboolean javaEPub3_handleSdkError(JNIEnv *env, jstring message, jboolean isSevereEpubError);
+void javaEPub3_handleContentFilterError(JNIEnv *env, jstring filterId, jlong errorCode, jstring message);
+
/*
* JNI functions
**************************************************/
diff --git a/Platform/Android/src/org/readium/sdk/android/ContentFilterErrorHandler.java b/Platform/Android/src/org/readium/sdk/android/ContentFilterErrorHandler.java
new file mode 100644
index 000000000..7041261a3
--- /dev/null
+++ b/Platform/Android/src/org/readium/sdk/android/ContentFilterErrorHandler.java
@@ -0,0 +1,21 @@
+// Copyright (c) 2015 Readium Foundation and/or its licensees. All rights reserved.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Licensed under Gnu Affero General Public License Version 3 (provided, notwithstanding this notice,
+// Readium Foundation reserves the right to license this material under a different separate license,
+// and if you have done so, the terms of that separate license control and the following references
+// to GPL do not apply).
+//
+// This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+// Affero General Public License as published by the Free Software Foundation, either version 3 of
+// the License, or (at your option) any later version. You should have received a copy of the GNU
+// Affero General Public License along with this program. If not, see .
+
+
+package org.readium.sdk.android;
+
+public interface ContentFilterErrorHandler {
+ void handleContentFilterError(String filterId, long errorCode, String message);
+}
diff --git a/Platform/Android/src/org/readium/sdk/android/EPub3.java b/Platform/Android/src/org/readium/sdk/android/EPub3.java
index 5e156eb05..2fa967626 100644
--- a/Platform/Android/src/org/readium/sdk/android/EPub3.java
+++ b/Platform/Android/src/org/readium/sdk/android/EPub3.java
@@ -169,4 +169,16 @@ private static boolean handleSdkError(String message, boolean isSevereEpubError)
// never throws an exception
return true;
}
+
+ private static ContentFilterErrorHandler m_contentFilterErrorHandler = null;
+
+ public static void setContentFilterErrorHandler(ContentFilterErrorHandler handler) {
+ m_contentFilterErrorHandler = handler;
+ }
+
+ private static void handleContentFilterError(String filterId, long errorCode, String message) {
+ if (m_contentFilterErrorHandler != null) {
+ m_contentFilterErrorHandler.handleContentFilterError(filterId, errorCode, message);
+ }
+ }
}
diff --git a/Platform/Apple/RDServices/Main/RDContainer.h b/Platform/Apple/RDServices/Main/RDContainer.h
index e7c35f58c..ba591bcd0 100644
--- a/Platform/Apple/RDServices/Main/RDContainer.h
+++ b/Platform/Apple/RDServices/Main/RDContainer.h
@@ -29,11 +29,19 @@
#import
+
+extern NSString * const EPub3ContentFilterErrorDomain;
+extern NSString * const EPub3ContentFilterIdentifierKey;
+extern NSString * const EPub3ContentFilterErrorCodeKey;
+extern NSString * const EPub3ContentFilterErrorMessage;
+
+
@class RDContainer;
@protocol RDContainerDelegate
- (BOOL)container:(RDContainer *)container handleSdkError:(NSString *)message isSevereEpubError:(BOOL)isSevereEpubError;
+- (void)container:(RDContainer *)container handleContentFilterError:(NSError *)error;
@end
diff --git a/Platform/Apple/RDServices/Main/RDContainer.mm b/Platform/Apple/RDServices/Main/RDContainer.mm
index b9265e48e..65edd7166 100644
--- a/Platform/Apple/RDServices/Main/RDContainer.mm
+++ b/Platform/Apple/RDServices/Main/RDContainer.mm
@@ -31,8 +31,14 @@
#import
#import
#import
+#import
#import "RDPackage.h"
+NSString * const EPub3ContentFilterErrorDomain = @"ePub3ContentFilterErrorDomain";
+NSString * const EPub3ContentFilterIdentifierKey = @"ePub3ContentFilterIdentifierKey";
+NSString * const EPub3ContentFilterErrorCodeKey = @"ePub3ContentFilterErrorCodeKey";
+NSString * const EPub3ContentFilterErrorMessage = @"ePub3ContentFilterErrorMessageKey";
+
@interface RDContainer () {
@private std::shared_ptr m_container;
@@ -81,6 +87,21 @@ - (instancetype)initWithDelegate:(id )delegate path:(NSStri
//return ePub3::DefaultErrorHandler(err);
};
ePub3::SetErrorHandler(sdkErrorHandler);
+
+ ePub3::ContentFilterErrorHandlerFn contentFilterErrorHandler = ^(const std::string &filterId, unsigned int errorCode, const std::string &message) {
+
+ NSDictionary *errorDictionary = @{
+ EPub3ContentFilterIdentifierKey : [NSString stringWithUTF8String:filterId.c_str()],
+ EPub3ContentFilterErrorCodeKey : [[NSNumber alloc] initWithUnsignedInt:errorCode],
+ EPub3ContentFilterErrorMessage : [NSString stringWithUTF8String:message.c_str()]
+ };
+
+ NSError *error = [[NSError alloc] initWithDomain:EPub3ContentFilterErrorDomain code:errorCode userInfo:errorDictionary];
+
+ [m_delegate container:self handleContentFilterError:error];
+ };
+
+ ePub3::ContentFilter::ResetContentFilterErrorHandler(contentFilterErrorHandler);
ePub3::InitializeSdk();
ePub3::PopulateFilterManager();
diff --git a/Platform/Apple/ePub3.xcodeproj/project.pbxproj b/Platform/Apple/ePub3.xcodeproj/project.pbxproj
index a48169bb1..860c91d68 100644
--- a/Platform/Apple/ePub3.xcodeproj/project.pbxproj
+++ b/Platform/Apple/ePub3.xcodeproj/project.pbxproj
@@ -16,6 +16,8 @@
1EFA3ACB17AB0BEF003A4BC2 /* filter_manager_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EFA3ACA17AB0BEF003A4BC2 /* filter_manager_impl.cpp */; };
1EFA3ACC17AB0C7A003A4BC2 /* filter_manager_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EFA3ACA17AB0BEF003A4BC2 /* filter_manager_impl.cpp */; };
3418BA7D16C4151E009AA7EF /* ring_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABA88FD116C2B4ED00F2014B /* ring_buffer.cpp */; };
+ 586C95941B41FCCE00FD3700 /* filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 586C95931B41FCCE00FD3700 /* filter.cpp */; };
+ 586C95951B41FCCE00FD3700 /* filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 586C95931B41FCCE00FD3700 /* filter.cpp */; };
588D24201A02EF8F006A92BB /* PassThroughFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 588D241E1A02EF8F006A92BB /* PassThroughFilter.cpp */; };
588D24211A02EF8F006A92BB /* PassThroughFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 588D241E1A02EF8F006A92BB /* PassThroughFilter.cpp */; };
588D24221A02EF8F006A92BB /* PassThroughFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 588D241F1A02EF8F006A92BB /* PassThroughFilter.h */; };
@@ -445,6 +447,7 @@
1ED0084717A9DC6F00819EBD /* initialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = initialization.cpp; sourceTree = ""; };
1EFA3AC917AB0BC0003A4BC2 /* filter_manager_impl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = filter_manager_impl.h; sourceTree = ""; };
1EFA3ACA17AB0BEF003A4BC2 /* filter_manager_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filter_manager_impl.cpp; sourceTree = ""; };
+ 586C95931B41FCCE00FD3700 /* filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filter.cpp; sourceTree = ""; };
588D241E1A02EF8F006A92BB /* PassThroughFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PassThroughFilter.cpp; sourceTree = ""; };
588D241F1A02EF8F006A92BB /* PassThroughFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PassThroughFilter.h; sourceTree = ""; };
850B1AE816A75AB000619C3C /* TestData */ = {isa = PBXFileReference; lastKnownFileType = folder; name = TestData; path = ../../TestData; sourceTree = ""; };
@@ -1098,6 +1101,7 @@
A250D24D05706C9BB1AA54ED /* filter_chain_byte_stream_range.h */,
A250DFDBD90C7E9C632B1E00 /* filter_chain_byte_stream.cpp */,
A250D26DB00356B591AEFC29 /* filter_chain_byte_stream.h */,
+ 586C95931B41FCCE00FD3700 /* filter.cpp */,
);
name = Filters;
sourceTree = "";
@@ -2030,6 +2034,7 @@
buildActionMask = 2147483647;
files = (
ABA4BAEF16ADF64400161B77 /* string16.cc in Sources */,
+ 586C95951B41FCCE00FD3700 /* filter.cpp in Sources */,
ABA4BAF016ADF64400161B77 /* gurl.cc in Sources */,
AB5284D417CBC395003D7BBF /* CPUCacheUtils.c in Sources */,
ABA4BAF316ADF64400161B77 /* url_canon_etc.cc in Sources */,
@@ -2174,6 +2179,7 @@
buildActionMask = 2147483647;
files = (
ABB18FE61656863300CFC651 /* mkstemp.c in Sources */,
+ 586C95941B41FCCE00FD3700 /* filter.cpp in Sources */,
AB718C04184CEEA900F86C6B /* xml_bridge_dtrace_probes.d in Sources */,
ABB18FE81656863300CFC651 /* zip_add.c in Sources */,
ABB18FE91656863300CFC651 /* zip_add_dir.c in Sources */,
diff --git a/ePub3/ePub/PassThroughFilter.cpp b/ePub3/ePub/PassThroughFilter.cpp
index 9cdf2ee9d..a777ee2b5 100644
--- a/ePub3/ePub/PassThroughFilter.cpp
+++ b/ePub3/ePub/PassThroughFilter.cpp
@@ -43,7 +43,7 @@ bool PassThroughFilter::SniffPassThroughContent(ConstManifestItemPtr item)
// auto mediaType = item->MediaType();
// return (mediaType == "audio/mp4" || mediaType == "audio/mpeg" || mediaType == "video/mp4" || mediaType == "video/mpeg");
- return false;
+ return false;
}
ContentFilterPtr PassThroughFilter::PassThroughFactory(ConstPackagePtr package)
@@ -96,6 +96,10 @@ void *PassThroughFilter::FilterData(FilterContext *context, void *data, size_t l
if (!byteStream->IsOpen())
{
+ HandleContentFilterError(
+ std::string(PASS_THROUGH_FILTER_ID),
+ ContentFilterError::InputStreamCannotBeOpened,
+ std::string("Input ByteStream is not opened"));
return nullptr;
}
diff --git a/ePub3/ePub/PassThroughFilter.h b/ePub3/ePub/PassThroughFilter.h
index c1c584e87..5cb17e367 100644
--- a/ePub3/ePub/PassThroughFilter.h
+++ b/ePub3/ePub/PassThroughFilter.h
@@ -28,6 +28,9 @@
#include
#import
+#define PASS_THROUGH_FILTER_ID "3439DA53-2559-400D-8231-981ABA6A85B4"
+
+
EPUB3_BEGIN_NAMESPACE
diff --git a/ePub3/ePub/filter.cpp b/ePub3/ePub/filter.cpp
new file mode 100644
index 000000000..70796ae59
--- /dev/null
+++ b/ePub3/ePub/filter.cpp
@@ -0,0 +1,29 @@
+//
+// filter.cpp
+// ePub3
+//
+// Created by Nelson Leme on 5/28/15.
+// Copyright (c) 2015 The Readium Foundation and contributors. All rights reserved.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Licensed under Gnu Affero General Public License Version 3 (provided, notwithstanding this notice,
+// Readium Foundation reserves the right to license this material under a different separate license,
+// and if you have done so, the terms of that separate license control and the following references
+// to GPL do not apply).
+//
+// This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+// Affero General Public License as published by the Free Software Foundation, either version 3 of
+// the License, or (at your option) any later version. You should have received a copy of the GNU
+// Affero General Public License along with this program. If not, see .
+
+
+#include
+#include "filter.h"
+
+EPUB3_BEGIN_NAMESPACE
+
+ContentFilterErrorHandlerFn ContentFilter::s_contentFilterErrorHandler = ContentFilter::DefaultContentFilterErrorHandler;
+
+EPUB3_END_NAMESPACE
diff --git a/ePub3/ePub/filter.h b/ePub3/ePub/filter.h
index 16f84c255..e2f652561 100644
--- a/ePub3/ePub/filter.h
+++ b/ePub3/ePub/filter.h
@@ -40,6 +40,19 @@ typedef std::shared_ptr PackagePtr;
class ContentFilter;
typedef std::shared_ptr ContentFilterPtr;
+enum class ContentFilterError : unsigned int
+{
+ GenericError = 0,
+ InputStreamCannotBeOpened,
+ OutputStreamCannotBeSought,
+ CorruptedResource,
+ NoLicenseForDecryption,
+ NotEnoughBytesAvailable
+ };
+
+typedef std::function ContentFilterErrorHandlerFn;
+
+
// -------------------------------------------------------------------------------------------
class ByteRange
@@ -287,6 +300,10 @@ class ContentFilter
/// No default constructor.
ContentFilter() _DELETED_;
+ static void DefaultContentFilterErrorHandler(const std::string &filterId, unsigned int code, const std::string &message) { };
+
+ static ContentFilterErrorHandlerFn s_contentFilterErrorHandler;
+
public:
///
/// Copy constructor.
@@ -364,6 +381,23 @@ class ContentFilter
*/
virtual void *FilterData(FilterContext* context, void *data, size_t len, size_t *outputLen) = 0;
+ /**
+ Reset the ContentFilteErrorHandler function.
+
+ Any app that is using the Readium SDK (and its associated ContentFilter classes) may
+ want to set up its own ContentFilterErrorHandler function. This way, the app can be notified
+ when there is an error in the processing done by the ContentFilter objects. Notice that,
+ unless this function is called and reset to something meaningful, the default
+ ContentFilterErrorHandler function is called, which will simply ignore any errors from the
+ ContentFilter.
+
+ @param contentFilterErrorHandler A new ContentFilterErrorHandler function
+ */
+ static void ResetContentFilterErrorHandler(ContentFilterErrorHandlerFn contentFilterErrorHandler)
+ {
+ s_contentFilterErrorHandler = contentFilterErrorHandler;
+ }
+
protected:
TypeSnifferFn _sniffer;
@@ -387,6 +421,47 @@ class ContentFilter
@result An object containing per-item data, or nullptr.
*/
virtual FilterContext *InnerMakeFilterContext(ConstManifestItemPtr item) const { return nullptr; }
+
+ /**
+ Report an error during the processing done by a ContentFilter.
+
+ When a ContentFilter is processing a sequence of bytes, it may reach an error. In that
+ case, the ContentFilter will want to report to the underlying app that something went
+ wrong, so that it can report that to the user. The two overloads of HandleContentFilterError(),
+ below, do exactly that: they allow an app to receive the error description (as parameters)
+ whenever an error happens in a given ContentFilter.
+
+ Notice that the first parameter of both overloads is the filterId. The filterId is a UUID (or
+ GUID) that identifies uniquely a different class of ContentFilter. This way, no matter how many
+ ContentFilter classes are created all over, there will be a unique way to identify each one of
+ them, and any app that uses the Readium SDK will not run the risk of mistaking one class of
+ ContentFilter by another.
+
+ @param filterId A UUID (or GUID) that will uniquely identify a given class of ContentFilter.
+ @param error One of the possible values of the ContentFilterError enumeration.
+ @param message An optional text message, containing whatever the ContentFilter wants to say.
+ */
+ static void HandleContentFilterError(const std::string &filterId, ContentFilterError error, const std::string &message)
+ {
+ HandleContentFilterError(filterId, (unsigned int)error, message);
+ }
+
+ /**
+ Report an error during the processing done by a ContentFilter.
+
+ This overload of HandleContentFilterError does exactly the same as the previous overload, with
+ one difference: the caller can pass an unsigned integer for error code, instead of the
+ ContentFilterError enumeration. The reason is that different people writing ContentFilter classes
+ may decide to use their own error codes for things.
+
+ @param filterId A UUID (or GUID) that will uniquely identify a given class of ContentFilter.
+ @param error An unsigned integer that corresponds to an error code.
+ @param message An optional text message, containing whatever the ContentFilter wants to say.
+ */
+ static void HandleContentFilterError(const std::string &filterId, unsigned int errorCode, const std::string &message)
+ {
+ s_contentFilterErrorHandler(filterId, errorCode, message);
+ }
};