说明
这个是封装Message的结构, 稍微了解linphone的都知道, linphone的数据都存储在jni层, 所以这个结构就显得尤为重要。
看来,得专门写一篇文章,看看linphone是怎样在底层存取数据的,好期待
写到现在, 突然就没有了什么动力去详细的往下追踪。 估计是因为从刚开始分析第二阶段的第一个类开始,跟现在的分析步骤, 和结构出奇的移植, 所以我决定, 往下的文章还是简单的略过, 快快的进入下一个阶段。
native函数
private native Object getContent(long infoptr);
private native void setContent(long nativePtr, String type, String subtype, String data);
private native void addHeader(long nativePtr, String name, String value);
private native String getHeader(long nativePtr, String name);
private native void delete(long nativePtr);
具体的函数分析
getContent
/*
* Class: org_linphone_core_LinphoneInfoMessageImpl
* Method: getContent
* Signature: (J)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getContent(JNIEnv *env, jobject jobj, jlong infoptr){
const LinphoneContent *content=linphone_info_message_get_content((LinphoneInfoMessage*)infoptr);
if (content){
return create_java_linphone_content(env,content);
}
return NULL;
}
让我们来看看LinphoneContent是个什么结构体。
LinphoneContent
submodules/linphone/coreapi/content.h:struct _LinphoneContent;
submodules/linphone/coreapi/content.h:typedef struct _LinphoneContent LinphoneContent;
submodules/linphone/coreapi/private.h:struct _LinphoneContent {
搜索_LinphonContent关键字, 搜到了结果。什么鬼, 竟然出现在两个不同的头文件中。
content.h ,我肯定在其它的文章中找到过, 看来得再找一遍了。、
/**
* The LinphoneContent object holds data that can be embedded in a signaling message.
**/
struct _LinphoneContent;
/**
* The LinphoneContent object holds data that can be embedded in a signaling message.
**/
typedef struct _LinphoneContent LinphoneContent;
什么, 没有定义结构体, 好尴尬啊。 我怎么办。
fuk, 结果在:private.h文件中
struct _LinphoneContent {
belle_sip_object_t base;
void *user_data;
SalBodyHandler *body_handler;
char *name; /**< used by RCS File transfer messages to store the original filename of the file to be downloaded from server */
char *key; /**< used by RCS File transfer messages to store the key to encrypt file if needed */
size_t keyLength; /**< Length of key in bytes */
void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */
bool_t owned_fields;
};
可是为什么content.h要声明_LinphoneContent呢, 哦, 原来是content.c文件中生命声明了头文件,content.h中没有声明,所以必须得声明一下。 不行, 还是云里雾里, 找个时间得好好补补c/c++的基础了。
linphone_info_message_get_content
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im);
submodules/linphone/coreapi/info.c:const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im){
/**
* Returns the info message's content as a #LinphoneContent structure.
**/
const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im){
return (im->content && linphone_content_get_type(im->content)) ? im->content : NULL;
}
这里运用了三目运算符。
create_java_linphone_content
static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *icontent){
jclass contentClass;
jmethodID ctor;
jstring jtype, jsubtype, jencoding, jname;
jbyteArray jdata = NULL;
jint jsize = 0;
const char *tmp;
void *data;
contentClass = (jclass)env->FindClass("org/linphone/core/LinphoneContentImpl");
ctor = env->GetMethodID(contentClass,"<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;I)V");
jtype = env->NewStringUTF(linphone_content_get_type(icontent));
jsubtype = env->NewStringUTF(linphone_content_get_subtype(icontent));
jencoding = ((tmp = linphone_content_get_encoding(icontent))) ? env->NewStringUTF(tmp) : NULL;
jname = ((tmp = linphone_content_get_name(icontent))) ? env->NewStringUTF(tmp) : NULL;
jsize = (jint) linphone_content_get_size(icontent);
data = (!linphone_content_is_multipart(icontent) ? linphone_content_get_buffer(icontent) : NULL);
if (data){
jdata = env->NewByteArray(linphone_content_get_size(icontent));
env->SetByteArrayRegion(jdata, 0, linphone_content_get_size(icontent), (jbyte*)data);
}
jobject jobj = env->NewObject(contentClass, ctor, jname, jtype, jsubtype, jdata, jencoding, jsize);
env->DeleteLocalRef(contentClass);
env->DeleteLocalRef(jtype);
env->DeleteLocalRef(jsubtype);
if (jencoding) {
env->DeleteLocalRef(jencoding);
}
if (jname) {
env->DeleteLocalRef(jname);
}
return jobj;
}
这个函数就字啊linphonecore_jni.cc文件中, 说明它是直接跟java代码操作相关系的。 分析到这里, 突然脑子一过, 好像所有的有关于jni层的东西都放在这一个类中。
setContent
/*
* Class: org_linphone_core_LinphoneInfoMessageImpl
* Method: setContent
* Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_setContent(JNIEnv *env, jobject jobj, jlong infoptr, jstring jtype, jstring jsubtype, jstring jdata){
LinphoneInfoMessage *infomsg = (LinphoneInfoMessage*) infoptr;
LinphoneContent * content = linphone_content_new();
const char *tmp;
linphone_content_set_type(content, tmp = env->GetStringUTFChars(jtype,NULL));
env->ReleaseStringUTFChars(jtype, tmp);
linphone_content_set_type(content, tmp = env->GetStringUTFChars(jsubtype,NULL));
env->ReleaseStringUTFChars(jsubtype, tmp);
linphone_content_set_string_buffer(content, tmp = env->GetStringUTFChars(jdata,NULL));
env->ReleaseStringUTFChars(jdata, tmp);
linphone_info_message_set_content((LinphoneInfoMessage*)infoptr, content);
linphone_content_unref(content);
}
LinphoneInfoMessage
submodules/linphone/coreapi/info.c:struct _LinphoneInfoMessage{
我摸到一个很有用的经验, 那就是要想搜某一个具体的结构体定义, 就搜同名+”_” , 百分百能搜到。
struct _LinphoneInfoMessage{
LinphoneContent *content;
SalCustomHeader *headers;
};
addHeader
/*
* Class: org_linphone_core_LinphoneInfoMessageImpl
* Method: addHeader
* Signature: (JLjava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_addHeader(JNIEnv *env, jobject jobj, jlong infoptr, jstring jname, jstring jvalue){
const char *name=NULL,*value=NULL;
name=env->GetStringUTFChars(jname,NULL);
value=env->GetStringUTFChars(jvalue,NULL);
linphone_info_message_add_header((LinphoneInfoMessage*)infoptr,name,value);
env->ReleaseStringUTFChars(jname,name);
env->ReleaseStringUTFChars(jvalue,value);
}
getHeader
/*
* Class: org_linphone_core_LinphoneInfoMessageImpl
* Method: getHeader
* Signature: (JLjava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getHeader(JNIEnv *env, jobject jobj, jlong infoptr, jstring jname){
const char *name=env->GetStringUTFChars(jname,NULL);
const char *ret=linphone_info_message_get_header((LinphoneInfoMessage*)infoptr,name);
env->ReleaseStringUTFChars(jname,name);
return ret ? env->NewStringUTF(ret) : NULL;
}
delete
/*
* Class: org_linphone_core_LinphoneInfoMessageImpl
* Method: delete
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_delete(JNIEnv *env, jobject jobj , jlong infoptr){
linphone_info_message_destroy((LinphoneInfoMessage*)infoptr);
}