简介
- MiniXML(mxml)
http://michaelrsweet.github.io/mxml/ - 下载
https://github.com/michaelrsweet/mxml/releases - 移植文件
https://code.aliyun.com/rgw/mxml-fatfs/tags - API文档
http://michaelrsweet.github.io/mxml/index.html - 中文文档
http://blog.csdn.net/duanlove/article/details/6919922?locationNum=6&fps=1
移植说明
移植版本为mxml-2.10,由于FatFS不兼容posix接口,因此移植主要针对不兼容的接口移植。工程中需要的文件不包括testmxml.c和mxmldoc.c。
mxml-file-fatfs.c
- 复制源文件备份,修改文件名为mxml-file-fatfs.c
- 增加头文件
#include "ff.h"
#include "ff_ex.h"
- 删除
#ifndef WIN32
# include <unistd.h>
#endif /* !WIN32 */
- 增加宏定义,也可以直接修改文件中的函数
#define FILE FIL
#define getc f_getc
#define putc f_putc
其中f_getc在FatFS中是没有的,可以自己实现。
/**
* @file ff_ex.c
* @brief fatfs extensional function.
* @author rgw
* @version 1.0
* @date 2016-12-06
*/
#include "ff.h"
int f_getc (
FIL *fp /* Pointer to the file object */
)
{
BYTE c;
UINT rc;
f_read(fp, &c, 1, &rc);
if (rc != 1)
{
return EOF;
}
return c;
}
- 删除所有fd操作
5.1 删除typedef
typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/
{
int fd; /* File descriptor */
unsigned char *current, /* Current position in buffer */
*end, /* End of buffer */
buffer[8192]; /* Character buffer */
} _mxml_fdbuf_t;
5.2 删除函数声明与函数体
static int mxml_fd_getc(void *p, int *encoding);
static int mxml_fd_putc(int ch, void *p);
static int mxml_fd_read(_mxml_fdbuf_t *buf);
static int mxml_fd_write(_mxml_fdbuf_t *buf);
mxmlLoadFd
mxmlSaveFd
mxmlSAXLoadFd
增加mxml-cb.c
#include "config.h"
#include "mxml.h"
extern int event_counts[6];
/*
* 'sax_cb()' - Process nodes via SAX.
*/
void
sax_cb(mxml_node_t *node, /* I - Current node */
mxml_sax_event_t event, /* I - SAX event */
void *data) /* I - SAX user data */
{
static const char * const events[] = /* Events */
{
"MXML_SAX_CDATA", /* CDATA node */
"MXML_SAX_COMMENT", /* Comment node */
"MXML_SAX_DATA", /* Data node */
"MXML_SAX_DIRECTIVE", /* Processing directive node */
"MXML_SAX_ELEMENT_CLOSE", /* Element closed */
"MXML_SAX_ELEMENT_OPEN" /* Element opened */
};
/*
* This SAX callback just counts the different events.
*/
if (!node)
fprintf(stderr, "ERROR: SAX callback for event %s has NULL node.\n", events[event]);
event_counts[event] ++;
}
/*
* 'type_cb()' - XML data type callback for mxmlLoadFile()...
*/
mxml_type_t /* O - Data type */
type_cb(mxml_node_t *node) /* I - Element node */
{
const char *type; /* Type string */
/*
* You can lookup attributes and/or use the element name, hierarchy, etc...
*/
if ((type = mxmlElementGetAttr(node, "type")) == NULL)
type = node->value.element.name;
if (!strcmp(type, "integer"))
return (MXML_INTEGER);
else if (!strcmp(type, "opaque") || !strcmp(type, "pre"))
return (MXML_OPAQUE);
else if (!strcmp(type, "real"))
return (MXML_REAL);
else
return (MXML_TEXT);
}
/*
* 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert
* newlines and tabs...
*/
const char * /* O - Whitespace string or NULL */
whitespace_cb(mxml_node_t *node, /* I - Element node */
int where) /* I - Open or close tag? */
{
mxml_node_t *parent; /* Parent node */
int level; /* Indentation level */
const char *name; /* Name of element */
static const char *tabs = "\t\t\t\t\t\t\t\t";
/* Tabs for indentation */
/*
* We can conditionally break to a new line before or after any element.
* These are just common HTML elements...
*/
name = node->value.element.name;
if (!strcmp(name, "html") || !strcmp(name, "head") || !strcmp(name, "body") ||
!strcmp(name, "pre") || !strcmp(name, "p") ||
!strcmp(name, "h1") || !strcmp(name, "h2") || !strcmp(name, "h3") ||
!strcmp(name, "h4") || !strcmp(name, "h5") || !strcmp(name, "h6"))
{
/*
* Newlines before open and after close...
*/
if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE)
return ("\n");
}
else if (!strcmp(name, "dl") || !strcmp(name, "ol") || !strcmp(name, "ul"))
{
/*
* Put a newline before and after list elements...
*/
return ("\n");
}
else if (!strcmp(name, "dd") || !strcmp(name, "dt") || !strcmp(name, "li"))
{
/*
* Put a tab before <li>'s, <dd>'s, and <dt>'s, and a newline after them...
*/
if (where == MXML_WS_BEFORE_OPEN)
return ("\t");
else if (where == MXML_WS_AFTER_CLOSE)
return ("\n");
}
else if (!strncmp(name, "?xml", 4))
{
if (where == MXML_WS_AFTER_OPEN)
return ("\n");
else
return (NULL);
}
else if (where == MXML_WS_BEFORE_OPEN ||
((!strcmp(name, "choice") || !strcmp(name, "option")) &&
where == MXML_WS_BEFORE_CLOSE))
{
for (level = -1, parent = node->parent;
parent;
level ++, parent = parent->parent);
if (level > 8)
level = 8;
else if (level < 0)
level = 0;
return (tabs + 8 - level);
}
else if (where == MXML_WS_AFTER_CLOSE ||
((!strcmp(name, "group") || !strcmp(name, "option") ||
!strcmp(name, "choice")) &&
where == MXML_WS_AFTER_OPEN))
return ("\n");
else if (where == MXML_WS_AFTER_OPEN && !node->child)
return ("\n");
/*
* Return NULL for no added whitespace...
*/
return (NULL);
}
/*
* End of "$Id: testmxml.c 466 2016-06-13 00:27:11Z msweet $".
*/
mxml.h
- 删除 mxml.h中关于Fd描述的声明
extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd,
mxml_type_t (*cb)(mxml_node_t *));
extern int mxmlSaveFd(mxml_node_t *node, int fd,
mxml_save_cb_t cb);
extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd,
mxml_type_t (*cb)(mxml_node_t *),
mxml_sax_cb_t sax, void *sax_data);
- 将所有FILE类型改为FIL
- 增加回调函数声明
void sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *data);
mxml_type_t type_cb(mxml_node_t *node);
const char *whitespace_cb(mxml_node_t *node, int where);
至此,移植完毕。
网友评论