#include "stdafx.h" //去掉....
#ifdef _DEBUG
#include "windows.h"
#endif
#include "outi_extract.h"
#ifdef _MSC_VER
#pragma warning (disable: 4996)
#endif
//比较a,b内存地址值
#define EQUAL_MEM(a,b) ( ( long long)(a) - ( long long)(b) )
//获取从m开始的内存偏移量f
#define OFFSET_MEM(m,f) (void*)(((unsigned long (m)) + (unsigned long)(f)))
#ifdef _WIN32
#define _NEWLINE_ ("\r\n")
#define _NEWLINE_LEN_ 2
#elif linux
#define _NEWLINE_ ("\n")
#define _NEWLINE_LEN_ 1
#elif _UNIX
#define _NEWLINE_ ("\n")
#define _NEWLINE_LEN_ 1
#endif
char * _strstrn( char * psrc,int len, char * psubstr)
{
if(psrc && psubstr && len>0){
char * pfind=NULL;
while( len-- > 0 )
{
pfind=strstr(psrc++,psubstr);
if(pfind)
return pfind;
}
}
return NULL;
}
//提取 outi.txt内的文件为各自的段落
char * oui_extractsegment(
__in char * pmemstart,
__in char * pmemend,
__out char * szbuf_oui,
__out int * poui_len,
__out char * szbuf_orgz,
__out int * porgz_len,
__out char * szbuf_comid,
__out int * pcomid_len,
__out char * szbuf_addr,
__out int * paddr_len)
{
//1. 内存区域检查,是否超出
//2. 规律
/*
CRLF (当前段落的开始) (上一个段落的终止)
内容1........CRLF
内容2........CRLF
内容3..........CRLF
内容n............CRLF
CRLF (下一个段落的开始)
2.1 CRLF 后面 不会存在字符
CRLF前面: 2.1a 如果不存在字符 则说明是片段的开始或终止
2.1b如果前面存在字符,则说明当前位置为某个片段的某行字符
3 查找规则
3.1 查找字符 不应仅是一个字符,至少是几个字符串
段落
关键字 为 xx-xx-xx 的 两个 " - " 条件为 在每个 - 间 存在两个16进制字符
且 向前偏移 能够找到 \n 则说明为一个 段落 的开始 ,然后向后查找 2 个 \n\n 则为
这个段落的结束
行
每一行以一个 \n开始 和 另一个 \n 结束 ,当查找到 \n 且接下来的字符(获取到达文件结尾)不是\n 则之前
在两个 \n 间的数据为一个段落内的一行数据
1.查找方法 找出 连续2个换行符 ,然后找出最近的 连续2个 换行符 ,如此为一个段落
2.按行解析
3.找到并解析 xx-xx-xx 如果条件满足 存在两个 - 就是 要查找的开始
*/
memset(szbuf_oui,0,12);
memset(szbuf_orgz,0,128);
memset(szbuf_comid,0,12);
memset(szbuf_addr,0,512);
//偏移溢出
if(EQUAL_MEM(pmemstart,pmemend) >= 0)
return NULL;
//指向当前段落的开始和结束,各自为两个连续的换行符
char * pseg_begin=NULL;
char * pseg_end=NULL;
int seg_len=0;
//换行符
char _line_label[16];
memset(_line_label,0,16);
int _line_c=3;
//可能的情况: 存在3个行
strcat(_line_label,_NEWLINE_);
strcat(_line_label,_NEWLINE_);
strcat(_line_label,_NEWLINE_);
pseg_begin=strstr(pmemstart,_line_label);
if(EQUAL_MEM(pseg_begin,pmemend)>=0)
return NULL;
if(pseg_begin==NULL)
{
_line_label[4]=0;
_line_label[5]=0;
pseg_begin=strstr(pmemstart,_line_label);
_line_c=2;
}
_line_label[4]=0;
_line_label[5]=0;
if(pseg_begin==NULL)
return NULL;
pseg_end=strstr((char*)OFFSET_MEM(pseg_begin,_line_c*_NEWLINE_LEN_),_line_label);
if(EQUAL_MEM(pseg_end,pmemend)>0)
return NULL;
seg_len=EQUAL_MEM(pseg_end,pseg_begin);
//第一行
char * pline_begin = pseg_begin; //行的开头
char * pline_end = _strstrn( (char*)OFFSET_MEM(pseg_begin,_line_c*_NEWLINE_LEN_) ,seg_len,_NEWLINE_); //行的结尾
int line_len=EQUAL_MEM(pline_end,pline_begin);
if(EQUAL_MEM(pline_end,pseg_end) >=0)
return NULL; //段落结束 不包括任何数据
if(line_len==0)
return pseg_end; //段落结束 不包括任何数据
//找到并解析 xx-xx-xx
char * phyphen=_strstrn(pline_begin,line_len,"-" ); //找出第一个 -
if(phyphen==NULL)
{
return NULL;
}
phyphen = (char*)OFFSET_MEM(phyphen,3); //找出第二个 -
if(*phyphen != '-' )
return NULL;
//向前偏移
phyphen=(char*)OFFSET_MEM(phyphen,-5);
memcpy(szbuf_oui,phyphen,8); //------------------ 假设固定为8个字节 xx-xx-xx oui
*poui_len=strlen(szbuf_oui); //不包括 终止符
//解析 组织名称
char * porgz= _strstrn(phyphen,line_len,")"); //找出 )
while( *(++porgz) <= 32 ) ; //去掉不能显示的 ,包括空格符
int orgz_len=EQUAL_MEM(pline_end,porgz);
memcpy(szbuf_orgz,porgz,orgz_len); // ---------------------------拷贝组织名称
*porgz_len=strlen(szbuf_orgz); //不包括终止符
//第二行
pline_begin=pline_end;
pline_end = _strstrn( (char*)OFFSET_MEM(pline_begin, _NEWLINE_LEN_),seg_len-=line_len,_NEWLINE_);
line_len = pline_end-pline_begin;
i�