Import Data by SDR - nmsoccer/sdr GitHub Wiki
导入数据将使用脚本文件将sdr dump出的xml文件转换为对应的二进制文件,然后其他程序可以使用sdr_unpack接口读取文件内容并解包成为内存数据.
tools/dump2bin.py
该工具将dump生成的xml文件转换成对应的二进制binary文件
/dump2bin.py -h
#########################################################
This script is only for dump xml generated by sdr lib:'sdr_dump_struct'.
it parses xml to binary file,which could be unpacked by sdr lib:'sdr_unpack'
It only parse label like this:
<entry name="xx" type="xx" value="xx" size="xx" />
<version name="dump_version" value="xx" />
#########################################################
-i <input xml file>
-o [output bin file] if 'output bin file' is not specified , default print to 'inputfile'.dump.bin
-h show help
-v print debug info
usage:./dump2bin.py -i <input xml file> -o [output bin file] [-v]
- 生成dump文件
我们使用导出数据例子里生成的xml文件.参考:https://github.com/nmsoccer/sdr/wiki/Dump-Data-by-SDR
现在假设已经导出了数据,并获得了dump_out.xml 内容如下:
<?xml version="1.0" encoding="utf8" ?>
<!-- Created by sdr on 2019-01-02 17:13:44 -->
<!-- @https://github.com/nmsoccer/sdr -->
<struct name="" type="user_info">
<entry name="sex" type="char" value="1" />
<entry name="name_len" type="char" value="14" />
<entry name="user_name" type="char[]" size="14" value="'c''s''_''f''*''*''k''_''s''u''o''m''e''i'" />
<entry name="age" type="short" value="32" />
<entry name="flags" type="unsigned char[]" size="10" value="'0xB1''0x3''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0'" />
<entry name="height" type="float" value="1.730000" />
<struct name="skill" type="skill_list">
<entry name="skill_count" type="char" value="2" />
<struct name="info_list" type="skill_info">
<entry name="type" type="char" value="1" />
<union name="data" type="skill_data">
<entry name="qskill" type="char" value="111" />
</union>
</struct>
<struct name="info_list" type="skill_info">
<entry name="type" type="char" value="3" />
<union name="data" type="skill_data">
<entry name="eskill" type="unsigned char[]" size="12" value="'w''e''a''r''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0'" />
</union>
</struct>
</struct>
<entry name="money" type="long long" value="1289" />
<entry name="gold" type="unsigned long" value="5000" />
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4000" />
<entry name="count" type="int" value="0" />
<entry name="instid" type="long long" value="10000" />
<entry name="grid" type="char" value="0" />
</struct>
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4001" />
<entry name="count" type="int" value="2" />
<entry name="instid" type="long long" value="10001" />
<entry name="grid" type="char" value="1" />
</struct>
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4002" />
<entry name="count" type="int" value="4" />
<entry name="instid" type="long long" value="10002" />
<entry name="grid" type="char" value="2" />
</struct>
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4003" />
<entry name="count" type="int" value="6" />
<entry name="instid" type="long long" value="10003" />
<entry name="grid" type="char" value="3" />
</struct>
<entry name="desc" type="char[]" size="32" value="'h''e''l''l''o'' ''w''o''r''l''d''!''0x0''0x0''0xE6''0x97''0xA5''0xE4''0xBA''0x86''0xE7''0x8B''0x97''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0'" />
<entry name="lat" type="double" value="38.657770" />
<entry name="lng" type="double" value="104.082960" />
</struct>
<version name="dump_max" value="3" />
- 使用dump2bin.py 将xml文件转化为bin文件
./dump2bin.py -i dump_out.xml
output is set to:dump_out.xml.dump.bin
[2019-01-02 17:14:01] Ready to parse dump xml to binary file
pares 'dump_out.xml' to 'dump_out.xml.dump.bin' success! bin_version:3 bin_size:180
正常执行后将生成对应的bin文件:
stat dump_out.xml.dump.bin
File: 'dump_out.xml.dump.bin'
Size: 188 Blocks: 8 IO Block: 4096 regular file
Device: 804h/2052d Inode: 2173646957 Links: 1
Access: (0644/-rw-r--r--) Uid: (30020/ nmsoccer) Gid: (30020/ nmsoccer)
Access: 2018-12-31 20:59:53.572654179 +0800
Modify: 2019-01-02 17:14:01.836077418 +0800
Change: 2019-01-02 17:14:01.836077418 +0800
Birth: -
- 新建一个C文件,用于读取dump_out.xml.dump.bin内容,将其解包,并将解包的结构dump到另外一份新xml文件作为对比.以下内容摘自import.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sdr/sdr.h>
#include "dump.h"
#define MAX_BUFF_LEN (10*1024)
#define SDR_PROTO_FILE "./dump.sdr"
#define BIN_FILE "./dump_out.xml.dump.bin"
#define OUT_XML "./import_out.xml"
...
int main(int argc , char **argv)
{
sdr_data_res_t *pres;
char buff[MAX_BUFF_LEN] = {0};
user_info_t dst_user;
int len = 0;
int version = -1;
int ret = -1;
int i = 0;
FILE *fp_bin = NULL;
FILE *fp = fopen(OUT_XML , "w+");
if(!fp)
{
printf("open %s failed!\n" , OUT_XML);
return -1;
}
fp_bin = fopen(BIN_FILE , "r");
if(!fp_bin)
{
printf("open %s failed!\n" , BIN_FILE);
return -1;
}
//init
memset(&dst_user , 0 , sizeof(dst_user));
//sdr
pres = sdr_load_bin(SDR_PROTO_FILE , NULL);
if(!pres)
{
printf("load %s failed!\n" , SDR_PROTO_FILE);
return -1;
}
//read bin file
ret = fread(buff , 1 , MAX_BUFF_LEN , fp_bin);
if(ret < 0)
{
printf("read %s failed!\n" , BIN_FILE);
return -1;
}
printf("read %s success! bytes:%d\n" , BIN_FILE , ret);
//unpack
len = sdr_unpack(pres , (char *)&dst_user , buff , "user_info" , NULL);
if(len < 0)
{
printf("sdr_unpack failed!\n");
return -1;
}
printf("sdr_unpack len:%d\n" , len);
print_user_info(&dst_user);
// dump
ret = sdr_dump_struct(pres , "user_info" , (char *)&dst_user , fp);
printf("sdr_dump_struct ret:%d\n" , ret);
//free
sdr_free_bin(pres);
return 0;
}
gcc -g import.c -lsdr -o import 生成可执行文件并执行:
./import
max node:61, map_count:39 , entry_size:61 entry_count:13
read ./dump_out.xml.dump.bin success! bytes:188
sdr_unpack len:599
-------------------------------
sex:1 name:cs_f**k_suomei age:32 money:1289 gold:5000 height:1.730000 , lat:38.657770 , lng:104.082960
flags:
'177''3''0''0''0''0''0''0''0''0'
...
sdr_dump_struct ret:0
- 将在当前目录下生成import_out.xml 内容如下:
<?xml version="1.0" encoding="utf8" ?>
<!-- Created by sdr on 2019-01-02 17:14:16 -->
<!-- @https://github.com/nmsoccer/sdr -->
<struct name="" type="user_info">
<entry name="sex" type="char" value="1" />
<entry name="name_len" type="char" value="14" />
<entry name="user_name" type="char[]" size="14" value="'c''s''_''f''*''*''k''_''s''u''o''m''e''i'" />
<entry name="age" type="short" value="32" />
<entry name="flags" type="unsigned char[]" size="10" value="'0xB1''0x3''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0'" />
<entry name="height" type="float" value="1.730000" />
<struct name="skill" type="skill_list">
<entry name="skill_count" type="char" value="2" />
<struct name="info_list" type="skill_info">
<entry name="type" type="char" value="1" />
<union name="data" type="skill_data">
<entry name="qskill" type="char" value="111" />
</union>
</struct>
<struct name="info_list" type="skill_info">
<entry name="type" type="char" value="3" />
<union name="data" type="skill_data">
<entry name="eskill" type="unsigned char[]" size="12" value="'w''e''a''r''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0'" />
</union>
</struct>
</struct>
<entry name="money" type="long long" value="1289" />
<entry name="gold" type="unsigned long" value="5000" />
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4000" />
<entry name="count" type="int" value="0" />
<entry name="instid" type="long long" value="10000" />
<entry name="grid" type="char" value="0" />
</struct>
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4001" />
<entry name="count" type="int" value="2" />
<entry name="instid" type="long long" value="10001" />
<entry name="grid" type="char" value="1" />
</struct>
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4002" />
<entry name="count" type="int" value="4" />
<entry name="instid" type="long long" value="10002" />
<entry name="grid" type="char" value="2" />
</struct>
<struct name="item_list" type="item">
<entry name="resid" type="int" value="4003" />
<entry name="count" type="int" value="6" />
<entry name="instid" type="long long" value="10003" />
<entry name="grid" type="char" value="3" />
</struct>
<entry name="desc" type="char[]" size="32" value="'h''e''l''l''o'' ''w''o''r''l''d''!''0x0''0x0''0xE6''0x97''0xA5''0xE4''0xBA''0x86''0xE7''0x8B''0x97''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0''0x0'" />
<entry name="lat" type="double" value="38.657770" />
<entry name="lng" type="double" value="104.082960" />
</struct>
<version name="dump_max" value="3" />
导入成功。