text: /*
   * UVCCamera
   * library and sample to access to UVC web camera on non-rooted Android device
   *
   * Copyright (c) 2014-2016 saki t_saki@serenegiant.com
   *
   * File name: utilbase.h
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   * All files in the folder are under this Apache License, Version 2.0.
   * Files in the jni/libjpeg, jni/libusb, jin/libuvc, jni/rapidjson folder may have a different license, see the respective files.
  */
  
  #ifndef UTILBASE_H_
  #define UTILBASE_H_
  
  #include <jni.h>
  #ifdef __ANDROID__
  #include <android/log.h>
  #endif
  #include <unistd.h>
  #include <libgen.h>
  #include "localdefines.h"
  
  #define		SAFE_FREE(p)				{ if (p) { free((p)); (p) = NULL; } }
  #define		SAFE_DELETE(p)				{ if (p) { delete (p); (p) = NULL; } }
  #define		SAFE_DELETE_ARRAY(p)		{ if (p) { delete [](p); (p) = NULL; } }
  #define		NUM_ARRAY_ELEMENTS(p)		((int) sizeof(p) / sizeof(p[0]))
  
  #if defined(__GNUC__)
  // the macro for branch prediction optimaization for gcc(-O2/-O3 required)
  #define		CONDITION(cond)				((__builtin_expect((cond)!=0, 0)))
  #define		LIKELY(x)					((__builtin_expect(!!(x), 1)))	// x is likely true
  #define		UNLIKELY(x)					((__builtin_expect(!!(x), 0)))	// x is likely false
  #else
  #define		CONDITION(cond)				((cond))
  #define		LIKELY(x)					((x))
  #define		UNLIKELY(x)					((x))
  #endif
  
  // XXX assertはNDEBUGが定義されていたら引数を含めて丸ごと削除されてしまうので
  // 関数実行を直接assertの引数にするとその関数はNDEBUGの時に実行されなくなるので注意
  #include <assert.h>
  #define CHECK(CONDITION) { bool RES = (CONDITION); assert(RES); }
  #define CHECK_EQ(X, Y) { bool RES = (X == Y); assert(RES); }
  #define CHECK_NE(X, Y) { bool RES = (X != Y); assert(RES); }
  #define CHECK_GE(X, Y) { bool RES = (X >= Y); assert(RES); }
  #define CHECK_GT(X, Y) { bool RES = (X > Y); assert(RES); }
  #define CHECK_LE(X, Y) { bool RES = (X <= Y); assert(RES); }
  #define CHECK_LT(X, Y) { bool RES = (X < Y); assert(RES); }
  
  #if defined(USE_LOGALL) && defined(__ANDROID__) && !defined(LOG_NDEBUG)
  	#define LOGV(FMT, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
  							gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  	#define LOGD(FMT, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
  							gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  	#define LOGI(FMT, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
  							gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  	#define LOGW(FMT, ...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
  							gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  	#define LOGE(FMT, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
  							gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  	#define LOGF(FMT, ...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
  							gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  	#define LOGV_IF(cond, ...) \
  		( (CONDITION(cond)) \
  			? LOGV(__VA_ARGS__) \
  			: (0) )
  	#define LOGD_IF(cond, ...) \
  		( (CONDITION(cond)) \
  			? LOGD(__VA_ARGS__) \
  			: (0) )
  	#define LOGI_IF(cond, ...) \
  		( (CONDITION(cond)) \
  			? LOGI(__VA_ARGS__) \
  			: (0) )
  	#define LOGW_IF(cond, ...) \
  		( (CONDITION(cond)) \
  			? LOGW(__VA_ARGS__) \
  			: (0) )
  	#define LOGE_IF(cond, ...) \
  		( (CONDITION(cond)) \
  			? LOGE(__VA_ARGS__) \
  			: (0) )
  	#define LOGF_IF(cond, ...) \
  		( (CONDITION(cond)) \
  			? LOGF(__VA_ARGS__) \
  			: (0) )
  #else
  	#if defined(USE_LOGV) && defined(__ANDROID__) && !defined(LOG_NDEBUG)
  		#define LOGV(FMT, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
           	 	 	 	 	 	 gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  		#define LOGV_IF(cond, ...) \
  			( (CONDITION(cond)) \
  			? LOGV(__VA_ARGS__) \
  			: (0) )
  		#else
  		#define LOGV(...)
  		#define LOGV_IF(cond, ...)
  	#endif
  	#if defined(USE_LOGD) && defined(__ANDROID__) && !defined(LOG_NDEBUG)
  		#define LOGD(FMT, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
           	 	 	 	 	 	 gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  		#define LOGD_IF(cond, ...) \
  			( (CONDITION(cond)) \
  			? LOGD(__VA_ARGS__) \
  			: (0) )
  	#else
  		#define LOGD(...)
  		#define LOGD_IF(cond, ...)
  	#endif
  	#if defined(USE_LOGI) && defined(__ANDROID__)
  		#define LOGI(FMT, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
           	 	 	 	 	 	 gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  		#define LOGI_IF(cond, ...) \
  			( (CONDITION(cond)) \
  			? LOGI(__VA_ARGS__) \
  			: (0) )
  	#else
  		#define LOGI(...)
  		#define LOGI_IF(cond, ...)
  	#endif
  	#if defined(USE_LOGW) && defined(__ANDROID__)
  		#define LOGW(FMT, ...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
           	 	 	 	 	 	 gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  		#define LOGW_IF(cond, ...) \
  			( (CONDITION(cond)) \
  			? LOGW(__VA_ARGS__) \
  			: (0) )
  	#else
  		#define LOGW(...)
  		#define LOGW_IF(cond, ...)
  	#endif
  	#if defined(USE_LOGE) && defined(__ANDROID__)
  		#define LOGE(FMT, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
           	 	 	 	 	 	 gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  		#define LOGE_IF(cond, ...) \
  			( (CONDITION(cond)) \
  			? LOGE(__VA_ARGS__) \
  			: (0) )
  	#else
  		#define LOGE(...)
  		#define LOGE_IF(cond, ...)
  	#endif
  	#if defined(USE_LOGF) && defined(__ANDROID__)
  		#define LOGF(FMT, ...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "[%d*%s:%d:%s]:" FMT,	\
           	 	 	 	 	 	 gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  		#define LOGF_IF(cond, ...) \
  			( (CONDITION(cond)) \
  			? LOGF(__VA_ARGS__) \
  			: (0) )
  	#else
  		#define LOGF(...)
  		#define LOGF_IF(cond, ...)
  	#endif
  #endif
  
  #ifndef		LOG_ALWAYS_FATAL_IF
  #define		LOG_ALWAYS_FATAL_IF(cond, ...) \
  				( (CONDITION(cond)) \
  				? ((void)__android_log_assert(#cond, LOG_TAG, ## __VA_ARGS__)) \
  				: (void)0 )
  #endif
  
  #ifndef		LOG_ALWAYS_FATAL
  #define		LOG_ALWAYS_FATAL(...) \
  				( ((void)__android_log_assert(NULL, LOG_TAG, ## __VA_ARGS__)) )
  #endif
  
  #ifndef		LOG_ASSERT
  #define		LOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
  #endif
  
  #ifdef LOG_NDEBUG
  
  #ifndef		LOG_FATAL_IF
  #define		LOG_FATAL_IF(cond, ...) ((void)0)
  #endif
  #ifndef		LOG_FATAL
  #define		LOG_FATAL(...) ((void)0)
  #endif
  
  #else
  
  #ifndef		LOG_FATAL_IF
  #define		LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
  #endif
  #ifndef		LOG_FATAL
  #define		LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
  #endif
  
  #endif
  
  #define		ENTER()				LOGD("begin")
  #define		RETURN(code,type)	{type RESULT = code; LOGD("end (%d)", (int)RESULT); return RESULT;}
  #define		RET(code)			{LOGD("end"); return code;}
  #define		EXIT()				{LOGD("end"); return;}
  #define		PRE_EXIT()			LOGD("end")
  
  #if defined(__ANDROID__) && (defined(USE_LOGALL) || defined(USE_LOGI)) && !defined(LOG_NDEBUG)
  #define MARK(FMT, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "[%s:%d:%s]:" FMT,	\
  						basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
  #else
  #define		MARK(...)
  #endif
  
  #define LITERAL_TO_STRING_INTERNAL(x)    #x
  #define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x)
  
  #define TRESPASS() \
  		LOG_ALWAYS_FATAL(                                       \
  			__FILE__ ":" LITERAL_TO_STRING(__LINE__)            \
  			" Should not be here.");
  
  void setVM(JavaVM *);
  JavaVM *getVM();
  JNIEnv *getEnv();
  
  #endif /* UTILBASE_H_ */
  