#ifndef __GT_TOOLKIT_EXT_H__
#define __GT_TOOLKIT_EXT_H__
#include <jni.h>

class GtToolkitExt
{
    public:
        /************************************************************
        *功能：获取接口版本
        *输入：无
        *输出：无
        *返回：版本号（主版本 << 16 | 中间版本 << 8 | 小版本）
        */        
        static int version();
        
        /************************************************************
        *功能：获取全局唯一流水号（线程安全）
        *输入：无
        *输出：无
        *返回：流水号
        */
        static unsigned long uniqueSerialNumber();
        
        /************************************************************
        *功能：超时等待
        *输入：fd=文件句柄
        *输入：timeout=超时时间（秒）
        *输出：无
        *返回：!=0错误
        */
        static int waitFor(int fd, int timeout);
        
        /************************************************************
        *功能：读取数据
        *输入：fd=文件句柄
        *输入：n=需要读取的数据长度
        *输入：timeout=超时时间（秒）
        *输出：data=读取到的数据
        *返回：!=0错误
        */
        static ssize_t readN(int fd, void *data, size_t n, int timeout);
        
        /************************************************************
        *功能：写入数据
        *输入：fd=文件句柄
        *输入：data=需要写入的数据
        *输入：n=需要写入的数据长度
        *输入：timeout=超时时间（秒）
        *输出：无
        *返回：!=0错误
        */
        static ssize_t writeN(int fd, const void *data, size_t n);
        
        /************************************************************
        *功能：字符串中获取第n-1到第n个分隔符之间的字符串
        *输入：inStr=字符串
        *输入：outBufLen=输出缓存大小
        *输入：delimiter=分隔符
        *输入：n=第n个分隔符（n>=1）
        *输出：outStr=获取到的字符串
        *返回：!=0错误
        */
        static int parseNChar(char *inStr, char *outStr, int outBufLen, char delimiter, int n);
        
        /************************************************************
        *功能：字符串中获取第n-1到第n个分隔符之间的字符串
        *输入：inStr=字符串
        *输入：outBufLen=输出缓存大小
        *输入：delimiter=分隔符字符串
        *输入：n=第n个分隔符（n>=1）
        *输出：outStr=获取到的字符串
        *返回：!=0错误
        */
        static int parseNString(char *inStr, char *outStr, int outBufLen, char* delimiter, int n);
        
        /************************************************************
        *功能：字符串中获取第n个分隔符索引
        *输入：inStr=字符串
        *输入：delimiter=分隔符字符串
        *输入：n=第n个分隔符（n>=1）
        *输出：无
        *返回：<0错误
        */
        static int parseNCharIndex(char *inStr, char delimiter, int n);
        
        /************************************************************
        *功能：字符串排序
        *输入：str=需排序字符串
        *输入：n=需排序的个数
        *输入：mode=[12]升序，[21]降序
        *输出：无
        *返回：!=0错误
        */
        static int sortChar(unsigned char *str, int n, int mode);
        
        /************************************************************
        *功能：X个选择Y个的组合数
        *输入：x
        *输入：y
        *输出：无
        *返回：组合数
        */
        static int cXY(int x, int y);
        
        /************************************************************
        *功能：gbk编码转utf8编码
        *输入：src=需转换的gbk编码字符串
        *输入：inLen=需转换的gbk字符串长度
        *输入：bufLen=转换utf8的缓存长度
        *输出：des=转换为utf8的字符串
        *输出：outLen=转换为utf8的字符串长度
        *返回：!=0错误
        */
        static int gbkToUtf8(char *src, int32_t inLen, char *des, int32_t bufLen, int *outLen);
        
        /************************************************************
        *功能：utf8编码转gbk编码
        *输入：src=需转换的utf8编码字符串
        *输入：inLen=需转换的utf8字符串长度
        *输入：bufLen=转换gbk的缓存长度
        *输出：des=转换为gbk的字符串
        *输出：outLen=转换为gbk的字符串长度
        *返回：!=0错误
        */
        static int utf8ToGbk(char *src, int32_t inLen, char *des, int32_t bufLen, int *outLen);
        
        /************************************************************
        *功能：十六进制转可视字符
        *输入：src=需转换十六进制值
        *输入：length=需转换的长度
        *输入：bufLen=转换后缓存长度
        *输出：desBuf=转换后的字符串
        *返回：!=0错误
        */
        static int hexToStr(unsigned char *src, int length, char *desBuf, int bufLen);
        
        /************************************************************
        *功能：十六进制字符串转十进制
        *输入：src=需转换十六进制字符串
        *输出：value=转换后的十进制值
        *返回：!=0错误
        */
        static int hexStrToInt(unsigned char *src, int *value);
        
        /************************************************************
        *功能：可视字符转十六进制
        *输入：src=需转换可视字符
        *输入：length=需转换的长度
        *输入：bufLen=转换后缓存长度
        *输出：desBuf=转换后的字符串
        *返回：!=0错误
        */
        static int strToHex(unsigned char *src, int length, unsigned char *desBuf);
        
        /************************************************************
        *功能：日期转换
        *输入：srcTime=需转换时间
        *输入：format=需要转换的格式（yyyy-MM-dd,yyyy/MM/dd等）
        *输出：des=转换后的时间
        *返回：!=0错误
        */
        static int convertTime(char *srcTime, char *format, time_t *desTime);
        
        /************************************************************
        *功能：日期转换
        *输入：srcTime=需转换时间
        *输入：format=需要转换的格式（yyyy-MM-dd,yyyy/MM/dd等）
        *输出：des=转换后的时间
        *返回：!=0错误
        */
        static int formatDate(time_t srcTime, char *format, char *des);
        
        /************************************************************
        *功能：日期时间转换
        *输入：srcTime=需转换时间
        *输入：format=需要转换的格式（yyyy-MM-dd hh:mm:ss,yyyy/MM/dd-hh:mm:ss等）
        *输出：des=转换后的时间
        *返回：!=0错误
        */
        static int formatDateTime(time_t srcTime, char *format, char *des);
        
        /************************************************************
        *功能：产生一个指定范围的随机数
        *输入：min最小数（min >= 0）
        *输入：max最大数（max >= 0）
        *输出：无
        *返回：随机数
        */
        static int randomN(int min, int max);
        
        /************************************************************
        *功能：产生随机验证码
        *输入：bufLen=缓存长度
        *输出：buf=随机验证码（格式为：随机码;验证码）
        *返回：无
        */
        static void randomIdentifyingCode(char *buf, int bufLen);

        /************************************************************
         *网络工具类
         */
        /************************************************************
        *功能：创建tcp协议socket
        *输入：无
        *输出：socketFd=已创建的socket句柄
        *返回：!=0错误
        */
        static int tcpSocket(int *socketFd);
        
        /************************************************************
        *功能：TCP网络连接
        *输入：socketFd=有效的socket句柄
        *输入：ip=服务器ip地址
        *输入：port=服务器端口
        *输入：timeout=超时时间（秒）
        *输出：无
        *返回：!=0错误
        */
        static int tcpConnect(int socketFd, char *ip, unsigned short port, int timeout);
        
        /************************************************************
        *功能：绑定并监听socket
        *输入：socketFd=有效的socket句柄
        *输入：listenSize=监听的队列大小
        *输入：ip=监听的ip地址
        *输入：port=监听的端口
        *输出：无
        *返回：!=0错误
        */
        static int tcpListen(int socketFd, int listenSize, char *ip, unsigned short port);
        
        /************************************************************
        *功能：接受TCP网络连接请求
        *输入：socketFd=监听的socket句柄
        *输出：connectFd=新的socket句柄
        *输出：connectIp=请求连接的ip地址
        *返回：!=0错误
        */
        static int tcpAccept(int socketFd, int *connectFd, char *connectIp);

        /************************************************************
         *文件工具类
         */
        /************************************************************
        *功能：文件是否存在
        *输入：fileName=文件路径名称
        *输出：无
        *返回：=0文件存在，!=0文件不存在
        */
        static int isFileExist(const char *fileName);
        
        /************************************************************
        *功能：获取文件大小
        *输入：fileName=文件路径名称
        *输出：无
        *返回：<0错误,>=0文件大小
        */
        static int getFileSize(const char *fileName);
        
        /************************************************************
        *功能：文件目录是否存在
        *输入：dirName=文件目录名称
        *输出：无
        *返回：=0目录存在，!=0目录不存在
        */
        static int dirIsExist(char *dirName);
        
        /************************************************************
        *功能：获取当前目录
        *输入：length=缓存长度
        *输出：dirName=文件目录名称
        *返回：!=0错误
        */
        static int currentDir(char *dirName, int length);
        
        /************************************************************
        *功能：创建目录，默认属性为0744
        *输入：dirName=文件目录名称
        *输出：无
        *返回：!=0错误
        */
        static int mkDir(char *dirName);
        
        /************************************************************
        *功能：检查当前文件大小，如果超出制定大小，默认10M，则重命名当前文件后缀为.old保存
        *输入：fileName=文件路径名称
        *输入：size=文件限制大小（单位：M）
        *输出：无
        *返回：无
        */
        static void limitFileSize(const char *fileName, int size = 10);
        
        /************************************************************
        *功能：写文件并且同步到磁盘,覆盖写
        *输入：fileName=文件路径名称
        *输入：buf=写入内容
        *输入：length=写入内容长度
        *输出：无
        *返回：!=0错误
        */
        static int writeSyncFile(const char *fileName, const void *buf, int length);
        
        /************************************************************
        *功能：写文件，追加写
        *输入：fileName=文件路径名称
        *输入：buf=写入内容
        *输入：length=写入内容长度
        *输出：无
        *返回：!=0错误
        */
        static int appendWriteFile(const char *fileName, const void *buf, int length);
        
        /************************************************************
        *功能：清除文件并且同步到磁盘，置文件长度为0
        *输入：fileName=文件路径名称
        *输出：无
        *返回：!=0错误
        */
        static int truncateSyncIOFile(const char *fileName);
        
        /************************************************************
        *功能：读取文件内容
        *输入：fileName=文件路径名称
        *输入：length=读入内容长度
        *输出：buf=读入内容
        *返回：!=0错误
        */
        static int readFile(const char *fileName, void *buf, int length);
        
        /************************************************************
        *功能：从指定文件读取指定属性
        *输入：fileName=文件路径名称
        *输入：attr=属性字段名称
        *输出：str=属性字段值
        *返回：!=0错误
        */
        static int readAttrFromFile(const char *fileName, const char *attr, char *str);
        
        /************************************************************
        *功能：写入指定字段值到文件
        *输入：fileName=文件路径名称
        *输入：attr=属性字段名称
        *输入：str=写入的字段内容
        *输出：无
        *返回：!=0错误
        */
        static int writeAttrCfgFile(const char *fileName, const char *attr, const char *str);
        
        /************************************************************
        *功能：写交易日志文件
        *输入：fileName=文件路径名称
        *输入：log=写入日志内容
        *输出：无
        *返回：!=0错误
        */
        static int tradingLogFile(const char *fileName, char *log, int logSize);
        
        /************************************************************
        *功能：写错误日志文件
        *输入：fileName=文件路径名称
        *输入：tag=日志标签
        *输入：line=行数
        *输入：logStr=日志数据
        *输出：无
        *返回：!=0错误
        */
        static int errorLogFile(const char *fileName, char *tag, char *logStr);

        /************************************************************
         *日志工具类
         */
        /************************************************************
        *功能：普通日志信息打印
        *输入：tag=日志标签
        *输入：str=日志信息
        *输出：无
        *返回：无
        */
        static void logInfo(const char *fileName, const int line, const char *str, ...);
        
        /************************************************************
        *功能：警告日志信息打印
        *输入：tag=日志标签
        *输入：str=日志信息
        *输出：无
        *返回：无
        */
        static void logWarn(const char *fileName, const int line, const char *str, ...);
        
        /************************************************************
        *功能：错误日志信息打印
        *输入：tag=日志标签
        *输入：str=日志信息
        *输出：无
        *返回：无
        */
        static void logError(const char *fileName, const int line, const char *str, ...);

        /************************************************************
         *信号量工具类
         */
        /************************************************************
        *功能：信号量等待操作
        *输入：name有名信号量
        *输入：timeout等待超时时间
        *输出：无
        *返回：无
        */
        static int semWait(char *name, int timeout);

        /************************************************************
        *功能：信号量等待操作
        *输入：name有名信号量
        *输入：无
        *输出：无
        *返回：无
        */
        static int semPost(char *name);

        /************************************************************
         *jni工具类
         */
        /************************************************************
        *功能：读取Assets目录文件
        *输入：env=虚拟机环境
        *输入：obj=AssetManager对象
        *输入：fileName=文件名称
        *输出：buf=数据
        *输出：length=数据长度
        *返回：!=0错误
        */
        static int readAssetFile(JNIEnv *env, jobject obj, char *fileName, char *buf, int *length);

        /************************************************************
        *功能：读取Assets目录BMP文件，并转换成位图数据（buf空间需手动释放）
        *输入：env=虚拟机环境
        *输入：obj=AssetManager对象
        *输入：fileName=文件名称
        *输出：buf=图片数据
        *输出：length=图片数据长度
        *输出：width=图片宽度
        *输出：height=图片高度
        *返回：!=0错误
        */
        static int readAssetBMP(JNIEnv *env, jobject obj, char *fileName, char **buf, int *length, int *width, int *height);
        
        /************************************************************
        *功能：java对象中int字段转c int值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的int类型字段名称
        *输出：value=转换后的c int值
        *返回：!=0错误
        */
        static int jIntCInt(JNIEnv *env, jobject obj, char *tag, int *value);
        
        /************************************************************
        *功能：java对象中long字段转c long值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的long类型字段名称
        *输出：value=转换后的c long值
        *返回：!=0错误
        */
        static int jLongCLong(JNIEnv *env, jobject obj, char *tag, long *value);
        
        /************************************************************
        *功能：java对象中double字段转c double值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的double类型字段名称
        *输出：value=转换后的c double值
        *返回：!=0错误
        */
        static int jDoubleCDouble(JNIEnv *env, jobject obj, char *tag, double *value);
        
        /************************************************************
        *功能：java对象中String字段转c char[]值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的char[]类型字段名称
        *输出：value=转换后的c char[]值
        *返回：!=0错误
        */
        static int jStringCCharArray(JNIEnv *env, jobject obj, char *tag, char *buf, int bufLen);
        
        /************************************************************
        *功能：java对象中String[]字段转c char[][]值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的char[][]类型字段名称
        *输出：buf=转换后的c char[][]值
        *返回：!=0错误
        */
        static int jStringArrayCCharArray2(JNIEnv *env, jobject obj, char *tag, char buf[][256]);
        
        /************************************************************
        *功能：java对象中byte[]字段转c char[]值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的char[]类型字段名称
        *输出：buf=转换后的c char[]值
        *返回：!=0错误
        */
        static int jByteArrayCCharArray(JNIEnv *env, jobject obj, char *tag, char *buf, int bufLen);
        
        /************************************************************
        *功能：java对象中byte[][]字段转c char[][]值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的char[][]类型字段名称
        *输出：buf=转换后的c char[][]值
        *返回：!=0错误
        */
        static int jByteArray2CCharArray2(JNIEnv *env, jobject obj, char *tag, char buf[][256], int *outLen);
        
        /************************************************************
        *功能：java对象中long[]字段转c long[]值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的long[]类型字段名称
        *输出：buf=转换后的c long[]值
        *返回：!=0错误
        */
        static int jLongArrayCLongArray(JNIEnv *env, jobject obj, char *tag, long *buf, int bufLen);
        
        /************************************************************
        *功能：java对象中int[]字段转c int[]值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的int[]类型字段名称
        *输出：buf=转换后的c int[]值
        *返回：!=0错误
        */
        static int jIntArrayCIntArray(JNIEnv *env, jobject obj, char *tag, int *buf, int bufLen);
        
        /************************************************************
        *功能：java对象中int[][]字段转c int[][]值
        *输入：env=虚拟机环境
        *输入：obj=java对象
        *输入：tag=java对象需要转换的int[][]类型字段名称
        *输出：buf=转换后的c int[][]值
        *返回：!=0错误
        */
        static int jIntArray2CIntArray2(JNIEnv *env, jobject obj, char *tag, int buf[][256], int *outLen);
        
        /************************************************************
        *功能：c int 转 java对象中的int字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的int类型字段名称
        *输入：value=c int值
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cIntJInt(JNIEnv *env, jobject obj, char *tag, int value);
        
        /************************************************************
        *功能：c long 转 java对象中的long字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的long类型字段名称
        *输入：value=c long值
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cLongJLong(JNIEnv *env, jobject obj, char *tag, long value);
        
        /************************************************************
        *功能：c double 转 java对象中的double字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的double类型字段名称
        *输入：value=c double值
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cDoubleJDouble(JNIEnv *env, jobject obj, char *tag, double value);
        
        /************************************************************
        *功能：c char[] 转 java对象中的String字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的String类型字段名称
        *输入：value=c char[]值
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cCharArrayJString(JNIEnv *env, jobject obj, char *tag, char *value);
        
        /************************************************************
        *功能：c char[] 转 java对象中的byte[]字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的byte[]类型字段名称
        *输入：value=c char[]值
        *输入：length=char[]缓存长度
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cCharArrayJByteArray(JNIEnv *env, jobject obj, char *tag, char *value, int length);
        
        /************************************************************
        *功能：c int[] 转 java对象中的int[]字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的int[]类型字段名称
        *输入：value=c int[]值
        *输入：length=缓存长度
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cIntArrayJIntArray(JNIEnv *env, jobject obj, char *tag, int *value, int length);
        
        /************************************************************
        *功能：c double[] 转 java对象中的double[]字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的double[]类型字段名称
        *输入：value=c double[]值
        *输入：length=缓存长度
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cDoubleArrayJDoubleArray(JNIEnv *env, jobject obj, char *tag, double *value, int length);
        
        /************************************************************
        *功能：c int[][] 转 java对象中的int[][]字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的int[][]类型字段名称
        *输入：value=c int[][]值
        *输入：size=一维缓存长度
        *输入：length=二维缓存长度
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cIntArray2JIntArray2(JNIEnv *env, jobject obj, char *tag, int value[][256], int size, int *length);
        
        /************************************************************
        *功能：c char[][] 转 java对象中的String[]字段
        *输入：env=虚拟机环境
        *输入：tag=java对象需要赋值的String[]类型字段名称
        *输入：value=c char[][]值
        *输入：size=一维缓存长度
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int cCharArray2CStringArray(JNIEnv *env, jobject obj, char *tag, char buf[][256], int size);
        
        /************************************************************
        *功能：对java Integer对象赋值
        *输入：env=虚拟机环境
        *输入：value=c int值
        *输出：obj=java对象
        *返回：!=0错误
        */
        static int setJInt(JNIEnv *env, jobject obj, int value);
        
        /************************************************************
        *功能：java String 转c char[]
        *输入：env=虚拟机环境
        *输入：obj=java String对象
        *输入：bufLen=c char[]缓存长度
        *输出：buf=c字符串
        *返回：!=0错误
        */
        static int jString2Char(JNIEnv *env, jstring obj, char *buf, int bufLen);
        
        /************************************************************
        *功能：java byte[] 转c char[]
        *输入：env=虚拟机环境
        *输入：obj=java byte[]对象
        *输入：bufLen=c char[]缓存长度
        *输出：buf=c字符串
        *返回：!=0错误
        */
        static int jByteArray2Char(JNIEnv *env, jbyteArray obj, char *buf, int bufLen);

    private:
        static int swapError(int srcError);
};

#endif
