socketref,再见!高德

https://github.com/adoggie

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  246 Posts :: 4 Stories :: 312 Comments :: 0 Trackbacks

常用链接

留言簿(54)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

#

在移植glib到wince环境时,发现wince的c runtime library不包含很多库函数,诸如 bsearch() 半則搜索法,其用法有点像 std::bind2nd(),
费了点时间将其刨了出来,相信对有些人有用

 1 void * bsearch(
 2          const void *key,
 3         const void *base0,
 4         size_t nmemb,
 5          size_t size,
 6          int (*compar)(const void *const void *)) {
 7 
 8          const char *base = base0;
 9          size_t lim;
10          int cmp;
11          const void *p;
12 
13         for (lim = nmemb; lim != 0; lim >>= 1) {
14                 p = base + (lim >> 1* size;
15                 cmp = (*compar)(key, p);
16                 if (cmp == 0)
17                         return ((void *)p);
18                 if (cmp > 0) {  /* key > p: move right */
19                         base = (char *)p + size;
20                         lim--;
21                 }               /* else move left */
22         }
23         return (NULL);
24 }


posted @ 2008-05-07 01:33 放屁阿狗 阅读(716) | 评论 (1)编辑 收藏

代码很容易阅读,以前做蓝牙项目时用户电话本搜索只用


static public string GetChineseSpell(string strText)
{
int len = strText.Length;
string myStr 
= "";
for(int i=0;i<len;i++)
{
myStr 
+= getSpell(strText.Substring(i,1));
}
return myStr;
}

static public string getSpell(string myChar)
{
byte[] arrCN = System.Text.Encoding.Default.GetBytes(myChar);
if(arrCN.Length > 1)
{
int area = (short)arrCN[0];
int pos = (short)arrCN[1];
int code = (area<<8+ pos;
int[] areacode = {45217,45253,45761,46318,46826,47010,47297,47614,48119,48119,49062,49324,49896,50371,50614,50622,50906,51387,51446,52218,52698,52698,52698,52980,53689,54481};
for(int i=0;i<26;i++)
{
int max = 55290;
if(i != 25) max = areacode[i+1];
if(areacode[i]<=code && code<max)
{
return System.Text.Encoding.Default.GetString(new byte[]{(byte)(65+i)});
}
}
return "*";
}
else return myChar;
}


posted @ 2008-05-07 01:28 放屁阿狗 阅读(2067) | 评论 (4)编辑 收藏

    昨天接到the9的人事mm的电话通知今天去公司面试,职位大概是开发岗位
这些年来也一直没有面试的经历,闲在家里没事所以今天就去看看。
the9.com =>张江高科技园区碧波路690号3号楼,google了一下具体位置,带了个导航仪开着桑哥走了。
外环比较拥挤,25公里开了45分钟便到了碧波路,一个大拐就进了690号,接着一个小拐又一个大拐,直接将车停就进了车位,"技术不错,可以打9.9分"。
    the9也算是有点财力和规模,整个一片都是the9公司。
刚想推门下车,一个保安马上上来,我想这个服务到是周到。"先生,这里不能停车,这是我们老板的车位". 奶奶的,确实边上不是BMW就是A6之类的车子,仔细一看,确实车位上都有具体的车牌。一不小心把车停到the9老板 家了。接着就倒车,7拐八拐 找了个日光浴的位置。
来到the9的前台,说是要做题,领了份考卷就去2号会议室。
    里面有2人,各一男女,没多时便走了,过了半小时又进来一位做题,看上去比我是年轻多了。
开始做题,好久没被面试了,有点兴奋。某些题目回答的太细且考虑过多,磨磨蹭蹭也搞了一个小时,看了下钟点15:30了。
接着等人来捞我去谈,等了30分钟也没人来,所以就踱到前台交予前台mm(长得不错哦)。然后我继续等,约莫20来分钟mm叫我,我便跟一个叫陈国*的Man去面试,陈**带我绕了几条走廊,那个走路的速度真是超级的慢,居然是我走在他前面,有点受不了。
    进了一会议室,陈**不知为何一下子没开口,瞬即拿出笔在白板上写了起来。
    "你现在做个题目哦,题目是这样的:1000~10000里面的4位平方数你给我找出来,数字的规则是 abcd, a=b c=d,我现在有个其他面试,过5分钟我再来",奶奶的,居然还让我做题,而且是这种小学生做的题目。说完陈Man就走了,真是来气,起来我也转身离开了the.com。
做了这么些年的开发,本来以为面试会跟我聊一下系统的架构,opensource,通信技巧,看了我的简历也不应该当成应届毕业生来对待啊,一些考官就是喜欢在面试过程中夹杂一些自己的小聪明搞一些旁门做到的东西,想想过去我做考官也不是这个样子的,还是比较对人尊重的,这么大的一个公司让面试的人左等右等,感觉这是不这么的好。
    记得一个mm说的好,说是老板与员工不存在地位的差别,雇佣和被雇工是建立在平等的基础上的合作关系。
    想到了 盖茨关于他的车位总是被员工占用,及员工总是跟盖茨借钱的故事;想到了以前一位博士领导整天给老总安装office的事情
    中国人骨子里还是比较官僚的,阶级感比较强烈,老板永远是老板,是上帝,打工的就是一条狗。
    不过我对狗这个字眼不感冒,我就是一条狗,但是是条有尊严的狗。
    the9对其现在不这么感兴趣了,林子大了啥鸟都有,还是老实在家呆着。
    the9的考题对于开发者的还是有点用的,凭着有点记忆的脑子回想一下考题,大致如下:

1.是非题: 10题  具体记不清楚了
2.解释:
    const 的作用(2种以上)
    数据与链表的差异和作用
    纯虚函数,重载的区别和作用

3.改错并解释:
  1. void getmemory( char * p){
          p = new char[20];
     }
     main(){
       char *str;
        getmemory(str);
       strcpy(str,"hello");
    }
  2. char * getmemory(){
       char buf[]="ssssssssssssssss";
       return buf;
    }
    main(){
       sprintf(buf,"%d",100);
       printf( buf);
    }

4.编写函数:
    1. strcmp
    int strcmp( char * s1,char * s2 ){
    }

    2. strstr
    // return pointer if s2 found in s1,else return NULL
    char * strstr(char* s1,char* s2){
    }

    3. void compress(char * in,char * out)
    要求:    
            in          out
            abc         abc
          aaabbbccc     a2b2c2

    5. 实现以下类成员函数并解释
        class String(){
          String(char* s=NULL);
          String( const String & other);
          String & operator+=(const String &other);
          bool operator==(const String & other );
          operator double();
        };
    6. 链表倒置
       struct listNode{
          struct listNode * next;
          int data;
        }  
       返回列表头节点
        listNode * reverse(listNode * head){
       }
      
这些题基本上是能考核一个c/cpp开发人员的基本技术能力的

posted @ 2008-05-06 20:16 放屁阿狗 阅读(5917) | 评论 (68)编辑 收藏


return true if equal

 1 bool strcmp( char* d,char * s){
 2     if( d==s) return true;
 3     while*d==*&& *&& *s){
 4         d++;s++;
 5     }
 6     if*d==*&& *d==0){
 7         return true;
 8     }
 9     return false;
10 }


posted @ 2008-05-05 02:57 放屁阿狗 阅读(4025) | 评论 (15)编辑 收藏

     摘要: 经常会在编写流驱动接口的时候必须实现一系列的接口,诸如 xxx_init,xxx_open,xxx_write等等,某些接口函数虽然无需功能的实现但也必须定义一个空的函数接口。由于多年的c++思路,利用虚函数(virtual)和重载(override)把这些驱动的实现封装起来,来简化代码量。程序的实现,采用了两种方式: 宏定义和类继承希望对编写wince 流驱动的开发人员有所帮助 Code hi...  阅读全文
posted @ 2008-05-05 02:15 放屁阿狗 阅读(2098) | 评论 (0)编辑 收藏

目前已经完成移植的开源项目列表:
    cairo.dll        
    zlib1_2_3.lib
   cairomm.lib
   expat_wince.dll
   expat_wince.lib
   fontconfig-lib.lib
   freetype235.lib
   gdkpixbuf.dll
   glib-lite.lib
   gmodule.lib
   gobject.lib
   gthread.lib
   iconv.dll
   iconv.lib
   jpeg.lib
   libsigc++.lib
   libtinyxpath.lib
   libxml_ce.dll
   libxml_ce.lib
   mini-fribidi.lib
   opentype.lib
   pango1.18.dll
   pango1.18.lib
   pangocairo.lib
   pangoft2.lib
   papyrus0.7.1.lib
   png1.2.8.dll
   png1.2.8.lib
   zlib1_2_3.dll
   wxWidgets

未完成的移植内容:
    librsvg
    wxLua

posted @ 2008-05-05 01:55 放屁阿狗 阅读(2521) | 评论 (5)编辑 收藏

Fontconfig 2.5.0

 

 

Cairo依赖Fontconfig部分,但未见其起初的时候调用fontconfig的初始化函数,诸如FcInit().

Fontconfig代码有WIN32条件编译的宏,且预定义了DllMain()入口,但也未调用FcInit()

 

Fontconfig要移植到wince,必须处理内部诸多的单字节与宽字符转换问题

 

 

Fontconfig将字体文件cached的过程就是将字体文件映射到内存地址空间

 

 

FontConfig 设有字体目录(font-dir),缓冲目录(cache-dir),配置目录(font-dir)

Cache-dir目录存放字体缓冲文件 ?????-x86- cache2,缓冲文件被mmap进内存

每个font目录都将创建一个cache文件,存放于cache-dir

 

Cache文件内存放一个字体目录下(font-dir)所有字体的pattern信息集合和基本的FcCache对象的控制信息,系统扫描完字体之后的信息存于FcSerialize对象,之后绑定到FcCache对象,之后将FcCache对象及其关联的数据全部写入本地文件cache-file

之后在加载cache-file时通过FcDirCacheMapHelper()->FcDirCacheMapFd()cache-file进行mmap映射到虚拟地址空间,采用mmap方式可以允许多个进程同时访问这些字体信息。

 

系统初始化时FcInit()检测cache文件是否存在(文件锁控制),不存在则扫描字体目录创建缓冲文件(一个字体目录对应一个缓冲文件);否则打开缓冲文件并映射进入本地进程的地址空间(mmap),其起始地址被转换为FcCache*对象返回

 

如果字体目录下存在子目录,在生成的信息存放在FcCache::dirs

 

FcSerialize过程

将不同类型的Fcxxxx对象序列化转储时,先将对象结构信息专储,对象内的指针指向的对象也进行转储到对象头信息之后,其位置由对象头结构内的intptr_t变量指定。

例如:

struct _FcCache {

    int           magic;            /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */

    int           version;       /* FC_CACHE_CONTENT_VERSION */

    intptr_t    size;            /* size of file */

    intptr_t    dir;             /* offset to dir name */

    intptr_t    dirs;            /* offset to subdirs */

    int           dirs_count;         /* number of subdir strings */

    intptr_t    set;             /* offset to font set */

    int           mtime;               /* low bits of directory mtime */

};

FcCache对象结构信息先被serialize, intptr_t变量指向的附属数据所在位置(本对象的当前偏移量)

struct _FcPattern {

    int               num;

    int               size;

    intptr_t        elts_offset;

    int               ref;

};

typedef struct _FcPatternElt {

    FcObject        object;

    FcValueList            *values;

} FcPatternElt;

每个FcPattern由若干个FcPatternElt组成FcPatternElt的数组的首地址与FcPattern对象地址的差值作为偏移量存储在FcPattern::elts_offset

 

 

Fonts.conf

可以禁用部分字体或者启用字体(字体目录)

{ "acceptfont",       FcElementAcceptfont },

{ "rejectfont", FcElementRejectfont },

如果没有定义acceptfontrejectfont,则默认都是acceptfont的,所以<dir>font-dir</dir>默认是允许的

 

每个字体文件通过freetype进行访问,当在font目录下扫描字体文件是,将读取若干个patterns

 

FcSerialize FcSerializeBucket存储

 

SystemFont or ApplicationFont

不同字体被登记在不同类别的字体集合中管理

 

 

FcSerializebucket不能超过 8k个,字体文件也不能过8k,每个字体文件名置入bucket

 

 

/**

 * container_of - cast a member of a structure out to the containing structure

 *

 * @ptr:  the pointer to the member.

 * @type:       the type of the container struct this is embedded in.

 * @member: the name of the member within the struct.

 *

 */

#define container_of(ptr, type, member) ({                \

        const typeof( ((type *)0)->member ) *__mptr = (ptr);       \

        (type *)( (char *)__mptr - offsetof(type,member) );})

#define list_entry(ptr, type, member) \

       container_of(ptr, type, member)

 

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

 

Example:

struct user_struct *user;

user = list_entry(up, struct user_struct, uidhash_list);

 

取成员变量偏移量:

struct testcls{

     int a;

     int b;

};

testcls *cls= new testcls;

UINT offset = (UINT)&((testcls*)0)->b;

 

 

 

 

编译

Fontconfig部分头文件需要在makefile时产生,比如fc-lang.h,fc-case.h,将其在linux下编译fontconfig.tgz,产生这几个头文件再拷贝出来

 

 

 

 

FONTCONFIG WINCE/WIN32移植

 

WinX版本去除了以下内容:

     FcCache

     FcSerialize  不支持对象的序列化存储

     不支持多字体目录

     不支持多cache目录

     所以不支持多进程共用fontconfig cache内容,也就是不能用mmap进行map到自己的空间。这样每个进程必须消耗一系列的Pattern及其相关对象所占据的内存空间。

     因为在嵌入式环境配置的字体可能只有12种,这种内存的消耗应该不会是很大

 

WINCE:

     字体存储和配置信息储存在wince.h文件

#define FONTS_DIR      "/nandflashpartition/fonts"

#define FONTS_CACHE_DIR "/nandflashpartition/fonts-cache"

#define FONTCONFIG_FILE FONTS_DIR##"/fonts.conf"

 

Fonts.conf

<fontconfig>

<dir>/nandflashpartition/fonts</dir>

<cachedir>/nandflashpartition</cachedir>

<font-file>simhei.ttf</font-file>

</fontconfig>

CMakefile的配置

#去除_WIN32 _WINDOWS定义

ADD_DEFINITIONS(-D_WINCE -D_WIN32_WCE=0x500 -DUNDER_CE -DWINCE -DARM -D_ARM_ -D_UNICODE -DUNICODE)

 

INCLUDE_DIRECTORIES("../" "C:/temp9/papyrus_dependencies/include" )

 

add_library (fontconfig

#    fcatomic.c

     fcblanks.c

#    fccache.c

     fccfg.c

     fccharset.c

     fcdbg.c

     fcdefault.c

     fcdir.c

     fcfreetype.c

     fcfs.c

     fcinit.c

     fclang.c

     fclist.c

     fcmatch.c

     fcmatrix.c

     fcname.c

     fcpat.c

#    fcserialize.c

     fcstr.c

     fcxml.c

     ftglue.h

     ftglue.c

     wince.h

     wince_imp.c                

     )

 

Fontconfig目前作为静态库生成并被使用,因为dll生成必须定义fontconfig.def(此操作费时)

 

posted @ 2008-04-04 02:50 放屁阿狗 阅读(2177) | 评论 (2)编辑 收藏

cairo
agg
wxArt2D
geos


posted @ 2008-04-04 02:40 放屁阿狗 阅读(946) | 评论 (0)编辑 收藏


cairo是opensource的项目,其在*nix上利用makefile,gcc便能很方便进行编译,客户程序也能很方便pkg-config进行链接.

cairo 依赖项目:  FreeType,FontConfig,libPng,libExpat,libZ

Win32平台的编译也是非常简单,只要将makefile.in里面的东东搬到CMakefiles.txt中,然后用CMake(2.4)产生vs2005的工程即可

WINCE的编译可谓是异常的麻烦
FreeType倒是不错,自带了wince的工程档,FontConfig却是没有,且Fontconfig为了实现多进程共享字体资源而采用了cache机制,应用程序通过mmap()将字体信息映射到自己的地址空间来访问。这种模式在wince里可谓没有必要,所以对Fontconfig进行了比较大的手术,去除了FcSerialize,FcCache,FcPattern的内存映射机制,同时限定fonts.conf的存储位置,字体目录位置等等。

libPng:
libpng的  png_convert_from_struct_tm ,png_convert_from_time_t  在wince得不到实现,因为部分的c runtime functions在wince没有实现,所以不得已自己实现这些功能函数

我编译的cairo特性:
    支持win32_surface,freetype,fontconfig,image_surface,png_surface











posted @ 2008-04-04 02:39 放屁阿狗 阅读(2714) | 评论 (9)编辑 收藏

#define OUT
#define INOUT
#define IN

#define INIT_LIST_HEAD(x)    

#define btsc_TRUE     0
#define btsc_FALSE    1
#define btsc_NULL     0

struct list_head{
    struct list_head* prev,*next;
};


struct btsc_Property{
    char *         name;
    char *         value;        
};


struct btsc_Packet{
    /*struct list_head    list;*/
    struct btsc_Property**     properties;
    int                size;
    int                capacity;
    struct btsc_Context    *    ctx;
};

struct btsc_Packet*     btsc_Packet_Alloc(struct btsc_Context* );
void                    btsc_Packet_Free(struct btsc_Packet*);

struct btsc_Property*    btsc_Property_Alloc(struct btsc_Context* ,char * name,char * value);
void                    btsc_Property_Free(struct btsc_Property*);


struct btsc_Property*     btsc_Property_Get(struct btsc_Packet* packet,char * name);     
void                    btsc_Property_Append(struct btsc_Packet* packet,struct btsc_Property * );


struct btsc_Context{
    void (*tx)(struct btsc_Context*,unsigned char * data,int len);        
    int (*notifier)(struct btsc_Packet* packet);/*外部释放packet,返回NULL*/        
    int        packet_cached_size;
    int        recv_cached_capacity;                        
    char*    recv_buff;                                    
    int        recv_size;        
    void*    user;    // 外部数据传递                            
};


int     btsc_init(struct btsc_Context* IN ctx);    
void     btsc_cleanup(struct btsc_Context* IN ctx);
int        btsc_Pack(struct btsc_Context* IN ctx,struct btsc_Packet* packet,unsigned char * INOUT buff,int* INOUT size);    
void    btsc_Parse(struct btsc_Context* , char * data,int len);


#define BTSC_PACKET_BEGIN(ctx) {\
                                struct btsc_Context* _ctx_internel;\
                                struct btsc_Packet * _pkt ;\
                                _ctx_internel= (ctx);\
                                _pkt = btsc_Packet_Alloc(_ctx_internel);
                                
/* key is not suitable for vairable*/                                
#define BTSC_NEW_PROPERTY(key,value)    {\
                                            struct btsc_Property * _ppt =btsc_Property_Alloc(_ctx_internel,key,value);\
                                            btsc_Property_Append(_pkt,_ppt);\
                                        }
#define BTSC_PACKET_END()        btsc_Pack(_ctx_internel,_pkt,btsc_NULL,0);\
                                btsc_Packet_Free(_pkt);\
                                }

#define BTSC_FOREACH(packet,ppt)    {\
                                    int n;\
                                    for(n=0;n<packet->size;n++){\
                                        ppt = packet->properties[n];
#define BTSC_END_FOREACH()            }\
                                }








/*
    name:            btsc
                    serial communicating  with bluetooth and app-user
    desc:            pair parameter codec
   
        packet=[ key:name,...]
       
    implemented:     zhangbin ,  3 hours occupied
    date:            2007-01-26
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _UNIX
#include <unistd.h>
#endif
#include "btsc.h"

#define PACKET_HEAD        '<'
#define PACKET_TAIL        '>'
#define PROPERTY_DELIMITER    ','
#define PAIR_DELIMITER        '='
#define ESCAPE_CHAR            '\\'


int calcEscapleLength(char * str);
char* escape_copy(char * dest,char * src);
void trim_escape_copy(char * dest,char * src,int size);
int  calcPacketLength(struct btsc_Packet* pkt);
int    is_escape_char(char c);
void parseProperty(struct btsc_Packet * pkt,char * s,char * e);
void parsePacket(struct btsc_Context* ctx,char * s,char* e);
char*     __memchr(char * s,char* e,char c);

char escape_ch_table[]={PACKET_HEAD,PACKET_TAIL,PROPERTY_DELIMITER,PAIR_DELIMITER,ESCAPE_CHAR,'\0'};

struct btsc_Packet*     btsc_Packet_Alloc(struct btsc_Context* ctx){   
    struct btsc_Packet * pt = malloc(sizeof(struct btsc_Packet));       
    pt->size = 0;
    pt->capacity = ctx->packet_cached_size;
    pt->properties=malloc(pt->capacity*sizeof(struct btsc_Property*));   
    pt->ctx = ctx;
    return pt;   
}

void    btsc_Packet_Free(struct btsc_Packet* pt){   
    struct btsc_Property** tmp;
    if( !pt )     return ;
    tmp = pt->properties;
    while(pt->size--){
        btsc_Property_Free(*tmp++);               
    }       
    if( pt->properties){
        free(pt->properties); 
    }
    free(pt);
}


struct btsc_Property*    btsc_Property_Alloc(struct btsc_Context* ctx,char * name,char * value){
    struct btsc_Property * ppt;
    printf("enter btsc_Property_Alloc()\n");
    ppt = malloc( sizeof( struct btsc_Property) );
    if(!ppt)    printf("error: malloc failed (s1)\n");
    ppt->name = malloc( strlen(name)+1);
    if( !ppt->name ) printf("error: malloc failed (s2)\n");
    strcpy(ppt->name,name);   
    ppt->value = malloc( strlen(value)+1);
    if( !ppt->value) printf("error: malloc failed (s3),str:%s, len: %d\n",value,strlen(value)+1);
    strcpy( ppt->value,value);
    return ppt;
}

void        btsc_Property_Free(struct btsc_Property* ppt){
    if( !ppt )    return;
    free( ppt->name);
    free( ppt->value);
    free( ppt);
}

/* scan pointer array */
struct btsc_Property*     btsc_Property_Get(struct btsc_Packet* pkt,char * name){
    int size;
    struct btsc_Property* ppt;
    size = pkt->size;
    while(size--){
        ppt = pkt->properties[size];
        if( !strcmp( name, ppt->name ) ){
            return ppt;/*that's ok */
        }
    }
    return btsc_NULL;
}

/* low effeciency, memory allocation,more costs*/
void    btsc_Property_Append(struct btsc_Packet* pt,struct btsc_Property * ppt){
    struct btsc_Property** tmpppt;
    if( pt->size==pt->capacity){        
        pt->capacity += pt->ctx->packet_cached_size;   
        tmpppt = pt->properties;       
        pt->properties = malloc( pt->capacity * sizeof( struct btsc_Property**) );
        memcpy( pt->properties, tmpppt, pt->size * sizeof( struct btsc_Property**));
        free( tmpppt);
    }
    pt->properties[pt->size++]=ppt;   
}

int     btsc_init(struct btsc_Context* ctx){   
    ctx->packet_cached_size = 10;   
    if( ctx->recv_cached_capacity==0){
        ctx->recv_cached_capacity = 1024*2;   
    }
    ctx->recv_buff = malloc( ctx->recv_cached_capacity );
    ctx->recv_size = 0;
    return btsc_TRUE;
}

void     btsc_cleanup(struct btsc_Context* ctx){
    free(ctx->recv_buff);   
}

/*
**    name:    calcEscapleLength
**    desc:    计算含转义字符串长度
*/
int     calcEscapleLength(char * str){
    int len;
    char * pesc;
    len = 0;   
    while( *str ){
        pesc = escape_ch_table;
        while( *pesc ){
            if( *pesc==*str){
                len++;
                break;
            }
            pesc++;
        }       
        str++;
    }   
    return len;
}


char* escape_copy(char * dest,char * src){
    char * pesc;
    while( *src ){
        pesc = escape_ch_table;
        while( *pesc ){
            if( *pesc==*src){
                *dest++=ESCAPE_CHAR;
                break;
            }
            pesc++;
        }
        *dest++=*src++;               
    }   
    return dest;   
}

void trim_escape_copy(char * dest,char * src,int size){
    int last_escape = btsc_FALSE;
    while( size--){
        if( *src == ESCAPE_CHAR && last_escape != btsc_TRUE){       
            last_escape = btsc_TRUE    ;
            src++;
            continue;
        }
        last_escape = btsc_FALSE;
        *dest++=*src++;       
    }
}

int       calcPacketLength(struct btsc_Packet* pkt){
    int len;
    int size;
    struct btsc_Property* ppt;   
    len = 0;
    size = pkt->size;
    while( size--){
        ppt = pkt->properties[size];   
        len+=strlen(ppt->name)+strlen(ppt->value);   

        len+= calcEscapleLength(ppt->name);
        len+= calcEscapleLength(ppt->value);   
    }
    len+= pkt->size*2+1;
    return  len;
}


int        btsc_Pack(struct btsc_Context*  ctx,struct btsc_Packet* pkt,unsigned char * obuff,int* osize){
    struct btsc_Property* ppt;
    int size;
    int len;
    unsigned char * buff;
    char * pbuff;
    len = calcPacketLength( pkt);
    buff = malloc( len );
    size = pkt->size;
    pbuff = (char*)buff;
    *pbuff++=PACKET_HEAD;   
    while( size--){
        ppt = pkt->properties[size];   
        pbuff = escape_copy(pbuff,ppt->name);
        *pbuff++=PAIR_DELIMITER;
        pbuff = escape_copy(pbuff,ppt->value);
        if( size ){
            *pbuff++=PROPERTY_DELIMITER;           
        }
    }
    *pbuff = PACKET_TAIL;
    if( ctx->tx ){
        ctx->tx(ctx,buff,len);
    }
    if( obuff && *osize >=len){
        memcpy( obuff, buff ,len);
        *osize = len;
    }

    free(buff);
    return btsc_TRUE;   
}

/* e not in range*/
char*     __memchr(char * s,char* e,char c){
    while( s!=e){
        if( *s == c){
            return s;
        }       
        s++;
    }
    return btsc_NULL;
}

int        is_escape_char(char c){
    return btsc_FALSE;   
}

/*
    name: parseProperty
    desc: 指定内存范围中提取属性  key=>value
        搜索包含e
    params:   
        pkt    --    消息数据包
        s    --    起始内存地址
        e    --    结束地址 ,
*/
void parseProperty(struct btsc_Packet * pkt,char * s,char * e){
    char * p1,*p2;
    int n;
    struct btsc_Property*    ppt;
    p1 = s ;
    p2 = e;
__REPEAT:   
    p1 = __memchr(p1,e+1,PAIR_DELIMITER);
    if( p1 ){
        if( *(p1-1) == ESCAPE_CHAR ){
            p1++;
            goto __REPEAT;
        }
        ppt = malloc( sizeof( struct btsc_Property ));
        n = p1-s;        
        ppt->name = malloc( n+1 );
        memset(ppt->name,0,n+1);       
        trim_escape_copy(ppt->name,s,n);
       
        n =e-p1;
        ppt->value = malloc( n+1);
        memset(ppt->value,0,n+1);
        trim_escape_copy(ppt->value,p1+1,n);
       
        btsc_Property_Append(pkt,ppt);
    }
}

/*
    name: parsePacket
    desc:    分解指定内存到包结构
            成功分解出包立刻回送到应用接收者 ( btsc_Context::notifier)
    param:
        s,e     内存地址 (处e)

** 缓冲区还需进一步测试,包括缓冲区大小调节, 不完整协议包格式的容错
*/
void     parsePacket(struct btsc_Context* ctx,char * s,char* e){
    char *p,*p1,*p2;
    struct btsc_Packet * pkt;
    if( e-s <=1 ){
        return ;
    }
    pkt = btsc_Packet_Alloc(ctx);
   
    p1 = s+1;
    p2 = e-1;
    p = p1;
__REPEAT:   
    p = __memchr(p,e,PROPERTY_DELIMITER);
    if( p ){
        if( *(p-1)==ESCAPE_CHAR){
            p = p+1;
            goto __REPEAT;
        }
        parseProperty(pkt,p1,p-1);
        p1 = ++p;
        goto __REPEAT;
    }
    /*allow one property reside in*/
    parseProperty(pkt,p1,e-1);
    if( ctx->notifier ){
        if(ctx->notifier(pkt)){ /* nonzero value, delete internal*/
            btsc_Packet_Free(pkt);           
        }
    }else{
       btsc_Packet_Free(pkt);   
    }
}

void    btsc_Parse(struct btsc_Context* ctx, char * data,int size){
    int len ;
_RESTART:
    while( size ){
        len = ctx->recv_cached_capacity - ctx->recv_size;
        if( len >0){
            if( size <= len){
                len = size;
                size = 0;
            }else{
                size-=len;
            }
            memcpy( ctx->recv_buff+ctx->recv_size,data,len);
            ctx->recv_size+=len;
            data+=len;
        }   
       
        {
            char * p1,*p2;           
_RESCAN:           
            p1 = ctx->recv_buff;
_RESCAN_HEAD:             
            p1 = __memchr(p1,ctx->recv_buff+ctx->recv_size,PACKET_HEAD);           
            if( !p1 ){
                ctx->recv_size =0;
                if( size ){
                    goto _RESTART;
                }
            }
            if( p1>ctx->recv_buff && *(p1-1)==ESCAPE_CHAR){ /* "\<" */
                p1++;
                goto _RESCAN_HEAD;   
            }
           
            /*move backward*/
            ctx->recv_size -=(p1-ctx->recv_buff);
            memmove(ctx->recv_buff,p1, ctx->recv_size);
            p1=ctx->recv_buff;
            p2 = p1+1;
_RESCAN_TAIL:           
            p2 = __memchr(p2,ctx->recv_buff+ctx->recv_size,PACKET_TAIL);
            if( !p2 ){
                if( ctx->recv_size == ctx->recv_cached_capacity ){
                    ctx->recv_size  = 0;
                }
                goto _RESTART;
            }
            if( *(p2-1) == ESCAPE_CHAR ){
                p2++;
                goto _RESCAN_TAIL;   
            }
           
            parsePacket(ctx,p1,p2);
            ctx->recv_size -=p2-p1+1;
            if( ctx->recv_size ){
                memmove(ctx->recv_buff,p2+1,ctx->recv_size);
                goto _RESCAN;
            }             
        }       
    }
}

/*   debug */
#ifdef _DEBUGX
void tx(unsigned char * data,int len);
void notifier(struct btsc_Packet* packet);
/*初始化上下文, tx=发送处理函数,notifier=接收函数*/
struct btsc_Context c={tx:tx,notifier:notifier};

/*测试数据接收并解析*/
void rx(){   
     char * msg="<MSG=HELLO,NAME=SCOTT>"
                 "<MSG2=HELLO2,NAME2=SCOTT2>"
                 "<MSG3=HELLO3,NAME3=SCOTT3>"; /*simulating data*/
    int len = strlen(msg);
    btsc_Parse(&c,msg,len);
}
/*发送处理过程*/
void tx(unsigned char * buff,int len){   
    char *outmsg = malloc(1024*10);
    memset(outmsg,0,1024*10);
    memcpy(outmsg,buff,len);
    printf("encode str: %s\n",outmsg);
    free(outmsg);
    btsc_Parse(&c,buff,len);
}

void notifier(struct btsc_Packet* packet){
    struct btsc_Property * ppt;
    ppt = btsc_Property_Get(packet,"MSG");
    if(ppt)
        printf("property get: MSG=>%s\n",ppt->value);
    /*遍历包内属性参数*/
    BTSC_FOREACH(packet,ppt);
    printf("packet: %s=>%s\n",ppt->name,ppt->value);
    BTSC_END_FOREACH();
}

int main(){
    int r;
    /*optional*/
    c.recv_cached_capacity = 1024; /*初始化接收缓冲区大小 byte*/
    c.packet_cached_size = 5;    /*消息包缓冲属性个数*/
    btsc_init(&c);            /*上下文初始化*/
    puts("test rx()...");
    rx();    /*接*/
    puts("escape testing...");   
    do{
        /*构造消息包,并完成发送*/
        BTSC_PACKET_BEGIN(&c);
        BTSC_NEW_PROPERTY("MSG","calling");

        BTSC_PACKET_END();   
        usleep(1000*50);
        printf(">>seq:%d\n",r);
    }while(0);
       
    btsc_cleanup(&c);   
   
    return 0;
}


#endif

posted @ 2007-02-23 22:54 放屁阿狗 阅读(1072) | 评论 (0)编辑 收藏

仅列出标题
共25页: First 17 18 19 20 21 22 23 24 25