Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
ve.bluecove.2.0.3.source-code.common.cpp Maven / Gradle / Ivy
/**
* BlueCove - Java library for Bluetooth
* Copyright (C) 2006-2008 Vlad Skarzhevskyy
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* @version $Id: common.cpp 2176 2008-05-07 04:38:36Z skarzhevskyy $
*/
#include "common.h"
#include "commonObjects.h"
#ifndef CPP_FILE
#define CPP_FILE "common.cpp"
#endif
BOOL nativeDebugCallbackEnabled = false;
static jclass nativeDebugListenerClass;
static jmethodID nativeDebugMethod = NULL;
const char* cRuntimeException = "java/lang/RuntimeException";
const char* cIOException = "java/io/IOException";
const char* cInterruptedIOException = "java/io/InterruptedIOException";
const char* cBluetoothStateException = "javax/bluetooth/BluetoothStateException";
const char* cBluetoothConnectionException = "javax/bluetooth/BluetoothConnectionException";
const char* cServiceRegistrationException = "javax/bluetooth/ServiceRegistrationException";
jint blueCoveVersion() {
return BLUECOVE_VERSION * 100 + BLUECOVE_BUILD;
}
// --- Debug
BOOL isDebugOn() {
return nativeDebugCallbackEnabled;
}
void enableNativeDebug(JNIEnv *env, jobject loggerClass, jboolean on) {
if (on) {
if (nativeDebugCallbackEnabled) {
return;
}
nativeDebugListenerClass = (jclass)env->NewGlobalRef(loggerClass);
if (nativeDebugListenerClass != NULL) {
nativeDebugMethod = env->GetStaticMethodID(nativeDebugListenerClass, "nativeDebugCallback", "(Ljava/lang/String;ILjava/lang/String;)V");
if (nativeDebugMethod != NULL) {
nativeDebugCallbackEnabled = true;
debug(("nativeDebugCallback ON"));
}
}
} else {
nativeDebugCallbackEnabled = false;
}
}
void stdOutPrint(const char* fileName, int lineN, const char* msg) {
fprintf(stdout, "NATIVE: %s\n\t%s(%i)\n", msg, fileName, lineN);
fflush(stdout);
}
void log_info(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
fprintf(stdout, "BlueCove-INFO:");
vfprintf(stdout, fmt, ap);
fprintf(stdout, "\n");
fflush(stdout);
va_end(ap);
}
void DebugMessage::printf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
{
if (nativeDebugCallbackEnabled) {
_vsnprintf_s(msg, DEBUG_MESSAGE_MAX, fmt, ap);
}
}
va_end(ap);
}
void DebugMessage::callDebugListener(JNIEnv *env, const char* fileName, int lineN) {
if ((env != NULL) && (nativeDebugCallbackEnabled)) {
if (ExceptionCheckCompatible(env)) {
stdOutPrint(fileName, lineN, msg);
} else {
env->CallStaticVoidMethod(nativeDebugListenerClass, nativeDebugMethod, env->NewStringUTF(fileName), lineN, env->NewStringUTF(msg));
}
}
}
void DebugMessage::callDebugStdOut(const char* fileName, int lineN) {
if (nativeDebugCallbackEnabled) {
stdOutPrint(fileName, lineN, msg);
}
}
void callDebugListener(JNIEnv *env, const char* fileName, int lineN, ...) {
va_list ap;
va_start(ap, lineN);
{
if ((env != NULL) && (nativeDebugCallbackEnabled)) {
char msg[DEBUG_MESSAGE_MAX+1];
char *fmt = va_arg(ap, char*);
_vsnprintf_s(msg, DEBUG_MESSAGE_MAX, fmt, ap);
if (ExceptionCheckCompatible(env)) {
stdOutPrint(fileName, lineN, msg);
} else {
env->CallStaticVoidMethod(nativeDebugListenerClass, nativeDebugMethod, env->NewStringUTF(fileName), lineN, env->NewStringUTF(msg));
}
}
}
va_end(ap);
}
void callDebugStdOut(const char* fileName, int lineN, ...) {
va_list ap;
va_start(ap, lineN);
{
if (nativeDebugCallbackEnabled) {
char msg[DEBUG_MESSAGE_MAX+1];
char *fmt = va_arg(ap, char*);
_vsnprintf_s(msg, DEBUG_MESSAGE_MAX, fmt, ap);
stdOutPrint(fileName, lineN, msg);
}
}
va_end(ap);
}
char* bool2str(BOOL b) {
if (b == false) {
return "FALSE";
} else {
return "TRUE";
}
}
// --- Error handling
void vthrowException(JNIEnv *env, const char *name, const char *fmt, va_list ap) {
char msg[DEBUG_MESSAGE_MAX+1];
if (env == NULL) {
return;
}
_vsnprintf_s(msg, DEBUG_MESSAGE_MAX, fmt, ap);
if (ExceptionCheckCompatible(env)) {
debug(("ERROR: can't throw second exception %s(%s)", name, msg));
return;
}
debug(("will throw exception %s(%s)", name, msg));
jclass cls = env->FindClass(name);
/* if cls is NULL, an exception has already been thrown */
if (cls != NULL) {
env->ThrowNew(cls, msg);
/* free the local ref */
env->DeleteLocalRef(cls);
} else {
debug(("Can't find Exception %s", name));
env->FatalError(name);
}
}
void throwException(JNIEnv *env, const char *name, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vthrowException(env, name, fmt, ap);
va_end(ap);
}
void throwRuntimeException(JNIEnv *env, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vthrowException(env, cRuntimeException, fmt, ap);
va_end(ap);
}
void throwIOException(JNIEnv *env, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vthrowException(env, cIOException, fmt, ap);
va_end(ap);
}
void throwInterruptedIOException(JNIEnv *env, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vthrowException(env, cInterruptedIOException, fmt, ap);
va_end(ap);
}
void throwServiceRegistrationException(JNIEnv *env, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vthrowException(env, cServiceRegistrationException, fmt, ap);
va_end(ap);
}
void throwBluetoothStateException(JNIEnv *env, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vthrowException(env, cBluetoothStateException, fmt, ap);
va_end(ap);
}
void throwBluetoothConnectionException(JNIEnv *env, int error, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
char msg[DEBUG_MESSAGE_MAX+1];
if (env == NULL) {
return;
}
_vsnprintf_s(msg, DEBUG_MESSAGE_MAX, fmt, ap);
if (ExceptionCheckCompatible(env)) {
debug(("ERROR: can't throw second exception %s(%s)", cBluetoothConnectionException, msg));
return;
}
debug(("will throw exception %s(%s)", cBluetoothConnectionException, msg));
jclass cls = env->FindClass(cBluetoothConnectionException);
/* if cls is NULL, an exception has already been thrown */
if (cls != NULL) {
jmethodID methodID = env->GetMethodID(cls, "", "(ILjava/lang/String;)V");
if (methodID == NULL) {
env->FatalError("Fail to get constructor for Exception");
} else {
jstring excMessage = env->NewStringUTF(msg);
jthrowable obj = (jthrowable)env->NewObject(cls, methodID, error, excMessage);
if (obj != NULL) {
env->Throw(obj);
} else {
env->FatalError("Fail to create new Exception");
}
}
/* free the local ref */
env->DeleteLocalRef(cls);
} else {
env->FatalError(cBluetoothConnectionException);
}
va_end(ap);
}
#ifdef WIN32
WCHAR *getWinErrorMessage(DWORD last_error) {
static WCHAR errmsg[DEBUG_MESSAGE_MAX+1];
if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
0,
last_error,
0,
errmsg,
511,
NULL))
{
swprintf_s(errmsg, DEBUG_MESSAGE_MAX, L"No error message for code %lu", last_error);
return errmsg;
}
size_t last = wcslen(errmsg) - 1;
while ((errmsg[last] == '\n') || (errmsg[last] == '\r')) {
errmsg[last] = 0;
last --;
}
return errmsg;
}
void throwExceptionWinErrorMessage(JNIEnv *env, const char *name, const char *msg, DWORD last_error) {
char errmsg[DEBUG_MESSAGE_MAX+1];
sprintf_s(errmsg, DEBUG_MESSAGE_MAX, "%s; [%lu] %S", msg, last_error, getWinErrorMessage(last_error));
throwException(env, name, errmsg);
}
void throwIOExceptionWinErrorMessage(JNIEnv *env, const char *msg, DWORD last_error) {
throwExceptionWinErrorMessage(env, cIOException, msg, last_error);
}
void throwBluetoothStateExceptionWinErrorMessage(JNIEnv *env, const char *msg, DWORD last_error) {
throwExceptionWinErrorMessage(env, cBluetoothStateException, msg, last_error);
}
void throwIOExceptionWinGetLastError(JNIEnv *env, const char *msg) {
throwIOExceptionWinErrorMessage(env, msg, GetLastError());
}
char* waitResultsString(DWORD rc) {
switch (rc) {
case WAIT_FAILED: return "WAIT_FAILED";
case WAIT_TIMEOUT: return "WAIT_TIMEOUT";
case WAIT_OBJECT_0: return "WAIT_OBJECT_0";
case WAIT_OBJECT_0 + 1: return "WAIT_OBJECT_1";
case WAIT_OBJECT_0 + 2: return "WAIT_OBJECT_2";
case WAIT_ABANDONED_0: return "WAIT_ABANDONED_0";
case WAIT_ABANDONED_0 + 1: return "WAIT_ABANDONED_1";
case WAIT_ABANDONED_0 + 2: return "WAIT_ABANDONED_2";
default : return "Unknown";
}
}
#endif
BOOL ExceptionCheckCompatible(JNIEnv *env) {
if (env->GetVersion() > JNI_VERSION_1_1) {
return env->ExceptionCheck();
} else {
return (env->ExceptionOccurred() != NULL);
}
}
BOOL isCurrentThreadInterrupted(JNIEnv *env, jobject peer) {
jclass peerClass = env->GetObjectClass(peer);
if (peerClass == NULL) {
throwRuntimeException(env, "Fail to get Object Class");
return TRUE;
}
jmethodID aMethod = env->GetMethodID(peerClass, "isCurrentThreadInterruptedCallback", "()Z");
if (aMethod == NULL) {
throwRuntimeException(env, "Fail to get MethodID isCurrentThreadInterruptedCallback");
return TRUE;
}
if (env->CallBooleanMethod(peer, aMethod)) {
throwInterruptedIOException(env, "thread interrupted");
return TRUE;
}
return ExceptionCheckCompatible(env);
}
jint detectBluetoothStack(JNIEnv *env) {
jint rc = 0;
#ifdef WIN32
#ifndef VC6
if (isMicrosoftBluetoothStackPresent(env)) {
rc += BLUECOVE_STACK_DETECT_MICROSOFT;
}
#else
if (isMicrosoftBluetoothStackPresentVC6(env)) {
rc += BLUECOVE_STACK_DETECT_MICROSOFT;
}
#endif
if (isWIDCOMMBluetoothStackPresent(env)) {
rc += BLUECOVE_STACK_DETECT_WIDCOMM;
}
#ifndef _WIN32_WCE
if (isBlueSoleilBluetoothStackPresent(env)) {
rc += BLUECOVE_STACK_DETECT_BLUESOLEIL;
}
if (isToshibaBluetoothStackPresent(env)) {
rc += BLUECOVE_STACK_DETECT_TOSHIBA;
}
#endif
#endif
return rc;
}
#ifdef WIN32
void convertUUIDBytesToGUID(jbyte *bytes, GUID *uuid) {
uuid->Data1 = bytes[0]<<24&0xff000000|bytes[1]<<16&0x00ff0000|bytes[2]<<8&0x0000ff00|bytes[3]&0x000000ff;
uuid->Data2 = bytes[4]<<8&0xff00|bytes[5]&0x00ff;
uuid->Data3 = bytes[6]<<8&0xff00|bytes[7]&0x00ff;
for(int i = 0; i < 8; i++) {
uuid->Data4[i] = bytes[i + 8];
}
}
void convertGUIDToUUIDBytes(GUID *uuid, jbyte *bytes) {
bytes[0] = (jbyte)((uuid->Data1>>24) & 0x00ff);
bytes[1] = (jbyte)((uuid->Data1>>16) & 0x00ff);
bytes[2] = (jbyte)((uuid->Data1>>8) & 0x00ff);
bytes[3] = (jbyte)((uuid->Data1) & 0x00ff);
bytes[4] = (jbyte)((uuid->Data2>>8) & 0x00ff);
bytes[5] = (jbyte)((uuid->Data2 & 0x00ff));
bytes[6] = (jbyte)((uuid->Data3>>8) & 0x00ff);
bytes[7] = (jbyte)((uuid->Data3 & 0x00ff));
for(int i = 0; i < 8; i++) {
bytes[i + 8] = uuid->Data4[i];
}
}
#endif
#define MAJOR_COMPUTER 0x0100
#define MAJOR_PHONE 0x0200
#define COMPUTER_MINOR_HANDHELD 0x10
#define PHONE_MINOR_SMARTPHONE 0x0c
jint getDeviceClassByOS(JNIEnv *env) {
#ifndef _WIN32_WCE
return MAJOR_COMPUTER;
#else
OSVERSIONINFO osvi;
TCHAR szPlatform[MAX_PATH];
BOOL rb;
osvi.dwOSVersionInfoSize = sizeof(osvi);
rb = GetVersionEx(&osvi);
if (rb == FALSE) {
return MAJOR_COMPUTER;
}
switch (osvi.dwPlatformId) {
// A Windows CE platform.
case VER_PLATFORM_WIN32_CE:
// Get platform string.
rb = SystemParametersInfo(SPI_GETPLATFORMTYPE, MAX_PATH, szPlatform, 0);
if (rb == FALSE) // SystemParametersInfo failed.
{
return MAJOR_COMPUTER & COMPUTER_MINOR_HANDHELD;
}
debug(("PLATFORMTYPE %S", szPlatform));
if (0 == lstrcmpi(szPlatform, TEXT("Smartphone"))) {
return MAJOR_PHONE | PHONE_MINOR_SMARTPHONE;
}
if (0 == lstrcmpi(szPlatform, TEXT("PocketPC"))) {
return MAJOR_COMPUTER | COMPUTER_MINOR_HANDHELD;
}
}
return MAJOR_COMPUTER;
#endif
}
#ifndef WIN32
void InitializeCriticalSection(CRITICAL_SECTION *criticalRegion) {
MPCreateCriticalRegion(criticalRegion);
}
void DeleteCriticalSection(CRITICAL_SECTION *criticalRegion) {
MPDeleteCriticalRegion(*criticalRegion);
}
void EnterCriticalSection(CRITICAL_SECTION *criticalRegion) {
MPEnterCriticalRegion(*criticalRegion, kDurationForever);
}
void LeaveCriticalSection(CRITICAL_SECTION *criticalRegion) {
MPExitCriticalRegion(*criticalRegion);
}
#endif
ReceiveBuffer::ReceiveBuffer() {
safe = RECEIVE_BUFFER_SAFE;
if (safe) InitializeCriticalSection(&lock);
this->size = RECEIVE_BUFFER_MAX;
reset();
}
ReceiveBuffer::ReceiveBuffer(int size) {
safe = RECEIVE_BUFFER_SAFE;
if (safe) InitializeCriticalSection(&lock);
this->size = size;
if (this->size > RECEIVE_BUFFER_MAX) {
this->size = RECEIVE_BUFFER_MAX;
}
reset();
}
ReceiveBuffer::~ReceiveBuffer() {
if (safe) DeleteCriticalSection(&lock);
magic1b = 0;
magic2b = 0;
magic1e = 0;
magic2e = 0;
}
void ReceiveBuffer::reset() {
rcv_idx = 0;
read_idx = 0;
overflown = FALSE;
full = FALSE;
magic1b = MAGIC_1;
magic2b = MAGIC_2;
magic1e = MAGIC_1;
magic2e = MAGIC_2;
}
BOOL ReceiveBuffer::isCorrupted() {
return ((magic1b != MAGIC_1) || (magic2b != MAGIC_2) || (magic1e != MAGIC_1) || (magic2e != MAGIC_2));
}
BOOL ReceiveBuffer::isOverflown() {
return overflown && (available() == 0);
}
void ReceiveBuffer::setOverflown() {
overflown = TRUE;
}
int ReceiveBuffer::write_buffer(void *p_data, int len) {
if (overflown) {
return 0;
}
int accept;
int _read_idx = read_idx;
if ((_read_idx == rcv_idx) && full) {
accept = 0;
} else if (_read_idx <= rcv_idx) {
accept = size - rcv_idx + _read_idx;
} else {
accept = _read_idx - rcv_idx;
}
if (accept > len) {
accept = len;
} else if (accept < len) {
overflown = TRUE;
}
if (accept != 0) {
if (rcv_idx + accept <= size) {
memcpy((buffer + rcv_idx), p_data, accept);
int new_rcv_idx = rcv_idx + accept;
if (new_rcv_idx >= size) {
new_rcv_idx = 0;
}
rcv_idx = new_rcv_idx;
} else {
// Read first part till the end of the buffer.
int accept_fill_end_size = size - rcv_idx;
memcpy((buffer + rcv_idx), p_data, accept_fill_end_size);
// Read second part at the beginning of the buffer.
int accept_fill_begin_size = accept - accept_fill_end_size;
memcpy(buffer, ((jbyte*)p_data + accept_fill_end_size), accept_fill_begin_size);
rcv_idx = accept_fill_begin_size;
}
if (read_idx == rcv_idx) {
full = TRUE;
}
}
return accept;
}
int ReceiveBuffer::write(void *p_data, int len) {
if (overflown) {
return 0;
}
if (safe) EnterCriticalSection(&lock);
int accept = write_buffer(p_data, len);
if (safe) LeaveCriticalSection(&lock);
return accept;
}
int ReceiveBuffer::write_with_len(void *p_data, int len) {
if (overflown) {
return 0;
}
if (safe) EnterCriticalSection(&lock);
int accept = write_buffer(&len, sizeof(int));
accept += write_buffer(p_data, len);
if (safe) LeaveCriticalSection(&lock);
return accept;
}
void ReceiveBuffer::incReadIdx(int count) {
int next_read_idx = read_idx + count;
if (next_read_idx >= size) {
next_read_idx -= size;
}
read_idx = next_read_idx;
full = FALSE;
}
int ReceiveBuffer::readByte() {
if (available() == 0) {
return -1;
}
if (safe) EnterCriticalSection(&lock);
jint result = (unsigned char)buffer[read_idx];
incReadIdx(1);
if (safe) LeaveCriticalSection(&lock);
return result;
}
int ReceiveBuffer::sizeof_len() {
return sizeof(int);
}
int ReceiveBuffer::read_len(int* len) {
return read(len, sizeof(int));
}
int ReceiveBuffer::read(void *p_data, int len) {
int count = available();
if (count == 0) {
return 0;
}
if (safe) EnterCriticalSection(&lock);
if (count > len) {
count = len;
}
if (read_idx + count < size) {
if (p_data != NULL) {
memcpy(p_data, (buffer + read_idx), count);
}
} else {
// Read first part from the end of the buffer.
int accept_fill_end_size = size - read_idx;
if (p_data != NULL) {
memcpy(p_data, (buffer + read_idx), accept_fill_end_size);
}
// Read second part from the beginning of the buffer.
int accept_fill_begin_size = count - accept_fill_end_size;
if (p_data != NULL) {
memcpy((jbyte*)p_data + accept_fill_end_size, buffer, accept_fill_begin_size);
}
}
incReadIdx(count);
if (safe) LeaveCriticalSection(&lock);
return count;
}
int ReceiveBuffer::skip(int n) {
return read(NULL, n);
}
int ReceiveBuffer::available() {
if (safe) EnterCriticalSection(&lock);
int rc;
int _rcv_idx = rcv_idx;
int _read_idx = read_idx;
if ((_read_idx == _rcv_idx) && full) {
rc = size;
} else if (_read_idx <= _rcv_idx) {
rc = (_rcv_idx - _read_idx);
} else {
rc = (_rcv_idx + (size - _read_idx));
}
if (safe) LeaveCriticalSection(&lock);
return rc;
}
// --------- ObjectPool -------------
PoolableObject::PoolableObject() {
magic1 = MAGIC_1;
magic2 = MAGIC_2;
internalHandle = -1;
usedCount = 0;
readyToFree = FALSE;
}
PoolableObject::~PoolableObject() {
magic1 = 0;
magic2 = 0;
#ifdef SAFE_OBJECT_DESTRUCTION
// Do not allow to free the object until thre are no functions in wait using it. e.g. read and write
while (usedCount > 0) {
Sleep(50);
}
#endif
}
void PoolableObject::tInc() {
#ifdef SAFE_OBJECT_DESTRUCTION
InterlockedIncrement(&usedCount);
#endif
}
void PoolableObject::tDec() {
#ifdef SAFE_OBJECT_DESTRUCTION
InterlockedDecrement(&usedCount);
#endif
}
BOOL PoolableObject::isValidObject() {
return ((magic1 == MAGIC_1) && (magic2 == MAGIC_2));
}
BOOL PoolableObject::isExternalHandle(jlong handle) {
return FALSE;
}
ObjectPool::ObjectPool(int size, int handleOffset, BOOL delayDelete) {
InitializeCriticalSection(&lock);
this->size = size;
this->handleOffset = handleOffset;
this->delayDelete = delayDelete;
this->handleReturned = 0;
this->handleBatch = 0;
handleMove = 0;
objs = new (PoolableObject* [size]);
for(int i = 0; i < size; i ++) {
objs[i] = NULL;
}
}
ObjectPool::~ObjectPool() {
EnterCriticalSection(&lock);
PoolableObject** __objs = objs;
objs = NULL;
for(int i = 0; i < size; i ++) {
if (__objs[i] != NULL) {
PoolableObject* o = __objs[i];
__objs[i] = NULL;
delete o;
}
}
delete __objs;
LeaveCriticalSection(&lock);
DeleteCriticalSection(&lock);
}
jlong ObjectPool::realIndex(jlong internalHandle) {
return (internalHandle - handleOffset) % size;
}
jlong ObjectPool::realIndex(PoolableObject* obj) {
return realIndex(obj->internalHandle);
}
BOOL ObjectPool::addObject(PoolableObject* obj) {
//ndebug(("new Object %p", obj));
EnterCriticalSection(&lock);
if (objs == NULL) {
LeaveCriticalSection(&lock);
return FALSE;
}
int freeIndex = -1;
for(int k = 0; k < size; k++) {
int i = k + handleMove;
if (i >= size) {
i -= size;
}
if (delayDelete && (objs[i] != NULL)) {
if (objs[i]->readyToFree) {
delete objs[i];
objs[i] = NULL;
}
}
if (objs[i] == NULL) {
freeIndex = i;
objs[freeIndex] = obj;
long newHandle = handleOffset + freeIndex + handleBatch * size;
while (newHandle <= handleReturned) {
newHandle += size;
handleBatch ++;
}
// Start all over from start
if (newHandle >= INT_MAX) {
newHandle = handleOffset + freeIndex;
handleBatch = 0;
}
handleReturned = (int)newHandle;
obj->internalHandle = (int)newHandle;
handleMove ++;
if (handleMove >= size) {
handleMove = 0;
}
LeaveCriticalSection(&lock);
return TRUE;
}
}
LeaveCriticalSection(&lock);
return FALSE;
}
BOOL ObjectPool::hasObject(PoolableObject* obj) {
for(int i = 0; (objs != NULL) && (i < size); i++) {
if ((void*)objs[i] == (void*)obj) {
return TRUE;
}
}
return FALSE;
}
BOOL ObjectPool::addObject(PoolableObject* obj, char poolableObjectType) {
obj->poolableObjectType = poolableObjectType;
return addObject(obj);
}
PoolableObject* ObjectPool::getObject(JNIEnv *env, jlong handle) {
if ((handle <= 0) || (objs == NULL)) {
throwIOException(env, "[EAO] Invalid handle %i", handle);
return NULL;
}
jlong idx = realIndex(handle);
if ((idx < 0) || (idx >= size)) {
throwIOException(env, "[EAO] Obsolete handle %i", handle);
return NULL;
}
PoolableObject* o = objs[idx];
if (o == NULL) {
throwIOException(env, "[EAO] Destroyed handle %i", handle);
return NULL;
}
if (o->readyToFree) {
throwIOException(env, "[EAO] Delay delete object access %i", handle);
return NULL;
}
if ((o->magic1 != MAGIC_1) || (o->magic2 != MAGIC_2)) {
throwIOException(env, "[EAO] Corrupted object %i", handle);
return NULL;
}
if ((o->internalHandle != handle) || (!o->isValidObject())) {
throwIOException(env, "[EAO] Corrupted handle %i", handle);
return NULL;
}
return o;
}
PoolableObject* ObjectPool::getObject(JNIEnv *env, jlong handle, char poolableObjectType) {
PoolableObject* o = getObject(env, handle);
if ((o != NULL) && (o->poolableObjectType != poolableObjectType)) {
throwIOException(env, "[EAO] Invalid handle type %i", handle);
return NULL;
}
return o;
}
PoolableObject* ObjectPool::getObjectByExternalHandle(jlong handle) {
for(int i = 0; (objs != NULL) && (i < size); i ++) {
if (objs[i] != NULL) {
PoolableObject* o = objs[i];
if (o->isExternalHandle(handle)) {
return o;
}
}
}
return NULL;
}
void ObjectPool::removeObject(PoolableObject* obj) {
jlong idx = realIndex(obj);
if ((idx >= 0) && (idx < size) && (objs != NULL)) {
objs[idx] = NULL;
}
}
DeviceInquiryCallback::DeviceInquiryCallback() {
this->peer = NULL;
this->deviceDiscoveredCallbackMethod = NULL;
this->startedNotify = NULL;
this->startedNotifyNotifyMethod = NULL;
}
BOOL DeviceInquiryCallback::builDeviceInquiryCallbacks(JNIEnv * env, jobject peer, jobject startedNotify) {
jclass peerClass = env->GetObjectClass(peer);
if (peerClass == NULL) {
throwRuntimeException(env, "Fail to get Object Class");
return FALSE;
}
jmethodID deviceDiscoveredCallbackMethod = env->GetMethodID(peerClass, "deviceDiscoveredCallback", "(Ljavax/bluetooth/DiscoveryListener;JILjava/lang/String;Z)V");
if (deviceDiscoveredCallbackMethod == NULL) {
throwRuntimeException(env, "Fail to get MethodID deviceDiscoveredCallback");
return FALSE;
}
jclass notifyClass = env->GetObjectClass(startedNotify);
if (notifyClass == NULL) {
throwRuntimeException(env, "Fail to get Object Class");
return FALSE;
}
jmethodID notifyMethod = env->GetMethodID(notifyClass, "deviceInquiryStartedCallback", "()V");
if (notifyMethod == NULL) {
throwRuntimeException(env, "Fail to get MethodID deviceInquiryStartedCallback");
return FALSE;
}
this->peer = peer;
this->deviceDiscoveredCallbackMethod = deviceDiscoveredCallbackMethod;
this->startedNotify = startedNotify;
this->startedNotifyNotifyMethod = notifyMethod;
return TRUE;
}
BOOL DeviceInquiryCallback::callDeviceInquiryStartedCallback(JNIEnv * env) {
if ((this->startedNotify == NULL) || (this->startedNotifyNotifyMethod == NULL)) {
throwRuntimeException(env, "DeviceInquiryCallback not initialized");
return FALSE;
}
env->CallVoidMethod(this->startedNotify, this->startedNotifyNotifyMethod);
if (ExceptionCheckCompatible(env)) {
return FALSE;
} else {
return TRUE;
}
}
BOOL DeviceInquiryCallback::callDeviceDiscovered(JNIEnv * env, jobject listener, jlong deviceAddr, jint deviceClass, jstring name, jboolean paired) {
if ((this->peer == NULL) || (this->deviceDiscoveredCallbackMethod == NULL)) {
throwRuntimeException(env, "DeviceInquiryCallback not initialized");
return FALSE;
}
env->CallVoidMethod(this->peer, this->deviceDiscoveredCallbackMethod, listener, deviceAddr, deviceClass, name, paired);
if (ExceptionCheckCompatible(env)) {
return FALSE;
} else {
return TRUE;
}
}