DS_xx工具
来源:互联网 发布:lca算法 pascal 编辑:程序博客网 时间:2024/05/09 07:43
************************************************************************************
************************************************************************************
************************************************************************************
*************************** ds. h ***************************************
************************************************************************************
************************************************************************************
*/
#ifndef __DS_H__
#define __DS_H__
#include <stdio.h>
#define DS_SIZE_CONTENT 4096
#define DS_SIZE_UNIT 64
#define DS_SIZE_PRE_COMMENT 1024
#define DS_SIZE_POST_COMMENT 1024
#define DS_MAX_ENTRY 10000
#define DS_MAX_ENTRY_INT 10000
#define DS_SIZE_ERROR 4096
#define DS_SIZE_RD 6144
#define DS_IGNORE_CASE 1
#define DS_IGNORE_PUNCT 2
#define DS_IGNORE_CASE_AND_PUNCT 3
typedef struct
{
unsigned int id;
char content[DS_SIZE_CONTENT];
char unit[DS_SIZE_UNIT];
char pre_comment[DS_SIZE_PRE_COMMENT];
char post_comment[DS_SIZE_POST_COMMENT]; //default = \n
}DS, *PDS, **PPDS;
typedef struct
{
PPDS pDSS;
unsigned int num; //the number of PDS
PPDS pDSS_int;
unsigned int num_int; //the number of PDS insert
unsigned int id_pointer; //id_pointer+1 is inserted next.
unsigned int id_auto; //id auto increase
char error[DS_SIZE_ERROR];
int char_mode; //case: 1 ignore case, 2 ignore punctuation, 3 ignore case and punctuation
}DS_BLOCK, *PDS_BLOCK;
/*=============== initialization and ending ========================*/
/************************************************************************/
/* 初始化文件块句柄
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
NULL 失败
其他: 成功
*/
/************************************************************************/
PDS_BLOCK ds_init();
/************************************************************************/
/* 释放文件块句柄
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
无
*/
/************************************************************************/
void ds_end(PDS_BLOCK p_b);
/*====================== read-write ==============================*/
/************************************************************************/
/* 读取文件
参数:
PDS_BLOCK p_b 文件块句柄
char* file_name 文件名
返回值:
0 成功
其它 失败
*/
/************************************************************************/
int ds_read(PDS_BLOCK p_b, char *file_name);
/************************************************************************/
/* 写入文件
参数:
PDS_BLOCK p_b 文件块句柄
char* file_name 文件名
返回值:
0 成功
其它 失败
*/
/************************************************************************/
int ds_write(PDS_BLOCK p_b, char *file_name, char *mode);
/************************************************************************/
/* 追加写入文件
参数:
PDS_BLOCK p_b 文件块句柄
char* file_name 文件名
PDS p_ds 条目
返回值:
0 成功
其它 失败
*/
/************************************************************************/
int ds_write_entry(PDS_BLOCK p_b, char *file_name, char *mode, PDS p_ds);
/*========================= search ==============================*/
/************************************************************************/
/* 根据ID查询条目
参数:
PDS_BLOCK p_b 文件块句柄
unsigned int id ID
PPDS pp_ds 返回条目
返回值:
0 查询成功
1 查询不到
其它 查询失败
*/
/************************************************************************/
int ds_search_id(PDS_BLOCK p_b, unsigned int id, PPDS pp_ds);
/************************************************************************/
/* 根据内容查询条目(不区分大小)
参数:
PDS_BLOCK p_b 文件块句柄
char *p_content 内容
char *p_unit 单位
PPDS pp_ds 返回条目
返回值:
0 查询成功
1 查询不到
其它 查询失败
*/
/************************************************************************/
int ds_search_content_unit(PDS_BLOCK p_b, char *p_content, char *p_unit, PPDS pp_ds);
/*========================= insert ==============================*/
/************************************************************************/
/* 根据ID、内容插入条目
参数:
PDS_BLOCK p_b 文件块句柄
unsigned int id ID
char *p_content 内容
char *p_unit 单位
PPDS pp_ds 返回插入成功或已存在的条目
返回值:
0 插入成功
其它 插入失败
*/
/************************************************************************/
int ds_insert_id_content_unit(PDS_BLOCK p_b, unsigned int id, char *p_content, char*p_unit, PPDS pp_ds);
/************************************************************************/
/* 根据内容插入条目,ID自增、内容不能重复
需先调用ds_set_id_pointer设置,插入的位置
参数:
PDS_BLOCK p_b 文件块句柄
char *p_content 内容
char *p_unit 单位
PPDS pp_ds 返回插入成功或已存在的条目
返回值:
0 插入成功
其它 插入失败
*/
/************************************************************************/
int ds_insert_auto(PDS_BLOCK p_b, char *p_content, char *p_unit, PPDS pp_ds);
/************************************************************************/
/* 根据条目插入,id、内容不能重复
参数:
PDS_BLOCK p_b 文件块句柄
PDS p_ds 待插入的条目
返回值:
0 插入成功
其它 插入失败
*/
/************************************************************************/
int ds_insert_entry(PDS_BLOCK p_b, PDS p_ds);
/*========================= delete ==============================*/
/************************************************************************/
/* 根据ID删除
参数:
PDS_BLOCK p_b 文件块句柄
unsigned int id ID
返回值:
0 删除成功
其它 删除失败
*/
/************************************************************************/
int ds_delete_id(PDS_BLOCK p_b, unsigned int id);
/*========================= replace ==============================*/
/************************************************************************/
/* 根据ID替换
参数:
PDS_BLOCK p_b 文件块句柄
unsigned int id, ID
PDS p_ds 条目
返回值:
0 替换成功
其它 替换失败
*/
/************************************************************************/
int ds_replace_id(PDS_BLOCK p_b, unsigned int id, PDS p_ds);
/************************************************************************/
/* 根据条目替换
参数:
PDS_BLOCK p_b 文件块句柄
PDS p_ds 条目
返回值:
0 替换成功
其它 替换失败
*/
/************************************************************************/
int ds_replace_entry(PDS_BLOCK p_b, PDS p_ds);
/*======================== sort =============================*/
/************************************************************************/
/* 正向排序:注意只排序p_b的pDSS部分
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
无
*/
/************************************************************************/
void ds_sort(PDS_BLOCK p_b);
/************************************************************************/
/* 正向排序PPDS pTexts
参数:
PPDS pTexts DS数据
unsigned int num PDS的个数
返回值:
无
*/
/************************************************************************/
void ds_sort_ppds(PPDS pDSS, unsigned int num);
/*======================== merge =============================*/
/************************************************************************/
/* 合并:将p_b的pDSS_int部分合并到p_b的pDSS
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
0 成功
其它 失败
*/
/************************************************************************/
int ds_merge(PDS_BLOCK p_b);
/*=============== getter and setter ========================*/
/************************************************************************/
/* 设置ID指针,条目被插入到ID+1位置
参数:
PDS_BLOCK p_b 文件块句柄
unsigned int id_auto ID
返回值:
无
*/
/************************************************************************/
void ds_set_id_auto(PDS_BLOCK p_b, unsigned int id_auto);
/************************************************************************/
/* 读取id_auto
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
ID指针
*/
/************************************************************************/
unsigned int ds_get_id_auto(PDS_BLOCK p_b);
/************************************************************************/
/* 设置ID指针,条目被插入到ID+1位置
参数:
PDS_BLOCK p_b 文件块句柄
unsigned int id_pointer ID
返回值:
无
*/
/************************************************************************/
void ds_set_id_pointer(PDS_BLOCK p_b, unsigned int id_pointer);
/************************************************************************/
/* 读取当前ID指针
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
ID指针
*/
/************************************************************************/
unsigned int ds_get_id_pointer(PDS_BLOCK p_b);
/************************************************************************/
/* 获取错误信息
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
错误信息
*/
/************************************************************************/
char* ds_get_err(PDS_BLOCK p_b);
/************************************************************************/
/* 清除错误信息
参数:
PDS_BLOCK p_b 文件块句柄
返回值:
无
*/
/************************************************************************/
void ds_clr_err(PDS_BLOCK p_b);
/************************************************************************/
/* 设置大小写
参数:
PDS_BLOCK p_b 文件块句柄
char_mode #define DS_IGNORE_CASE 1
#define DS_IGNORE_PUNCT 2
#define DS_IGNORE_CASE_AND_PUNCT 3
返回值:
ID指针
*/
/************************************************************************/
void ds_set_search_mode(PDS_BLOCK p_b, int char_mode);
#endif
/*
************************************************************************************
************************************************************************************
************************************************************************************
*************************** ds. c ***************************************
************************************************************************************
************************************************************************************
*/
#include "ds.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*============ function prototype ================*/
static char* quote_position (char *pdata);
static void write_a_entry (FILE *fp, PDS p_ds);
void ignore_punctuation (char *str);
// ======================== //
// getter and setter //
// ======================== //
void ds_set_id_auto(PDS_BLOCK p_b, unsigned int id_auto)
{
if (NULL == p_b)
return;
p_b->id_auto = id_auto;
}
unsigned int ds_get_id_auto(PDS_BLOCK p_b)
{
if (NULL == p_b)
return 0xFFFFFFFF;
return p_b->id_auto;
}
void ds_set_id_pointer(PDS_BLOCK p_b, unsigned int id_pointer)
{
if (NULL == p_b)
return;
p_b->id_pointer = id_pointer;
}
unsigned int ds_get_id_pointer(PDS_BLOCK p_b)
{
if (NULL == p_b)
return 0xFFFFFFFF;
return p_b->id_pointer;
}
char* ds_get_err(PDS_BLOCK p_b)
{
if (NULL == p_b)
return "PDS_BLOCK is NULL.\n";
else
return &p_b->error[0];
}
void ds_clr_err(PDS_BLOCK p_b)
{
p_b->error[0] = '\0';
}
// ======================== //
// extern function //
// ======================== //
PDS_BLOCK ds_init()
{
PDS_BLOCK p_b = NULL;
p_b = malloc(sizeof(DS_BLOCK));
if (NULL == p_b)
{
return NULL;
}
memset(p_b, 0, sizeof(DS_BLOCK));
p_b->pDSS = malloc(DS_MAX_ENTRY * sizeof(PDS));
if (NULL == p_b->pDSS)
{
free(p_b);
return NULL;
}
p_b->pDSS_int = malloc(DS_MAX_ENTRY_INT * sizeof(PDS));
if (NULL == p_b->pDSS_int)
{
free(p_b->pDSS);
free(p_b);
return NULL;
}
memset(p_b->pDSS, 0, DS_MAX_ENTRY * sizeof(PDS));
memset(p_b->pDSS_int, 0, DS_MAX_ENTRY_INT * sizeof(PDS));
p_b->id_pointer = 0xFFFFFFFF;
return p_b;
}
void ds_end(PDS_BLOCK p_b)
{
unsigned int i = 0;
if (NULL == p_b)
return;
for (i=0; i<p_b->num; i++)
{
free(p_b->pDSS[i]);
p_b->pDSS[i] = 0;
}
p_b->num = 0;
for (i=0; i<p_b->num_int; i++)
{
free(p_b->pDSS_int[i]);
p_b->pDSS_int[i] = 0;
}
p_b->num_int = 0;
free(p_b->pDSS_int);
p_b->pDSS_int = 0;
free(p_b->pDSS);
p_b->pDSS = 0;
free(p_b);
p_b = 0;
}
/********
1.skip comment line and blank line
2.identify data line : 0x??,0x??
3.read id : 0x??,0x??
4.read content and unit
*********/
int ds_read(PDS_BLOCK p_b, char *file_name)
{
FILE *fp = NULL;
unsigned int id = 0;
int ret = 0;
long row_no = 0;
int pos[4] = {0};
char *p = NULL;
char *p_quote = NULL; //first quote
char *p_post = NULL; //post comment
char *p_content = NULL; //content
char *p_unit = NULL; //unit
char read[DS_SIZE_RD] = {0};
char comment[DS_SIZE_PRE_COMMENT] = {0}; //pre-comment
char err[100] = {0};
char err_buf[DS_SIZE_ERROR] = {0};
if (NULL == p_b)
return -1;
if (NULL == file_name)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
//__asm{INT 3};
if (NULL == (fp=fopen(file_name, "rt")))
{
sprintf(p_b->error, "Can not open %s.\n", file_name);
return -1;
}
ds_clr_err(p_b);
for (row_no=1; !feof(fp); row_no++)
{
#if defined _DEBUG
printf("Row no %d.\n", row_no);
#endif
if (p_b->num >= DS_MAX_ENTRY)
{
sprintf(err, "More than %d entries.\n", DS_MAX_ENTRY);
strcat(p_b->error, err);
fclose(fp);
return -1;
}
if (NULL == fgets(read, sizeof(read), fp)) // only EOF
{
if (feof(fp))
break;
sprintf(err, "Read file data error.\n");
strcat(p_b->error, err);
fclose(fp);
return -1;
}
if (NULL==strchr(read, '\n') && !feof(fp)) // '\n' may be not in the last line.
{
sprintf(err, "Row %d: Too long line.\n", row_no);
strcat(err_buf, err);
while(NULL!=fgets(read, sizeof(read), fp) || !feof(fp))
{
if (NULL != strchr(read, '\n'))
break;
}
ret = -1;
continue;
}
if ('0' != read[0]) // empty row or pure comment row, because data line begine with 0x??,0x??
{ //settle pre-comment
p = &read[0];
while (' '==*p || '\t'==*p)
p++;
if ('\n'!=*p && ';'!=*p)
{
sprintf(err, "Row %d: Unknown row format.\n", row_no);
strcat(err_buf, err);
ret = -1;
continue;
}
if (strlen(comment)+strlen(p) > sizeof(comment)-2)
{
sprintf(err, "Row %d: Too long pre-omment.\n", row_no);
strcat(err_buf, err);
ret = -1;
continue;
}
strcat(comment, p);
}
else //entry row
{ //settle data
pos[3] = -1;
pos[2] = -1;
pos[1] = -1;
pos[0] = -1;
sscanf(&read[0], "%2x,%2x,%2x,%2x,", &pos[3], &pos[2], &pos[1], &pos[0]); // Not very strict, but it always work well.
if (pos[3]>0x100 || pos[3]<0 ||
pos[2]>0x100 || pos[2]<0 ||
pos[1]>0x100 || pos[1]<0 ||
pos[0]>0x100 || pos[0]<0)
{
sprintf(err, "Row %d: ID error.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
id = (pos[3]<<24) + (pos[2]<<16) + (pos[1]<<8) + (pos[0]);
p = &read[20];
while (' '==*p || '\t'==*p)
p++;
if ('\"' != *p)
{
sprintf(err, "Row %d: Not a quote follows ID.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
p_quote = quote_position(p); //search next speech mark
if (NULL == p_quote)
{
sprintf(err, "Row %d: Quote error.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
p_content = p+1;
*p_quote = '\0';
if (strlen(p_content) > DS_SIZE_CONTENT-1)
{
sprintf(err, "Row %d: Too long content.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
p = p_quote+1;
while (' '==*p || '\t'==*p)
p++;
if ('\"' != *p)
{
sprintf(err, "Row %d: Not a quote follows Content.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
p_quote = quote_position(p); //search next speech mark
if (NULL == p_quote)
{
sprintf(err, "Row %d: Quote error in Unit.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
p_unit = p+1; //unit begin
*p_quote = '\0';
if (strlen(p_unit) > DS_SIZE_UNIT-1)
{
sprintf(err, "Row %d: Too long unit.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
p_post = p_quote+1; //post comment begin
while (' '==*p_post || '\t'==*p_post)
p_post++;
if ('\n'!=*p_post && ';'!=*p_post)
{
if (!feof(fp))
{
sprintf(err, "Row %d: Error occurs behind unit.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
}
p_post = p_quote+1; //post comment begin
if (feof(fp) && NULL==strchr(p_post, '\n'))
strcat(p_post, "\n");
if (strlen(p_post) > DS_SIZE_POST_COMMENT-1)
{
sprintf(err, "Row %d: Too long post-comment.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
if (0 == ds_search_id(p_b, id, NULL))
{
sprintf(err, "Row %d: ID has existed.\n", row_no);
strcat(err_buf, err);
comment[0] = '\0';
ret = -1;
continue;
}
p_b->pDSS[p_b->num] = malloc(sizeof(DS));
if (0 == p_b->pDSS[p_b->num])
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
fclose(fp);
return -1;
}
memset(p_b->pDSS[p_b->num], 0, sizeof(DS));
p_b->pDSS[p_b->num]->id = id;
strcpy(p_b->pDSS[p_b->num]->content, p_content);
strcpy(p_b->pDSS[p_b->num]->unit, p_unit);
if ('\0' != comment[0]) // write pre-comment first
{
strcpy(p_b->pDSS[p_b->num]->pre_comment, comment);
comment[0] = '\0';
}
strcpy(p_b->pDSS[p_b->num]->post_comment, p_post);
p_b->num++;
} // end of if ('0' != read[0])
} // end of while (!feof(fp))
fclose(fp);
strcpy(p_b->error, err_buf);
return ret;
}
int ds_write(PDS_BLOCK p_b, char *file_name, char *mode)
{
FILE *fp = NULL;
unsigned int i = 0;
unsigned int insert_index = 0;
if (NULL == p_b)
return -1;
if (NULL == file_name)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
if (0xFFFFFFFF == p_b->id_pointer) //insert into the last
insert_index = p_b->num;
else
{ //search where to insert
for (i=0; i<p_b->num; i++)
{
if (p_b->pDSS[i]->id == p_b->id_pointer)
{
insert_index = i+1;
break;
}
}
if (i == p_b->num)
{
sprintf(p_b->error, "Id pointer %d is not exist.\n", p_b->id_pointer);
return -1;
}
}
if (NULL==mode || 0==strcmp(mode, "wt"))
fp = fopen(file_name, "wt");
else if(0 == strcmp(mode, "at"))
{
fp = fopen(file_name, mode);//"wt" "at"
}
else
{
sprintf(p_b->error, "Open mode error.\n");
return -1;
}
if (NULL == fp)
{
sprintf(p_b->error, "Can not open %s.\n", file_name);
return -1;
}
if(mode!=NULL && 0==strcmp(mode, "at"))
fseek(fp, SEEK_END, 0);
for (i=0; i<insert_index; i++)
{
write_a_entry(fp, p_b->pDSS[i]);
}
for (i=0; i<p_b->num_int; i++)
{
write_a_entry(fp, p_b->pDSS_int[i]);
}
for (i=insert_index; i<p_b->num; i++)
{
write_a_entry(fp, p_b->pDSS[i]);
}
fclose(fp);
return 0;
}
int ds_write_entry(PDS_BLOCK p_b, char *file_name, char *mode, PDS p_ds)
{
FILE *fp = NULL;
if (NULL==p_b)
return -1;
if (NULL==file_name)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
if (NULL==mode || 0==strcmp(mode, "wt"))
fp = fopen(file_name, "wt");
else if(0 == strcmp(mode, "at"))
{
fp = fopen(file_name, mode);//"wt" "at"
}
else
{
sprintf(p_b->error, "Open mode error.\n");
return -1;
}
if (NULL == fp)
{
sprintf(p_b->error, "Can not open %s.\n", file_name);
return -1;
}
if(mode!=NULL && 0==strcmp(mode, "at"))
fseek(fp, SEEK_END, 0);
write_a_entry(fp, p_ds);
fclose(fp);
return 0;
}
//
int ds_search_id(PDS_BLOCK p_b, unsigned int id, PPDS pp_ds)
{
unsigned int i = 0;
if (NULL==p_b)
{
return -1;
}
for (i=0; i<p_b->num; i++)
{
if (id == p_b->pDSS[i]->id)
{
if (NULL != pp_ds)
*pp_ds = p_b->pDSS[i];
return 0;
}
}
for (i=0; i<p_b->num_int; i++)
{
if (id == p_b->pDSS_int[i]->id)
{
if (NULL != pp_ds)
*pp_ds = p_b->pDSS_int[i];
return 0;
}
}
sprintf(p_b->error, "Can not find the entry with the same id.\n");
return 1;
}
int ds_search_content_unit(PDS_BLOCK p_b, char *p_content, char *p_unit, PPDS pp_ds)
{
unsigned int i = 0;
char *p1 = NULL; //p_content bak
char *p2 = NULL; //p_content bak
char *p3 = NULL; //p_unit bak
char *p4 = NULL; //p_unit bak
if (NULL==p_b)
return -1;
if (NULL==p_content || NULL==p_unit)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
if (p_b->char_mode)
{
p1 = malloc(strlen(p_content)+1);
if (NULL == p1)
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
return -1;
}
strcpy(p1, p_content);
if (DS_IGNORE_CASE==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
strupr(p1);
if (DS_IGNORE_PUNCT==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
ignore_punctuation(p1);
p3 = malloc(strlen(p_unit)+1);
if (NULL == p3)
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
free(p1);
p1 = NULL;
return -1;
}
strcpy(p3, p_unit);
if (DS_IGNORE_CASE==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
strupr(p3);
}
else
{ //id case and punct
p1 = p_content;
p3 = p_unit;
}
for (i=0; i<p_b->num; i++)
{
if (p_b->char_mode)
{
p2 = malloc(strlen(p_b->pDSS[i]->content) + 1);
if (NULL == p2)
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
free(p1);
free(p3);
p1 = NULL;
p3 = NULL;
return -1;
}
strcpy(p2, p_b->pDSS[i]->content);
if (DS_IGNORE_CASE==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
strupr(p2);
if (DS_IGNORE_PUNCT==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
ignore_punctuation(p2);
p4 = malloc(strlen(p_b->pDSS[i]->unit) + 1);
if (NULL == p4)
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
free(p1);
free(p2);
free(p3);
p1 = NULL;
p2 = NULL;
p3 = NULL;
return -1;
}
strcpy(p4, p_b->pDSS[i]->unit);
if (DS_IGNORE_CASE==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
strupr(p4);
}
else
{
p2 = p_b->pDSS[i]->content;
p4 = p_b->pDSS[i]->unit;
}
if (0==strcmp(p1, p2) && 0==strcmp(p3, p4))
{
if (NULL != pp_ds)
*pp_ds = p_b->pDSS[i];
if (p_b->char_mode)
{
free(p1);
free(p2);
free(p3);
free(p4);
p1 = NULL;
p2 = NULL;
p3 = NULL;
p4 = NULL;
}
return 0;
}
if (p_b->char_mode)
{
free(p2);
free(p4);
p2 = NULL;
p4 = NULL;
}
}
for (i=0; i<p_b->num_int; i++)
{
if (p_b->char_mode)
{
p2 = malloc(strlen(p_b->pDSS_int[i]->content) + 1);
if (NULL == p2)
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
free(p1);
free(p3);
p1 = NULL;
p3 = NULL;
return -1;
}
strcpy(p2, p_b->pDSS_int[i]->content);
if (DS_IGNORE_CASE==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
strupr(p2);
if (DS_IGNORE_PUNCT==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
ignore_punctuation(p2);
p4 = malloc(strlen(p_b->pDSS_int[i]->unit) + 1);
if (NULL == p4)
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
free(p1);
free(p2);
free(p3);
p1 = NULL;
p2 = NULL;
p3 = NULL;
return -1;
}
strcpy(p4, p_b->pDSS_int[i]->unit);
if (DS_IGNORE_CASE==p_b->char_mode || DS_IGNORE_CASE_AND_PUNCT==p_b->char_mode)
strupr(p4);
}
else
{
p2 = p_b->pDSS_int[i]->content;
p4 = p_b->pDSS_int[i]->unit;
}
if (0==strcmp(p1, p2) && 0==strcmp(p3, p4))
{
if (NULL != pp_ds)
*pp_ds = p_b->pDSS_int[i];
if (p_b->char_mode)
{
free(p1);
free(p2);
free(p3);
free(p4);
p1 = NULL;
p2 = NULL;
p3 = NULL;
p4 = NULL;
}
return 0;
}
if (p_b->char_mode)
{
free(p2);
free(p4);
p2 = NULL;
p4 = NULL;
}
}
if (p_b->char_mode)
{
free(p1);
free(p3);
p1 = NULL;
p3 = NULL;
}
sprintf(p_b->error, "Can not find the entry with same content.\n");
return 1;
}
int ds_insert_id_content_unit(PDS_BLOCK p_b, unsigned int id, char *p_content, char*p_unit, PPDS pp_ds)
{
int ret = 0;
if (NULL == p_b)
return -1;
if (NULL==p_content || NULL==p_unit)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
if (p_b->num_int >= DS_MAX_ENTRY_INT)
{
sprintf(p_b->error, "DS_MAX_ENTRY_INT is not enough.\n");
return -1;
}
if ((ret=ds_search_id(p_b, id, pp_ds)) < 0) //error happens in search module, so already has error information
return ret;
if (0 == ret)
{
sprintf(p_b->error, "Entry's id has already existed.\n");
return -1;
}
if ((ret=ds_search_content_unit(p_b, p_content, p_unit, pp_ds)) < 0) //error happens in search module, so already has error information
return ret;
if (0 == ret)
{
sprintf(p_b->error, "Entry's content or unit has already existed.\n");
return -1;
}
if (strlen(p_content) > DS_SIZE_CONTENT-1)
{
sprintf(p_b->error, "Too long content.\n");
return -1;
}
if (strlen(p_unit) > DS_SIZE_UNIT-1)
{
sprintf(p_b->error, "Too long unit.\n");
return -1;
}
p_b->pDSS_int[p_b->num_int] = malloc(sizeof(DS));
if (0 == p_b->pDSS_int[p_b->num_int])
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
return -1;
}
memset(p_b->pDSS_int[p_b->num_int], 0, sizeof(DS));
p_b->pDSS_int[p_b->num_int]->id = id;
strcpy(p_b->pDSS_int[p_b->num_int]->content, p_content);
strcpy(p_b->pDSS_int[p_b->num_int]->unit, p_unit);
if (NULL != pp_ds)
*pp_ds = p_b->pDSS_int[p_b->num_int];
p_b->num_int++;
return 0;
}
int ds_insert_auto(PDS_BLOCK p_b, char *p_content, char *p_unit, PPDS pp_ds)
{
if (NULL==p_b)
return -1;
if (NULL==p_content || NULL==p_unit)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
if (0xFFFFFFFF == p_b->id_auto)
{
sprintf(p_b->error, "ID overflows.\n");
return -1;
}
if (0 == ds_insert_id_content_unit(p_b, p_b->id_auto+1, p_content, p_unit, pp_ds))
{
p_b->id_auto++;
return 0;
}
else
return -1;
}
int ds_insert_entry(PDS_BLOCK p_b, PDS p_ds)
{
int ret = 0;
if (NULL == p_b)
return -1;
if (NULL == p_ds)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
if (p_b->num_int >= DS_MAX_ENTRY_INT)
{
sprintf(p_b->error, "DS_MAX_ENTRY_INT is not enough.\n");
return -1;
}
if ((ret=ds_search_id(p_b, p_ds->id, NULL)) < 0) //error happens in search module, so already has error information
return ret;
if (0 == ret)
{
sprintf(p_b->error, "Entry's id has already existed.\n");
return -1;
}
if ((ret=ds_search_content_unit(p_b, p_ds->content, p_ds->unit, NULL)) < 0) //error happens in search module, so already has error information
return ret;
if (0 == ret)
{
sprintf(p_b->error, "Entry's content or unit has already existed.\n");
return -1;
}
p_b->pDSS_int[p_b->num_int] = malloc(sizeof(DS));
if (0 == p_b->pDSS_int[p_b->num_int])
{
sprintf(p_b->error, "Allocate dynamic memory fail.\n");
return -1;
}
memcpy(p_b->pDSS_int[p_b->num_int], p_ds, sizeof(DS));
p_b->num_int++;
return 0;
}
int ds_delete_id(PDS_BLOCK p_b, unsigned int id)
{
unsigned int i = 0;
if (NULL == p_b)
return -1;
for (i=0; i<p_b->num; i++)
{
if (id == p_b->pDSS[i]->id)
break;
}
if (i != p_b->num)
{
free(p_b->pDSS[i]);
for (; i<p_b->num; i++)
p_b->pDSS[i] = p_b->pDSS[i+1];
p_b->num--;
return 0;
}
for (i=0; i<p_b->num_int; i++)
{
if (id == p_b->pDSS_int[i]->id)
break;
}
if (i != p_b->num_int)
{
free(p_b->pDSS_int[i]);
for (; i<p_b->num_int; i++)
p_b->pDSS_int[i] = p_b->pDSS_int[i+1];
p_b->num_int--;
return 0;
}
sprintf(p_b->error, "ID can not be found.\n");
return -1;
}
int ds_replace_id(PDS_BLOCK p_b, unsigned int id, PDS p_ds)
{
PDS p = NULL;
if (NULL == p_b)
return -1;
if (NULL == p_ds)
{
sprintf(p_b->error, "Parameter error.\n");
return -1;
}
if (0 != ds_search_id(p_b, id, &p))
return -1;
if (id!=p_ds->id && 0==ds_search_id(p_b, p_ds->id, NULL))
{
sprintf(p_b->error, "PDS->ID has already existed.\n");
return -1;
}
memcpy(p, p_ds, sizeof(DS));
return 0;
}
int ds_replace_entry(PDS_BLOCK p_b, PDS p_ds)
{
return ds_replace_id(p_b, p_ds->id, p_ds);
}
void ds_sort(PDS_BLOCK p_b)
{
if (NULL == p_b)
return;
if (NULL == p_b->pDSS)
{
sprintf(p_b->error, "Parameter error.\n");
return;
}
ds_sort_ppds(p_b->pDSS, p_b->num);
}
void ds_sort_ppds(PPDS pDSS, unsigned int num)
{
unsigned i = 0;
unsigned j = 0;
PDS p_temp = NULL;
if (NULL == pDSS)
return;
for (i=0; i<num; i++) //fast sort
{
for (j=i+1; j<num; j++)
{
if (pDSS[i]->id > pDSS[j]->id)
{
p_temp = pDSS[i];
pDSS[i] = pDSS[j];
pDSS[j] = p_temp;
}
}
}
}
int ds_merge(PDS_BLOCK p_b)
{
unsigned int i = 0;
unsigned int insert_index = 0;
unsigned int offset = 0;
if (NULL == p_b)
return -1;
offset = p_b->num_int;
if (p_b->num + p_b->num_int > DS_MAX_ENTRY)
{
sprintf(p_b->error, "More than %d entries.\n", DS_MAX_ENTRY);
return -1;
}
if (0xFFFFFFFF == p_b->id_pointer)
insert_index = p_b->num;
else
{
for (i=0; i<p_b->num; i++)
{
if (p_b->pDSS[i]->id == p_b->id_pointer)
{
insert_index = i+1;
break;
}
}
if (i == p_b->num)
{
sprintf(p_b->error, "Id pointer %d is not exist.\n", p_b->id_pointer);
return -1;
}
}
if (0 != p_b->num)
{
for (i=p_b->num-1; i>=insert_index; i--) //ending data first, avoid overwrite
{
p_b->pDSS[i+offset] = p_b->pDSS[i];
}
}
for (i=0; i<offset; i++)
{
p_b->pDSS[insert_index+i] = p_b->pDSS_int[i];
p_b->pDSS_int[i] = NULL;
}
p_b->num += p_b->num_int;
p_b->num_int = 0;
p_b->id_pointer = 0xFFFFFFFF;
return 0;
}
/*******
#define DS_IGNORE_CASE 1
#define DS_IGNORE_PUNCT 2
#define DS_IGNORE_CASE_AND_PUNCT 3
*****/
void ds_set_search_mode(PDS_BLOCK p_b, int char_mode)
{
if (NULL != p_b)
p_b->char_mode = char_mode;
}
// ======================== //
// inner function //
// ======================== //
/******************
1. search first ", except for \"
return NULL: can not be found
******************/
char* quote_position(char *pdata)
{
if (NULL == pdata)
return NULL;
do
{
pdata++;
pdata = strchr(pdata, '\"');
if (NULL == pdata)
return NULL;
}
while ('\\' == *(pdata-1));
return pdata;
}
/****************
write a entry
*****************/
void write_a_entry(FILE *fp, PDS p_ds)
{
fputs(&p_ds->pre_comment[0], fp);
fprintf(fp, "0x%02X,0x%02X,0x%02X,0x%02X,\t\"", //id + tab + quote
(unsigned char)(p_ds->id>>24),
(unsigned char)(p_ds->id>>16),
(unsigned char)(p_ds->id>>8),
(unsigned char)(p_ds->id));
fputs(p_ds->content, fp);
fputs("\"\t\"", fp);
fputs(p_ds->unit, fp);
fputs("\"", fp);
fputs(p_ds->post_comment, fp);
if (NULL == strchr(p_ds->post_comment, '\n'))
fputs("\n", fp);
}
/****************
ignoring punctuation
*****************/
char punctuations[20] = {' ', '\t', ',', '.', '_', '?', '!', '(', ')', '\0'};
void ignore_punctuation(char *str)
{
char *copy = str;
int i = 0;
while (*copy != '\0')
{
for (i=0; punctuations[i]!='\0'; i++)
{
if (*copy == punctuations[i])
break;
}
if ('\0' != punctuations[i])
{
copy++;
continue;
}
if ('\\'==*copy && ('t'==*(copy+1) || 'n'==*(copy+1) || 'T'==*(copy+1) || 'N'==*(copy+1)) )
{
copy += 2;
continue;
}
*str++ = *copy++;
}
*str++ = '\0';
}
- DS_xx工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- 工具
- freemarker学习1
- 在VC安装后不能使用dumpbin命令解决办法
- 如果交换空间不足,则按照如下步骤扩大交换空间
- 目录
- sqlplus 中复制粘贴问题
- DS_xx工具
- 软件设计方案(数据库设计原则)
- mongodb java 查询
- 实现C语言的拷贝函数且将复制后的字符串逆序,不能使用库函数,不能定义其他的变量。
- Properties
- 腾讯/新浪/搜狐IP地址API
- ANTI-DEDE的几个方法
- 存储过程实现Grid View分页
- 运用Button删除GridView中CheckBox选中行