本文剖析asn-bool.h/c,从源代码来学习eSNACC对BOOLEAN的编码和解码。
BOOLEAN类型很简单,所以代码其实也很简单,闲话少说,看代码:
#ifndef _asn_bool_h_
#define _asn_bool_h_
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char AsnBool;
AsnLen BEncAsnBool PROTO ((GenBuf *b, AsnBool *data));
void BDecAsnBool PROTO ((GenBuf *b, AsnBool *result, AsnLen *bytesDecoded, ENV_TYPE env));
AsnLen BEncAsnBoolContent PROTO ((GenBuf *b, AsnBool *data));
void BDecAsnBoolContent PROTO ((GenBuf *b, AsnTag tag, AsnLen len, AsnBool *result, AsnLen *bytesDecoded, ENV_TYPE env));
/**//* do nothing */
void FreeAsnBool PROTO ((AsnBool *b));
#define FreeAsnBool( v)
void PrintAsnBool PROTO ((FILE *f, AsnBool *b, unsigned int indent));
#ifdef __cplusplus
}
#endif /* extern 'C' */
以上就是.h文件的内容了。一目了然,基本没什么说的,除了一些函数声明,要提两点:
1、eSNACC中对AsnBool是用unsigned char表示的。
2、布尔类型的释放例程其实不需要做任何事情。这里要说的是:在一个程序中定义了同名的函数和宏,那到底会调用哪一个呢?
其实,我们关键是要记住宏和函数的根本区别:
宏是在预编译阶段对代码进行替换。
而函数在编译时链接找对应的函数地址,然后以生成机器码。如果一个函数名有多个定义就会在连接的时候报错。
所以,如果在代码中直接出现了这个相同的名字并且符合宏的定义的话,在预编译阶段就被替换掉了,除了是用函数指针,否则就没有函数的用武之地了。
头文件到此,下面看源文件。
///*************************************休息一下******************************
编码函数
/**//*
* encodes universal TAG LENGTH and Contents of and ASN.1 BOOLEAN
*/
AsnLen
BEncAsnBool PARAMS ((b, data),
GenBuf *b _AND_
AsnBool *data)
{
AsnLen len;
len = BEncAsnBoolContent (b, data);
len += BEncDefLen (b, len);
len += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE);
return len;
} /**//* BEncAsnBool */
可以看到编码布尔型的过程是:
1.编码布尔值内容。2.编码这个值的长度。3.编码布尔标签,从代码可以看到,asn.1的布尔型属于UNIVERSAL-PRIM-1。
解码函数
/**//*
* decodes universal TAG LENGTH and Contents of and ASN.1 BOOLEAN
*/
void
BDecAsnBool PARAMS ((b, result, bytesDecoded, env),
GenBuf *b _AND_
AsnBool *result _AND_
AsnLen *bytesDecoded _AND_
jmp_buf env)
{
AsnTag tag;
AsnLen elmtLen;
if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE))
{
Asn1Error ("BDecAsnBool: ERROR - wrong tag on BOOLEAN.\n");
longjmp (env, -40);
}
elmtLen = BDecLen (b, bytesDecoded, env);
BDecAsnBoolContent (b, tag, elmtLen, result, bytesDecoded, env);
} /**//* BDecAsnBool */
函数先判断标签是否正确,然后在解码长度,最后解码内容。
实现文件后面还有几个例程,代码很简单,一看就会,就不贴出来了。