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]

EXAMPLE

  1. 生成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" />

  1. 使用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: -
  1. 新建一个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
  1. 将在当前目录下生成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" />

导入成功。

⚠️ **GitHub.com Fallback** ⚠️