0
点赞
收藏
分享

微信扫一扫

linphone-LpConfigImpl文件对应的JNI层文件分析


说明

native 函数

private native long newLpConfigImpl(String file);
    private native void delete(long ptr);

    private native void sync(long ptr);
    private native void setInt(long ptr, String section, String key, int value);
    private native void setFloat(long ptr, String section, String key, float value);

    private native void setBool(long ptr, String section, String key, boolean value);
    private native void setString(long ptr, String section, String key, String value);
    private native void setIntRange(long ptr, String section, String key, int min, int max);
    private native int getInt(long ptr, String section, String key, int defaultValue);
    private native float getFloat(long ptr, String section, String key, float defaultValue);
    private native boolean getBool(long ptr, String section, String key, boolean defaultValue);
    private native String getString(long ptr, String section, String key, String defaultValue);
    private native int[] getIntRange(long ptr, String section, String key, int defaultMin, int defaultMax);

具体的函数分析

newLpConfigImpl

// LpConfig
extern "C" jlong Java_org_linphone_core_LpConfigImpl_newLpConfigImpl(JNIEnv *env, jobject thiz, jstring file) {
        const char *cfile = env->GetStringUTFChars(file, NULL);
        LpConfig *lp = lp_config_new(cfile);
    env->ReleaseStringUTFChars(file, cfile);
    return (jlong) lp;
}

lp_config_new

submodules/linphone/coreapi/lpconfig.c:LpConfig * lp_config_new(const char *filename){

submodules/linphone/coreapi/lpconfig.h:LINPHONE_PUBLIC LpConfig * lp_config_new(const char *filename);

根据以往的经验, 本篇写文章就是根据lpconfig.h和lpconfig.c文件展开的。 这充分说明了, linphone是按模块化来区分的 。 这一点在以后的分析中,和自己写程序的时候, 会有很大的帮助。

LpConfig * lp_config_new(const char *filename){
    return lp_config_new_with_factory(filename, NULL);
}

lp_config_new_with_factory

LpConfig *lp_config_new_with_factory(const char *config_filename, const char *factory_config_filename) {
    LpConfig *lpconfig=lp_new0(LpConfig,1);
    lpconfig->refcnt=1;
    if (config_filename!=NULL){
        if(ortp_file_exist(config_filename) == 0) {
            lpconfig->filename=lp_realpath(config_filename, NULL);
            if(lpconfig->filename == NULL) {
                ms_error("Could not find the real path of %s: %s", config_filename, strerror(errno));
                goto fail;
            }
        } else {
            lpconfig->filename = ms_strdup(config_filename);
        }
        lpconfig->tmpfilename=ortp_strdup_printf("%s.tmp",lpconfig->filename);
        ms_message("Using (r/w) config information from %s", lpconfig->filename);

#if !defined(_WIN32)
        {
            struct stat fileStat;
            if ((stat(lpconfig->filename,&fileStat) == 0) && (S_ISREG(fileStat.st_mode))) {
                /* make existing configuration files non-group/world-accessible */
                if (chmod(lpconfig->filename, S_IRUSR | S_IWUSR) == -1) {
                    ms_warning("unable to correct permissions on "
                        "configuration file: %s", strerror(errno));
                }
            }
        }
#endif /*_WIN32*/
        /*open with r+ to check if we can write on it later*/
        lpconfig->file=fopen(lpconfig->filename,"r+");
#ifdef RENAME_REQUIRES_NONEXISTENT_NEW_PATH
        if (lpconfig->file==NULL){
            lpconfig->file=fopen(lpconfig->tmpfilename,"r+");
            if (lpconfig->file){
                ms_warning("Could not open %s but %s works, app may have crashed during last sync.",lpconfig->filename,lpconfig->tmpfilename);
            }
        }
#endif
        if (lpconfig->file!=NULL){
            lp_config_parse(lpconfig,lpconfig->file);
            fclose(lpconfig->file);

            lpconfig->file=NULL;
            lpconfig->modified=0;
        }
    }
    if (factory_config_filename != NULL) {
        lp_config_read_file(lpconfig, factory_config_filename);
    }
    return lpconfig;

fail:
    ms_free(lpconfig);
    return NULL;
}

LpConfig

struct _LpConfig{
    int refcnt;
    FILE *file;
    char *filename;
    char *tmpfilename;
    MSList *sections;
    int modified;
    int readonly;
};

这个下划线和不错, 将结构做成一个统一的格式, 使用的又是一个没有“_”格式, 这样又方便查找, 又利于其他人的理解。这里用的太帅了。

这里有一个FILE类型的声明, 我突然想到, 是不是那个作为配置文件的文件, 是不是通过这个类存储的呢, 有可能, 也有可能这就是一个结构,存储在另一个地方。我感觉还是前者, 毕竟是FILE类型么。好, 继续看看。

lp_new0

submodules/linphone/coreapi/lpconfig.c:#define lp_new0(type,n)  (type*)calloc(sizeof(type),n)

原来是给再分配内存重新分配了一个名字。为啥! 就是为了便于阅读。也许吧。

lp_realpath

submodules/linphone/coreapi/lpconfig.c:char* lp_realpath(const char* file, char* name) {

char* lp_realpath(const char* file, char* name) {
#if defined(_WIN32) || defined(__QNX__) || defined(ANDROID)
    return ms_strdup(file);
#else
    char * output = realpath(file, name);
    char * msoutput = ms_strdup(output);
    free(output);
    return msoutput;
#endif
}

就是分配内存之类的, 这是个通用的格式。不予理会, 以后可以详细看。

ortp_file_exist

submodules/linphone/oRTP/include/ortp/port.h:ORTP_PUBLIC int ortp_file_exist(const char *pathname);

submodules/linphone/oRTP/src/port.c:int ortp_file_exist(const char *pathname) {

submodules/linphone/oRTP/src/port.c:int ortp_file_exist(const char *pathname) {

submodules/linphone/mediastreamer2/src/ortp-deps/port.c:int ortp_file_exist(const char *pathname) {

submodules/linphone/mediastreamer2/src/ortp-deps/port.c:int ortp_file_exist(const char *pathname) {

submodules/linphone/mediastreamer2/src/ortp-deps/ortp/port.h:ORTP_PUBLIC int ortp_file_exist(const char *pathname);

这里有两个显现, 分别在oRTP和ortp-deps中。让我先看看, 在下结论这里为什么有两个, 让我带着怀疑‘两个实现不一样吗?’看看。

  • 第一个

#if defined (_WIN32_WCE) || defined(_MSC_VER)
int ortp_file_exist(const char *pathname) {
    FILE* fd;
    if (pathname==NULL) return -1;
    fd=fopen(pathname,"r");
    if (fd==NULL) {
        return -1;
    } else {
        fclose(fd);
        return 0;
    }
}
#else
int ortp_file_exist(const char *pathname) {
    return access(pathname,F_OK);
}
#endif /*_WIN32_WCE*/

这里不得不赞叹, 这个预编译也太神奇了, 不同的代码可以存在一个地方, 我曾经在写java的时候被老板说过可不可以像c语言一样预编译,但是并没有什么在意, 没想到现在遇到了,真感觉c语言不错。

  • 第二个

#if defined (_WIN32_WCE) || defined(_MSC_VER)
int ortp_file_exist(const char *pathname) {
    FILE* fd;
    if (pathname==NULL) return -1;
    fd=fopen(pathname,"r");
    if (fd==NULL) {
        return -1;
    } else {
        fclose(fd);
        return 0;
    }
}
#else
int ortp_file_exist(const char *pathname) {
    return access(pathname,F_OK);
}
#endif /*_WIN32_WCE*/

第一个和第二个代码一样啊, 为什么会这个样子呢, 估计是第二个是第一个的改进版, 所以才出奇的相似吧。肯定是这个样子的。

ortp_strdup_printf

submodules/linphone/mediastreamer2/src/ortp-deps/logging.c:char *ortp_strdup_printf(const char *fmt,...){

submodules/linphone/oRTP/src/logging.c:char *ortp_strdup_printf(const char *fmt,...){

这一一看就是打印log日志的地方。详细看一看,毕竟我们公司的项目里面用到了,这个, 这个号对比的学习一番。

char *ortp_strdup_printf(const char *fmt,...){
    char *ret;
    va_list args;
    va_start (args, fmt);
    ret=ortp_strdup_vprintf(fmt, args);
    va_end (args);
    return ret;
}

这里还是归结到了其他地方, 看下面。

ortp_strdup_vprintf

submodules/linphone/oRTP/include/ortp/port.h:ORTP_PUBLIC char *ortp_strdup_vprintf(const char *fmt, va_list ap);

submodules/linphone/oRTP/src/logging.c:char * ortp_strdup_vprintf(const char *fmt, va_list ap)

哇塞!

char * ortp_strdup_vprintf(const char *fmt, va_list ap)
{
/* Guess we need no more than 100 bytes. */
    int n, size = 200;
    char *p,*np;
#ifndef _WIN32
    va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/
#endif
    if ((p = (char *) ortp_malloc (size)) == NULL)
        return NULL;
    while (1){
/* Try to print in the allocated space. */
#ifndef _WIN32
        va_copy(cap,ap);
        n = vsnprintf (p, size, fmt, cap);
        va_end(cap);
#else
        /*this works on 32 bits, luckily*/
        n = vsnprintf (p, size, fmt, ap);
#endif
        /* If that worked, return the string. */
        if (n > -1 && n < size)
            return p;
//printf("Reallocing space.\n");
        /* Else try again with more space. */
        if (n > -1) /* glibc 2.1 */
            size = n + 1;   /* precisely what is needed */
        else        /* glibc 2.0 */
            size *= 2;  /* twice the old size */
        if ((np = (char *) ortp_realloc (p, size)) == NULL)
        {
            free(p);
            return NULL;
        } else {
            p = np;
        }
    }
}

这么多的预编译。真应该好好看看, 但是我估计我也不明白。往下看吧。

delete

extern "C" void Java_org_linphone_core_LpConfigImpl_delete(JNIEnv *env, jobject thiz, jlong lpc) {
    LpConfig *lp = (LpConfig *)lpc;
    lp_config_destroy(lp);
}

lp_config_destroy

static void _lp_config_destroy(LpConfig *lpconfig){
    if (lpconfig->filename!=NULL) ortp_free(lpconfig->filename);
    if (lpconfig->tmpfilename) ortp_free(lpconfig->tmpfilename);
    ms_list_for_each(lpconfig->sections,(void (*)(void*))lp_section_destroy);
    ms_list_free(lpconfig->sections);
    free(lpconfig);
}

sync

extern "C" void Java_org_linphone_core_LpConfigImpl_sync(JNIEnv *env, jobject thiz, jlong lpc) {
    LpConfig *lp = (LpConfig *)lpc;
    lp_config_sync(lp);
}

lp_config_sync

int lp_config_sync(LpConfig *lpconfig){
    FILE *file;
    if (lpconfig->filename==NULL) return -1;
    if (lpconfig->readonly) return 0;
#ifndef _WIN32
    /* don't create group/world-accessible files */
    (void) umask(S_IRWXG | S_IRWXO);
#endif
    file=fopen(lpconfig->tmpfilename,"w");
    if (file==NULL){
        ms_warning("Could not write %s ! Maybe it is read-only. Configuration will not be saved.",lpconfig->filename);
        lpconfig->readonly=1;
        return -1;
    }
    ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file);
    fclose(file);
#ifdef RENAME_REQUIRES_NONEXISTENT_NEW_PATH
    /* On windows, rename() does not accept that the newpath is an existing file, while it is accepted on Unix.
     * As a result, we are forced to first delete the linphonerc file, and then rename.*/
    if (remove(lpconfig->filename)!=0){
        ms_error("Cannot remove %s: %s",lpconfig->filename, strerror(errno));
    }
#endif
    if (rename(lpconfig->tmpfilename,lpconfig->filename)!=0){
        ms_error("Cannot rename %s into %s: %s",lpconfig->tmpfilename,lpconfig->filename,strerror(errno));
    }
    lpconfig->modified=0;
    return 0;
}

啊哈, 我就说了么, 这个就是写入到文件中的, 不知道是哪个文件。 让我去找找, 应该LinphoneCoreFactory.java中, 我看看是不是。

呜呜呜, 没找到, 这个无耻的搜索linphonerc 这个文件了, 想知道这个是哪里知道的么, 是在linphone工程目录下, 是真的运行目录下。/data/data/org.sainthigh.linphone/files

让我们碰碰运气。
原来是在linphoneManager中。

mLPConfigXsd = basePath + "/lpconfig.xsd";
    mLinphoneFactoryConfigFile = basePath + "/linphonerc";
    mLinphoneConfigFile = basePath + "/.linphonerc";
    mLinphoneRootCaFile = basePath + "/rootca.pem";
    mRingSoundFile = basePath + "/oldphone_mono.wav";
    mRingbackSoundFile = basePath + "/ringback.wav";
    mPauseSoundFile = basePath + "/hold.mkv";
    mChatDatabaseFile = basePath + "/linphone-history.db";
    mCallLogDatabaseFile = basePath + "/linphone-log-history.db";
    mErrorToneFile = basePath + "/error.wav";
    mConfigFile = basePath + "/configrc";
    mUserCertificatePath = basePath;

setInt

extern "C" void Java_org_linphone_core_LpConfigImpl_setInt(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jint value) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        lp_config_set_int((LpConfig *)lpc, csection, ckey, (int) value);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
}

这个linphonecore_jni可有意思了, 把所有的有关与java和c对应的东西,都放在这里。

lp_config_set_int

submodules/linphone/coreapi/lpconfig.h:LINPHONE_PUBLIC void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value);
submodules/linphone/coreapi/lpconfig.h:LINPHONE_PUBLIC void lp_config_set_int_hex(LpConfig *lpconfig,const char *section, const char *key, int value);
submodules/linphone/coreapi/lpconfig.h:LINPHONE_PUBLIC void lp_config_set_int64(LpConfig *lpconfig,const char *section, const char *key, int64_t value);


submodules/linphone/coreapi/lpconfig.c:void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){
submodules/linphone/coreapi/lpconfig.c:void lp_config_set_int_hex(LpConfig *lpconfig,const char *section, const char *key, int value){
submodules/linphone/coreapi/lpconfig.c:void lp_config_set_int64(LpConfig *lpconfig,const char *section, const char *key, int64_t value){

void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){
    char tmp[30];
    snprintf(tmp,sizeof(tmp),"%i",value);
    lp_config_set_string(lpconfig,section,key,tmp);
}

void lp_config_set_int_hex(LpConfig *lpconfig,const char *section, const char *key, int value){
    char tmp[30];
    snprintf(tmp,sizeof(tmp),"0x%x",value);
    lp_config_set_string(lpconfig,section,key,tmp);
}

void lp_config_set_int64(LpConfig *lpconfig,const char *section, const char *key, int64_t value){
    char tmp[30];
    snprintf(tmp,sizeof(tmp),"%lli",(long long)value);
    lp_config_set_string(lpconfig,section,key,tmp);
}

lp_config_set_string

这个应该是写入文件的操作了。为什么会这么想呢, 前面已经遇到了这样的函数了啊。没什么可激动的。

void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){
    LpItem *item;
    LpSection *sec=lp_config_find_section(lpconfig,section);
    if (sec!=NULL){
        item=lp_section_find_item(sec,key);
        if (item!=NULL){
            if (value!=NULL && value[0] != '\0')
                lp_item_set_value(item,value);
            else lp_section_remove_item(sec,item);
        }else{
            if (value!=NULL && value[0] != '\0')
                lp_section_add_item(sec,lp_item_new(key,value));
        }
    }else if (value!=NULL && value[0] != '\0'){
        sec=lp_section_new(section);
        lp_config_add_section(lpconfig,sec);
        lp_section_add_item(sec,lp_item_new(key,value));
    }
    lpconfig->modified++;
}

不错不错, 原来差不多所有的有关操作都在这个类里面的,这是结构化, 不错不错。

LpItem

typedef struct _LpItem{
    char *key;
    char *value;
    int is_comment;
    bool_t overwrite; // If set to true, will add overwrite=true when converted to xml
} LpItem;

lp_section_find_item

LpItem *lp_section_find_item(const LpSection *sec, const char *name){
    MSList *elem;
    LpItem *item;
    /*printf("Looking for item %s\n",name);*/
    for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){
        item=(LpItem*)elem->data;
        if (!item->is_comment && strcmp(item->key,name)==0) {
            /*printf("Item %s found\n",name);*/
            return item;
        }
    }
    return NULL;
}

LpSection

typedef struct _LpSection{
    char *name;
    MSList *items;
    MSList *params;
    bool_t overwrite; // If set to true, will add overwrite=true to all items of this section when converted to xml
} LpSection;

lp_config_find_section

LpSection *lp_config_find_section(const LpConfig *lpconfig, const char *name){
    LpSection *sec;
    MSList *elem;
    /*printf("Looking for section %s\n",name);*/
    for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){
        sec=(LpSection*)elem->data;
        if (strcmp(sec->name,name)==0){
            /*printf("Section %s found\n",name);*/
            return sec;
        }
    }
    return NULL;
}

lp_item_set_value

void lp_item_set_value(LpItem *item, const char *value){
    char *prev_value=item->value;
    item->value=ortp_strdup(value);
    ortp_free(prev_value);
}

其实我现在还是没有搞明白ortp_strfup 到底是干什么用的, 好尴尬, 其实我已经看到过了。

lp_section_remove_item

void lp_section_remove_item(LpSection *sec, LpItem *item){
sec->items=ms_list_remove(sec->items,(void *)item);
lp_item_destroy(item);
}

lp_item_destroy
void lp_item_destroy(void *pitem){
LpItem item=(LpItem)pitem;
if (item->key) ortp_free(item->key);
ortp_free(item->value);
free(item);
}

就是将整个结构都删除掉, 让其不在保存。

lp_section_add_item

void lp_section_add_item(LpSection *sec,LpItem *item){
    sec->items=ms_list_append(sec->items,(void *)item);
}

将新的数据添加到列表中。

lp_section_new

LpSection *lp_section_new(const char *name){
    LpSection *sec=lp_new0(LpSection,1);
    sec->name=ortp_strdup(name);
    return sec;
}

lp_config_add_section

void lp_config_add_section(LpConfig *lpconfig, LpSection *section){
    lpconfig->sections=ms_list_append(lpconfig->sections,(void *)section);
}

setFloat

extern "C" void Java_org_linphone_core_LpConfigImpl_setFloat(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jfloat value) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        lp_config_set_float((LpConfig *)lpc, csection, ckey, (float) value);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
}

lp_config_set_float

void lp_config_set_float(LpConfig *lpconfig,const char *section, const char *key, float value){
    char tmp[30];
    snprintf(tmp,sizeof(tmp),"%f",value);
    lp_config_set_string(lpconfig,section,key,tmp);
}

lp_config_set_string

void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){
    LpItem *item;
    LpSection *sec=lp_config_find_section(lpconfig,section);
    if (sec!=NULL){
        item=lp_section_find_item(sec,key);
        if (item!=NULL){
            if (value!=NULL && value[0] != '\0')
                lp_item_set_value(item,value);
            else lp_section_remove_item(sec,item);
        }else{
            if (value!=NULL && value[0] != '\0')
                lp_section_add_item(sec,lp_item_new(key,value));
        }
    }else if (value!=NULL && value[0] != '\0'){
        sec=lp_section_new(section);
        lp_config_add_section(lpconfig,sec);
        lp_section_add_item(sec,lp_item_new(key,value));
    }
    lpconfig->modified++;
}

lp_item_set_value

void lp_item_set_value(LpItem *item, const char *value){
    char *prev_value=item->value;
    item->value=ortp_strdup(value);
    ortp_free(prev_value);
}

setBool

extern "C" void Java_org_linphone_core_LpConfigImpl_setBool(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jboolean value) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        lp_config_set_int((LpConfig *)lpc, csection, ckey, value ? 1 : 0);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
}

setString

extern "C" void Java_org_linphone_core_LpConfigImpl_setString(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jstring value) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        const char *cvalue = value ? env->GetStringUTFChars(value, NULL) : NULL;
        lp_config_set_string((LpConfig *)lpc, csection, ckey, cvalue);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
        if (value) env->ReleaseStringUTFChars(value, cvalue);
}

setIntRange

extern "C" void Java_org_linphone_core_LpConfigImpl_setIntRange(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jint min, jint max) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        lp_config_set_range((LpConfig *)lpc, csection, ckey, min, max);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
}

lp_config_set_range

void lp_config_set_range(LpConfig *lpconfig, const char *section, const char *key, int min_value, int max_value) {
    char tmp[30];
    snprintf(tmp, sizeof(tmp), "%i-%i", min_value, max_value);
    lp_config_set_string(lpconfig, section, key, tmp);
}

getInt

extern "C" jint Java_org_linphone_core_LpConfigImpl_getInt(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jint defaultValue) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        int returnValue = lp_config_get_int((LpConfig *)lpc, csection, ckey, (int) defaultValue);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
        return (jint) returnValue;
}

getFloat

extern "C" jfloat Java_org_linphone_core_LpConfigImpl_getFloat(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jfloat defaultValue) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        float returnValue = lp_config_get_float((LpConfig *)lpc, csection, ckey, (float) defaultValue);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
        return (jfloat) returnValue;
}

getBool

extern "C" jboolean Java_org_linphone_core_LpConfigImpl_getBool(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jboolean defaultValue) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        int returnValue = lp_config_get_int((LpConfig *)lpc, csection, ckey, defaultValue ? 1 : 0);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
        return (jboolean) returnValue == 1;
}

getString

extern "C" jstring Java_org_linphone_core_LpConfigImpl_getString(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jstring defaultValue) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        const char *cvalue = defaultValue ? env->GetStringUTFChars(defaultValue, NULL) : NULL;

        const char *returnValue = lp_config_get_string((LpConfig *)lpc, csection, ckey, cvalue);

        jstring jreturnValue = NULL;
        if (returnValue)
            jreturnValue = env->NewStringUTF(returnValue);

        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
        if (cvalue)
            env->ReleaseStringUTFChars(defaultValue, cvalue);

        return jreturnValue;
}

getIntRange

extern "C" jintArray Java_org_linphone_core_LpConfigImpl_getIntRange(JNIEnv *env, jobject thiz, jlong lpc,
        jstring section, jstring key, jint defaultmin, jint defaultmax) {
        const char *csection = env->GetStringUTFChars(section, NULL);
        const char *ckey = env->GetStringUTFChars(key, NULL);
        int *values = (int*)calloc(2, sizeof(int));
        lp_config_get_range((LpConfig *)lpc, csection, ckey, &values[0], &values[1], defaultmin, defaultmax);
        jintArray returnValues = env->NewIntArray(2);
        env->SetIntArrayRegion(returnValues, 0, 2, values);
        ms_free(values);
        env->ReleaseStringUTFChars(section, csection);
        env->ReleaseStringUTFChars(key, ckey);
        return returnValues;
}


举报

相关推荐

0 条评论