Merge branch 'master' of http://git.komect.net/ISG/secogateway
This commit is contained in:
commit
c22ad8f5d9
|
@ -0,0 +1,3 @@
|
|||
[submodule "libs/src/cJSON"]
|
||||
path = libs/src/cJSON
|
||||
url = https://github.com/DaveGamble/cJSON.git
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* This file is part of the struct2json Library.
|
||||
*
|
||||
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Function: It is an head file for this library. You can see all be called functions.
|
||||
* Created on: 2015-10-14
|
||||
*/
|
||||
|
||||
#ifndef __S2J_H__
|
||||
#define __S2J_H__
|
||||
|
||||
#include <cjson/cJSON.h>
|
||||
#include <string.h>
|
||||
#include "s2jdef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* struct2json software version number */
|
||||
#define S2J_SW_VERSION "1.0.3"
|
||||
|
||||
/* Create JSON object */
|
||||
#define s2j_create_json_obj(json_obj) \
|
||||
S2J_CREATE_JSON_OBJECT(json_obj)
|
||||
|
||||
/* Delete JSON object */
|
||||
#define s2j_delete_json_obj(json_obj) \
|
||||
S2J_DELETE_JSON_OBJECT(json_obj)
|
||||
|
||||
/* Set basic type element for JSON object */
|
||||
#define s2j_json_set_basic_element(to_json, from_struct, type, element) \
|
||||
S2J_JSON_SET_BASIC_ELEMENT(to_json, from_struct, type, element)
|
||||
|
||||
/* Set array type element for JSON object */
|
||||
#define s2j_json_set_array_element(to_json, from_struct, type, element, size) \
|
||||
S2J_JSON_SET_ARRAY_ELEMENT(to_json, from_struct, type, element, size)
|
||||
|
||||
/* Set child structure type element for JSON object */
|
||||
#define s2j_json_set_struct_element(child_json, to_json, child_struct, from_struct, type, element) \
|
||||
S2J_JSON_SET_STRUCT_ELEMENT(child_json, to_json, child_struct, from_struct, type, element)
|
||||
|
||||
/* Create structure object */
|
||||
#define s2j_create_struct_obj(struct_obj, type) \
|
||||
S2J_CREATE_STRUCT_OBJECT(struct_obj, type)
|
||||
|
||||
/* Delete structure object */
|
||||
#define s2j_delete_struct_obj(struct_obj) \
|
||||
S2J_DELETE_STRUCT_OBJECT(struct_obj)
|
||||
|
||||
/* Get basic type element for structure object */
|
||||
#define s2j_struct_get_basic_element(to_struct, from_json, type, element) \
|
||||
S2J_STRUCT_GET_BASIC_ELEMENT(to_struct, from_json, type, element)
|
||||
|
||||
/* Get array type element for structure object */
|
||||
#define s2j_struct_get_array_element(to_struct, from_json, type, element) \
|
||||
S2J_STRUCT_GET_ARRAY_ELEMENT(to_struct, from_json, type, element)
|
||||
|
||||
/* Get child structure type element for structure object */
|
||||
#define s2j_struct_get_struct_element(child_struct, to_struct, child_json, from_json, type, element) \
|
||||
S2J_STRUCT_GET_STRUCT_ELEMENT(child_struct, to_struct, child_json, from_json, type, element)
|
||||
|
||||
/* s2j.c */
|
||||
extern S2jHook s2jHook;
|
||||
void s2j_init(S2jHook *hook);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __S2J_H__ */
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* This file is part of the struct2json Library.
|
||||
*
|
||||
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Function: It is an head file for this library.
|
||||
* Created on: 2015-10-14
|
||||
*/
|
||||
|
||||
#ifndef __S2JDEF_H__
|
||||
#define __S2JDEF_H__
|
||||
|
||||
#include <cjson/cJSON.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} S2jHook, *S2jHook_t;
|
||||
|
||||
#define S2J_STRUCT_GET_int_ELEMENT(to_struct, from_json, _element) \
|
||||
json_temp = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (json_temp) (to_struct)->_element = json_temp->valueint;
|
||||
|
||||
#define S2J_STRUCT_GET_string_ELEMENT(to_struct, from_json, _element) \
|
||||
json_temp = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (json_temp) strcpy((to_struct)->_element, json_temp->valuestring);
|
||||
|
||||
#define S2J_STRUCT_GET_double_ELEMENT(to_struct, from_json, _element) \
|
||||
json_temp = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (json_temp) (to_struct)->_element = json_temp->valuedouble;
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_int_ELEMENT(to_struct, from_json, _element, index) \
|
||||
(to_struct)->_element[index] = from_json->valueint;
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_string_ELEMENT(to_struct, from_json, _element, index) \
|
||||
strcpy((to_struct)->_element[index], from_json->valuestring);
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_double_ELEMENT(to_struct, from_json, _element, index) \
|
||||
(to_struct)->_element[index] = from_json->valuedouble;
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_ELEMENT(to_struct, from_json, type, _element, index) \
|
||||
S2J_STRUCT_ARRAY_GET_##type##_ELEMENT(to_struct, from_json, _element, index)
|
||||
|
||||
#define S2J_JSON_SET_int_ELEMENT(to_json, from_struct, _element) \
|
||||
cJSON_AddNumberToObject(to_json, #_element, (from_struct)->_element);
|
||||
|
||||
#define S2J_JSON_SET_double_ELEMENT(to_json, from_struct, _element) \
|
||||
cJSON_AddNumberToObject(to_json, #_element, (from_struct)->_element);
|
||||
|
||||
#define S2J_JSON_SET_string_ELEMENT(to_json, from_struct, _element) \
|
||||
cJSON_AddStringToObject(to_json, #_element, (from_struct)->_element);
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_int_ELEMENT(to_json, from_struct, _element, index) \
|
||||
cJSON_AddItemToArray(to_json, cJSON_CreateNumber((from_struct)->_element[index]));
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_double_ELEMENT(to_json, from_struct, _element, index) \
|
||||
cJSON_AddItemToArray(to_json, cJSON_CreateNumber((from_struct)->_element[index]));
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_string_ELEMENT(to_json, from_struct, _element, index) \
|
||||
cJSON_AddItemToArray(to_json, cJSON_CreateString((from_struct)->_element[index]));
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_ELEMENT(to_json, from_struct, type, _element, index) \
|
||||
S2J_JSON_ARRAY_SET_##type##_ELEMENT(to_json, from_struct, _element, index)
|
||||
|
||||
|
||||
#define S2J_CREATE_JSON_OBJECT(json_obj) \
|
||||
cJSON *json_obj = cJSON_CreateObject();
|
||||
|
||||
#define S2J_DELETE_JSON_OBJECT(json_obj) \
|
||||
cJSON_Delete(json_obj);
|
||||
|
||||
#define S2J_JSON_SET_BASIC_ELEMENT(to_json, from_struct, type, _element) \
|
||||
S2J_JSON_SET_##type##_ELEMENT(to_json, from_struct, _element)
|
||||
|
||||
#define S2J_JSON_SET_ARRAY_ELEMENT(to_json, from_struct, type, _element, size) \
|
||||
{ \
|
||||
cJSON *array; \
|
||||
size_t index = 0; \
|
||||
array = cJSON_CreateArray(); \
|
||||
if (array) { \
|
||||
while (index < size) { \
|
||||
S2J_JSON_ARRAY_SET_ELEMENT(array, from_struct, type, _element, index++); \
|
||||
} \
|
||||
cJSON_AddItemToObject(to_json, #_element, array); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define S2J_JSON_SET_STRUCT_ELEMENT(child_json, to_json, child_struct, from_struct, type, _element) \
|
||||
type *child_struct = &((from_struct)->_element); \
|
||||
cJSON *child_json = cJSON_CreateObject(); \
|
||||
if (child_json) cJSON_AddItemToObject(to_json, #_element, child_json);
|
||||
|
||||
#define S2J_CREATE_STRUCT_OBJECT(struct_obj, type) \
|
||||
cJSON *json_temp; \
|
||||
type *struct_obj = s2jHook.malloc_fn(sizeof(type)); \
|
||||
if (struct_obj) memset(struct_obj, 0, sizeof(type));
|
||||
|
||||
#define S2J_DELETE_STRUCT_OBJECT(struct_obj) \
|
||||
s2jHook.free_fn(struct_obj);
|
||||
|
||||
#define S2J_STRUCT_GET_BASIC_ELEMENT(to_struct, from_json, type, _element) \
|
||||
S2J_STRUCT_GET_##type##_ELEMENT(to_struct, from_json, _element)
|
||||
|
||||
#define S2J_STRUCT_GET_ARRAY_ELEMENT(to_struct, from_json, type, _element) \
|
||||
{ \
|
||||
cJSON *array, *array_element; \
|
||||
size_t index = 0, size = 0; \
|
||||
array = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (array) { \
|
||||
size = cJSON_GetArraySize(array); \
|
||||
while (index < size) { \
|
||||
array_element = cJSON_GetArrayItem(array, index); \
|
||||
if (array_element) S2J_STRUCT_ARRAY_GET_ELEMENT(to_struct, array_element, type, _element, index++); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define S2J_STRUCT_GET_STRUCT_ELEMENT(child_struct, to_struct, child_json, from_json, type, _element) \
|
||||
type *child_struct = &((to_struct)->_element); \
|
||||
cJSON *child_json = cJSON_GetObjectItem(from_json, #_element);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __S2JDEF_H__ */
|
|
@ -0,0 +1,78 @@
|
|||
# target name, the target name must have the same name of c source file
|
||||
TARGET_NAME=pdeliv
|
||||
|
||||
# target
|
||||
# for linux module driver: KO
|
||||
# for application: EXE
|
||||
# for dynamic library: DLL
|
||||
TARGET_TYPE = EXE
|
||||
|
||||
# target object
|
||||
# for application: APP
|
||||
# for device driver: DRV
|
||||
TARGET_OBJ = APP
|
||||
|
||||
# custom install dir
|
||||
TARGET_BOX =
|
||||
|
||||
#debug mode or release mode
|
||||
DEBUG = TRUE
|
||||
|
||||
PLAT_LINUX ?= TRUE
|
||||
PLAT_ARM64 ?= TRUE
|
||||
|
||||
VPATH = ../user/pdeliv_u
|
||||
|
||||
# source code
|
||||
|
||||
# set the source file, don't used .o because of ...
|
||||
|
||||
COMMON_SRCS = pdelivery_main.c
|
||||
|
||||
# MRS Board Source Files
|
||||
PLAT_LINUX_SRCS = $(COMMON_SRCS)
|
||||
PLAT_ARM64_SRCS = $(COMMON_SRCS)
|
||||
|
||||
# gcc CFLAGS
|
||||
PLAT_ARM64_CFLAGS := -I../../Common -I../user/netlink_uapi
|
||||
PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS)
|
||||
|
||||
|
||||
PLAT_ARM64_LDFLAGS :=
|
||||
PLAT_LINUX_LDFLAGS := $(PLAT_ARM64_LDFLAGS)
|
||||
|
||||
ARM64_LIBS := ./pdeliv-rcvtest-arm64.so
|
||||
LINUX_LIBS := ./pdeliv-rcvtest-linux.so
|
||||
|
||||
|
||||
|
||||
ifeq ($(PLAT_ARM64), TRUE)
|
||||
DEPEND_LIB += ./debug/libnetlinku-arm64.so
|
||||
USER_CLEAN_ITEMS += ./libnetlinku-arm64.so
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT_LINUX), TRUE)
|
||||
DEPEND_LIB += ./debug/libnetlinku-linux.so
|
||||
USER_CLEAN_ITEMS += ./libnetlinku-linux.so
|
||||
endif
|
||||
|
||||
|
||||
# this line must be at below of thus, because of...
|
||||
include ../../Common/common.Makefile
|
||||
|
||||
ifneq ($(MAKECMDGOALS), clean)
|
||||
ifneq ($(MAKECMDGOALS), cleanall)
|
||||
ifneq ($(notdir $(DEPEND_LIB)), $(wildcard $(DEPEND_LIB)))
|
||||
$(shell $(CP) $(DEPEND_LIB) ./)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS), )
|
||||
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
|
||||
else
|
||||
ifeq ($(MAKECMDGOALS), all)
|
||||
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
|
||||
endif
|
||||
endif
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# target name, the target name must have the same name of c source file
|
||||
TARGET_NAME=pdeliv
|
||||
|
||||
# target
|
||||
# for linux module driver: KO
|
||||
# for application: EXE
|
||||
# for dynamic library: DLL
|
||||
TARGET_TYPE = EXE
|
||||
|
||||
# target object
|
||||
# for application: APP
|
||||
# for device driver: DRV
|
||||
TARGET_OBJ = APP
|
||||
|
||||
# custom install dir
|
||||
TARGET_BOX =
|
||||
|
||||
#debug mode or release mode
|
||||
DEBUG = TRUE
|
||||
|
||||
PLAT_LINUX ?= TRUE
|
||||
PLAT_ARM64 ?= TRUE
|
||||
|
||||
VPATH = ../user/pdeliv_u
|
||||
|
||||
# source code
|
||||
|
||||
# set the source file, don't used .o because of ...
|
||||
|
||||
COMMON_SRCS = pdelivery_main.c
|
||||
|
||||
# MRS Board Source Files
|
||||
PLAT_LINUX_SRCS = $(COMMON_SRCS)
|
||||
PLAT_ARM64_SRCS = $(COMMON_SRCS)
|
||||
|
||||
# gcc CFLAGS
|
||||
PLAT_ARM64_CFLAGS := -I../../Common -I../user/netlink_uapi
|
||||
PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS)
|
||||
|
||||
|
||||
PLAT_ARM64_LDFLAGS :=
|
||||
PLAT_LINUX_LDFLAGS := $(PLAT_ARM64_LDFLAGS)
|
||||
|
||||
ARM64_LIBS := ./pdeliv-rcvtest-arm64.so
|
||||
LINUX_LIBS := ./pdeliv-rcvtest-linux.so
|
||||
|
||||
|
||||
|
||||
ifeq ($(PLAT_ARM64), TRUE)
|
||||
DEPEND_LIB += ./debug/libnetlinku-arm64.so
|
||||
USER_CLEAN_ITEMS += ./libnetlinku-arm64.so
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT_LINUX), TRUE)
|
||||
DEPEND_LIB += ./debug/libnetlinku-linux.so
|
||||
USER_CLEAN_ITEMS += ./libnetlinku-linux.so
|
||||
endif
|
||||
|
||||
|
||||
# this line must be at below of thus, because of...
|
||||
include ../../Common/common.Makefile
|
||||
|
||||
ifneq ($(MAKECMDGOALS), clean)
|
||||
ifneq ($(MAKECMDGOALS), cleanall)
|
||||
ifneq ($(notdir $(DEPEND_LIB)), $(wildcard $(DEPEND_LIB)))
|
||||
$(shell $(CP) $(DEPEND_LIB) ./)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS), )
|
||||
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
|
||||
else
|
||||
ifeq ($(MAKECMDGOALS), all)
|
||||
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
|
||||
endif
|
||||
endif
|
||||
|
|
@ -253,7 +253,7 @@ int nf_nlmsg_multicast(struct netlinkk_cfg *g_nlcfg, struct sk_buff *skb)
|
|||
if (ret < 0)
|
||||
{
|
||||
//g_nlcfg->dfs.send_fail ++;
|
||||
printk(KERN_ERR "Error while sending pkt to user, ret id: %d\n", ret);
|
||||
//printk(KERN_ERR "Error while sending pkt to user, ret id: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -205,12 +205,14 @@ unsigned int pdelivery_hook_func(void *priv,
|
|||
int payload_len; // with padding, but ok for echo
|
||||
struct iphdr *iph;
|
||||
int ret = -1;
|
||||
|
||||
|
||||
#if 0
|
||||
iph = ip_hdr(skb);
|
||||
printk(KERN_INFO "pdelivery_hook_func:pktlen=%d,mac_header = %d IP:",skb->len,skb->mac_len);
|
||||
printk_ipaddress(iph->saddr);
|
||||
printk(KERN_INFO "-->");
|
||||
printk_ipaddress(iph->daddr);
|
||||
#endif
|
||||
|
||||
payload = skb_mac_header(skb);
|
||||
payload_len = skb->len + skb->mac_len;/**/
|
||||
|
@ -235,7 +237,7 @@ unsigned int pdelivery_hook_func(void *priv,
|
|||
/*int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data);*/
|
||||
/********************************************************************************/
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\r\n",
|
||||
*((char*)out_payload),*((char*)out_payload+1),
|
||||
*((char*)out_payload+2),*((char*)out_payload+3),
|
||||
|
@ -249,14 +251,14 @@ unsigned int pdelivery_hook_func(void *priv,
|
|||
goto failure;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "pdelivery_hook_func() end.\n");
|
||||
//printk(KERN_INFO "pdelivery_hook_func() end.\n");
|
||||
g_nlcfg.dfs.send_succ ++;
|
||||
g_nlcfg.msg_processer[NLMSG_RECV_RAW_PKT].dfs.send_succ++;
|
||||
|
||||
return NF_ACCEPT;/*must return a value*/
|
||||
|
||||
failure:
|
||||
printk(KERN_INFO " failed in pdelivery_hook_func!\n");
|
||||
//printk(KERN_INFO " failed in pdelivery_hook_func!\n");
|
||||
g_nlcfg.dfs.send_fail ++;
|
||||
g_nlcfg.msg_processer[NLMSG_RECV_RAW_PKT].dfs.send_fail++;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ int set_user_policy()
|
|||
commnl_addattr_l(&req.n, sizeof(req), POLICYCONFA_SRCIP, debug, debug_len);
|
||||
|
||||
/*发送组装好的netlink消息*/
|
||||
if (pdeliv_talk(1, &req.n, NULL) < 0)
|
||||
if (pdeliv_talk(0, &req.n, NULL) < 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ int main( int argc, char **argv)
|
|||
printf("cfgchannel main begin:\r\n");
|
||||
|
||||
/*创建通道*/
|
||||
ret = pdelivnl_open();
|
||||
ret = pdelivnl_open(0);
|
||||
if(ret < 0)
|
||||
{
|
||||
printf("pdelivnl_open fail,exit.\r\n");
|
||||
|
@ -79,7 +79,7 @@ int main( int argc, char **argv)
|
|||
}
|
||||
|
||||
/*关闭netlink通道*/
|
||||
pdelivnl_close();
|
||||
pdelivnl_close(0);
|
||||
|
||||
printf("cfgchannel main exit!\r\n");
|
||||
return 0;
|
||||
|
|
|
@ -293,14 +293,15 @@ void commcfgnl_close()
|
|||
return;
|
||||
}
|
||||
|
||||
int pdelivnl_open()
|
||||
int pdelivnl_open(unsigned int group)
|
||||
{
|
||||
return commnl_open_byproto(PDNLGRP_ALLRAW, NETLINK_PDELIVERY);
|
||||
return commnl_open_byproto(group, NETLINK_PDELIVERY);
|
||||
}
|
||||
|
||||
void pdelivnl_close()
|
||||
|
||||
void pdelivnl_close(unsigned int group)
|
||||
{
|
||||
commnl_close(PDNLGRP_ALLRAW,NETLINK_PDELIVERY);
|
||||
commnl_close(group,NETLINK_PDELIVERY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -769,7 +770,7 @@ int pdeliv_main(pdelivnl_listen_filter_t process_pkt)
|
|||
printf("pdeliv_main begin:\r\n");
|
||||
|
||||
/*创建通道*/
|
||||
ret = pdelivnl_open();
|
||||
ret = pdelivnl_open(PDNLGRP_ALLRAW);
|
||||
if(ret < 0)
|
||||
{
|
||||
printf("pdelivnl_open fail,exit.\r\n");
|
||||
|
@ -781,7 +782,7 @@ int pdeliv_main(pdelivnl_listen_filter_t process_pkt)
|
|||
|
||||
|
||||
/*关闭netlink通道*/
|
||||
pdelivnl_close();
|
||||
pdelivnl_close(PDNLGRP_ALLRAW);
|
||||
|
||||
printf("pdeliv_main exit!\r\n");
|
||||
return 0;
|
||||
|
|
|
@ -114,8 +114,8 @@ void commcfgnl_close();
|
|||
/*输出参数: struct upmnl_handle * upmh ,存放创建的通道相关信息。*/
|
||||
/*返回值:0通道创建成果;< 0,失败 */
|
||||
/****************************************************************/
|
||||
int pdelivnl_open();
|
||||
void pdelivnl_close();
|
||||
int pdelivnl_open(unsigned int group);
|
||||
void pdelivnl_close(unsigned int group);
|
||||
|
||||
//int upnl_dump_type(struct upmnl_handle *upmh, unsigned int type);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ int set_pdeliv_debug_waitack(unsigned char * msgtype)
|
|||
commnl_addattr_l(&req.n, sizeof(req), NLDEBUG_MSG_TYPE, msgtype, debug_len);
|
||||
|
||||
/*发送组装好的netlink消息*/
|
||||
if (pdeliv_talk(1, &req.n, answer) < 0)
|
||||
if (pdeliv_talk(0, &req.n, answer) < 0)
|
||||
{
|
||||
printf("set_user_policy_waitack rcv ack msg faild.\r\n");
|
||||
return -2;
|
||||
|
@ -110,7 +110,7 @@ int main( int argc, char **argv)
|
|||
}
|
||||
|
||||
/*创建通道*/
|
||||
ret = pdelivnl_open();
|
||||
ret = pdelivnl_open(0);
|
||||
if(ret < 0)
|
||||
{
|
||||
printf("pdelivnl_open fail,exit.\r\n");
|
||||
|
@ -126,7 +126,7 @@ int main( int argc, char **argv)
|
|||
}
|
||||
|
||||
/*关闭netlink通道*/
|
||||
pdelivnl_close();
|
||||
pdelivnl_close(0);
|
||||
|
||||
printf("cfgchannel main exit!\r\n");
|
||||
return 0;
|
||||
|
|
|
@ -38,6 +38,10 @@ COMMON_CFLAGS := -I../../Common
|
|||
PLAT_LINUX_CFLAGS += $(COMMON_CFLAGS)
|
||||
PLAT_ARM64_CFLAGS += $(COMMON_CFLAGS)
|
||||
|
||||
COMMON_LIBS := -lcjson
|
||||
LINUX_LIBS := $(COMMON_LIBS)
|
||||
ARM64_LIBS := $(COMMON_LIBS)
|
||||
|
||||
# this line must be at below of thus, because of...
|
||||
include ../../Common/common.Makefile
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <cjson/cJSON.h>
|
||||
|
||||
#include "compile.h"
|
||||
|
||||
|
@ -13,6 +14,9 @@
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
int c, optidx = 0;
|
||||
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'v' },
|
||||
|
@ -20,6 +24,7 @@ int main(int argc, char **argv)
|
|||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
cJSON_Delete(root);
|
||||
while((c = getopt_long(argc, argv, "hv", long_opts, &optidx)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "uthash.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
struct user_struct
|
||||
{
|
||||
int id; //用户ID
|
||||
uint32_t ip; //用户IP,以IP为索引
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
//initialize to NULL
|
||||
struct user_struct *users = NULL;
|
||||
|
||||
//add user information
|
||||
void add_user(uint32_t user_ip, int user_id)
|
||||
{
|
||||
struct user_struct *s;
|
||||
HASH_FIND_INT(users, &user_ip, s); /*ip already in the hash? */
|
||||
if(s == NULL)
|
||||
{
|
||||
s = (struct user_struct *)malloc(sizeof *s);
|
||||
s->ip = user_ip;
|
||||
HASH_ADD_INT(users, ip, s);
|
||||
}
|
||||
s->id = user_id;
|
||||
}
|
||||
|
||||
//find user information
|
||||
struct user_struct *find_user(uint32_t user_ip)
|
||||
{
|
||||
struct user_struct *s;
|
||||
HASH_FIND_INT(users, &user_ip, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
void delete_user(struct user_struct *user)
|
||||
{
|
||||
HASH_DEL(users, user); /* user: pointer to delete */
|
||||
free(user);
|
||||
}
|
||||
|
||||
//delect all uesr'informations
|
||||
void delete_all()
|
||||
{
|
||||
struct user_struct *current_user, *tmp;
|
||||
HASH_ITER(hh, users, current_user, tmp)
|
||||
{
|
||||
HASH_DEL(users,current_user); /* delete; users advances to next */
|
||||
free(current_user);
|
||||
}
|
||||
}
|
||||
|
||||
//printf user information
|
||||
void print_users()
|
||||
{
|
||||
struct user_struct *s;
|
||||
char str[32];
|
||||
for(s=users; s != NULL; s=(struct user_struct*)(s->hh.next))
|
||||
{
|
||||
//printf("user ip %s: user id %d\n", s->ip, s->id);
|
||||
inet_ntop(AF_INET, (void *)&s->ip, str, 32);
|
||||
printf(" user_ip: %s user_id: %d \n", str, s->id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
#ifndef __HLIST_H
|
||||
#define __HLIST_H
|
||||
|
||||
struct hlist_head {
|
||||
struct hlist_node *first;
|
||||
};
|
||||
|
||||
struct hlist_node {
|
||||
struct hlist_node *next, **pprev;
|
||||
};
|
||||
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
#define HLIST_HEAD_INIT { .first = NULL }
|
||||
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
|
||||
|
||||
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
|
||||
|
||||
static inline void INIT_HLIST_NODE(struct hlist_node *h)
|
||||
{
|
||||
h->next = NULL;
|
||||
h->pprev = NULL;
|
||||
}
|
||||
|
||||
static inline int hlist_unhashed(const struct hlist_node *h)
|
||||
{
|
||||
return !h->pprev;
|
||||
}
|
||||
|
||||
static inline int hlist_empty(const struct hlist_head *h)
|
||||
{
|
||||
return !h->first;
|
||||
}
|
||||
|
||||
static inline void __hlist_del(struct hlist_node *n)
|
||||
{
|
||||
struct hlist_node *next = n->next;
|
||||
struct hlist_node **pprev = n->pprev;
|
||||
*pprev = next;
|
||||
if (next)
|
||||
next->pprev = pprev;
|
||||
}
|
||||
|
||||
static inline void hlist_del(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
n->next = NULL;
|
||||
n->pprev = NULL;
|
||||
}
|
||||
|
||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *first = h->first;
|
||||
n->next = first;
|
||||
if (first)
|
||||
first->pprev = &n->next;
|
||||
h->first = n;
|
||||
n->pprev = &h->first;
|
||||
}
|
||||
|
||||
|
||||
static inline void hlist_del_init(struct hlist_node *n)
|
||||
{
|
||||
if (!hlist_unhashed(n)) {
|
||||
__hlist_del(n);
|
||||
INIT_HLIST_NODE(n);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hlist_add_before(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
static inline void hlist_add_after(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
next->next = n->next;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
|
||||
if(next->next)
|
||||
next->next->pprev = &next->next;
|
||||
}
|
||||
|
||||
static inline void hlist_move_list(struct hlist_head *old,
|
||||
struct hlist_head *new)
|
||||
{
|
||||
new->first = old->first;
|
||||
if (new->first)
|
||||
new->first->pprev = &new->first;
|
||||
old->first = NULL;
|
||||
}
|
||||
|
||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
||||
|
||||
|
||||
#define hlist_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
||||
pos = n)
|
||||
|
||||
#define hlist_for_each_entry(tpos, pos, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
||||
for (pos = (pos)->next; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_entry_from(tpos, pos, member) \
|
||||
for (; pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ n = pos->next; 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = n)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "hlist.h"
|
||||
#include "k-hashtable.h"
|
||||
|
||||
struct hlist_head *hash;
|
||||
struct hlist_node *p = NULL, *n = NULL ;
|
||||
int i = 0;
|
||||
USER_INFO *pNode ;
|
||||
|
||||
/*计算hash值 */
|
||||
struct hlist_head *call_hash(struct hlist_head *hash, uint32_t ip)
|
||||
{
|
||||
unsigned int val = ip % 100;
|
||||
return &hash[val];
|
||||
}
|
||||
|
||||
/*初始化函数 */
|
||||
int Init_hash()
|
||||
{
|
||||
hash = (struct hlist_head*)malloc(sizeof(*hash)*100);
|
||||
if(NULL == hash)
|
||||
{
|
||||
printf("alloc error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < 100; i++)
|
||||
INIT_HLIST_HEAD(&hash[i]);
|
||||
}
|
||||
|
||||
|
||||
/*查找用户信息*/
|
||||
struct user_info *kfind_user(uint32_t user_ip)
|
||||
{
|
||||
hlist_for_each_safe(p,n,call_hash(hash,user_ip))
|
||||
{
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
if(pNode != NULL)
|
||||
printf("user_id :%d\n",pNode->id);
|
||||
return pNode;
|
||||
}
|
||||
}
|
||||
|
||||
/*增加用户信息*/
|
||||
int kadd_user(uint32_t user_ip, int user_id)
|
||||
{
|
||||
USER_INFO *pNode =NULL;
|
||||
hlist_for_each_safe(p,n,call_hash(hash, user_ip)) /*查找ip是否存在hash表中 */
|
||||
{
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
if(pNode != NULL)
|
||||
printf("IP ALEADY EXISTED\n");
|
||||
}
|
||||
|
||||
if (pNode == NULL)
|
||||
{
|
||||
pNode = (struct user_info *)malloc(sizeof(struct user_info));
|
||||
if (NULL == pNode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memset(pNode,0,sizeof(struct user_info));
|
||||
INIT_HLIST_NODE(&pNode->hnode);
|
||||
pNode->ip = user_ip;
|
||||
hlist_add_head(&pNode->hnode, call_hash(hash, user_ip));
|
||||
}
|
||||
pNode->id = user_id;
|
||||
|
||||
}
|
||||
|
||||
/*删除用户信息 */
|
||||
void kdelete_user(int user_ip)
|
||||
{
|
||||
hlist_for_each_safe(p,n,call_hash(hash,user_ip))
|
||||
{
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
hlist_del(&pNode->hnode);
|
||||
free(pNode);
|
||||
}
|
||||
}
|
||||
|
||||
/*删除所有的hash节点 */
|
||||
void kdelete_all()
|
||||
{
|
||||
for(i = 0; i < 100; i++)
|
||||
{
|
||||
hlist_for_each_safe(p,n,&hash[i])
|
||||
{
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
hlist_del(&pNode->hnode);
|
||||
free(pNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*打印所有信息信息 */
|
||||
void kprintf_users()
|
||||
{
|
||||
for(i = 0; i < 100; i++)
|
||||
{
|
||||
hlist_for_each_safe(p,n,&hash[i])
|
||||
{
|
||||
char str[32];
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
if(pNode != NULL)
|
||||
inet_ntop(AF_INET, (void *)&pNode->ip, str, 32);
|
||||
printf("user_ip :%s user_id:%d\n", str, pNode->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef K_HASHTABLE_H
|
||||
#define K_HASHTABLE_H
|
||||
#include <stdint.h>
|
||||
#include "hlist.h"
|
||||
|
||||
typedef struct user_info{
|
||||
struct hlist_node hnode;
|
||||
int id;
|
||||
uint32_t ip;
|
||||
}USER_INFO;
|
||||
|
||||
/*计算hash值 */
|
||||
struct hlist_head *call_hash(struct hlist_head *hash, uint32_t ip);
|
||||
|
||||
/*初始化函数 */
|
||||
int Init_hash();
|
||||
|
||||
/*查找用户信息*/
|
||||
struct user_info *kfind_user(uint32_t user_ip);
|
||||
|
||||
/*增加用户信息*/
|
||||
int kadd_user(uint32_t user_ip, int user_id);
|
||||
|
||||
/*删除用户信息 */
|
||||
void kdelete_user(int user_ip);
|
||||
|
||||
/*删除所有的hash节点 */
|
||||
void kdelete_all();
|
||||
|
||||
/*打印所有信息信息 */
|
||||
void kprintf_users();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include "u-hashtable.h"
|
||||
|
||||
/*initialize */
|
||||
USER_STRUCT *users = NULL;
|
||||
|
||||
/*add user information */
|
||||
void uadd_user(uint32_t user_ip, USER user_info)
|
||||
{
|
||||
USER_STRUCT *s ;
|
||||
HASH_FIND_INT(users, &user_ip, s); /*ip already in the hash? */
|
||||
if(s == NULL)
|
||||
{
|
||||
s = (struct user_struct *)malloc(sizeof *s);
|
||||
s->ip = user_ip;
|
||||
HASH_ADD_INT(users, ip, s);
|
||||
}
|
||||
|
||||
s->info = user_info;
|
||||
}
|
||||
|
||||
/*find user information */
|
||||
USER_STRUCT *ufind_user(uint32_t user_ip)
|
||||
{
|
||||
USER_STRUCT *s;
|
||||
HASH_FIND_INT(users, &user_ip, s);
|
||||
printf("user_nams: %s user_id:%d usergroud_id:%d\n", s->info.name, s->info.user_id, s->info.usergroud_id);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*delete user information */
|
||||
void udelete_user(USER_STRUCT *user)
|
||||
{
|
||||
HASH_DEL(users, user); /* user: pointer to delete */
|
||||
free(user);
|
||||
}
|
||||
|
||||
/*delect all uesr'informations */
|
||||
void udelete_all()
|
||||
{
|
||||
USER_STRUCT *current_user, *tmp;
|
||||
HASH_ITER(hh, users, current_user, tmp)
|
||||
{
|
||||
HASH_DEL(users,current_user); /* delete; users advances to next */
|
||||
free(current_user);
|
||||
}
|
||||
}
|
||||
|
||||
/*printf user information */
|
||||
void uprint_users()
|
||||
{
|
||||
USER_STRUCT *s;
|
||||
char str[32];
|
||||
for(s=users; s != NULL; s=(USER_STRUCT *)(s->hh.next))
|
||||
{
|
||||
inet_ntop(AF_INET, (void *)&s->ip, str, 32);
|
||||
printf(" user_ip: %s user_nams: %s user_id:%d usergroud_id:%d\n", str, s->info.name, s->info.user_id, s->info.usergroud_id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef U_HASHTABLE_H
|
||||
#define U_HASHTABLE_H
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include "uthash.h"
|
||||
|
||||
typedef struct user_info
|
||||
{
|
||||
char name[32]; /*用户名 */
|
||||
int user_id; /*用户ID */
|
||||
int usergroud_id; /*用户组ID */
|
||||
uint64_t message_num; /*下行报文数 */
|
||||
uint64_t byte_num; /*下行字节数*/
|
||||
time_t online_time; /*在线时间 */
|
||||
}USER;
|
||||
|
||||
|
||||
typedef struct user_struct
|
||||
{
|
||||
uint32_t ip; /*用户IP key*/
|
||||
USER info; /*用户信息 */
|
||||
UT_hash_handle hh;
|
||||
}USER_STRUCT;
|
||||
|
||||
/*add user information */
|
||||
void uadd_user(uint32_t user_ip, USER user_info);
|
||||
|
||||
/*find user information */
|
||||
USER_STRUCT *ufind_user(uint32_t user_ip);
|
||||
|
||||
/*delete user information */
|
||||
void udelete_user(USER_STRUCT *user);
|
||||
|
||||
/*delect all uesr'informations */
|
||||
void udelete_all();
|
||||
|
||||
/*printf user information */
|
||||
void uprint_users();
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 3c8935676a97c7c97bf006db8312875b4f292f6c
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Armink (armink.ztl@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,61 @@
|
|||
# C结构体与 JSON 快速互转库
|
||||
|
||||
---
|
||||
|
||||
## struct2json
|
||||
|
||||
[struct2json](https://github.com/armink/struct2json) 是一个开源的C结构体与 JSON 快速互转库,它可以快速实现 **结构体对象** 与 **JSON 对象** 之间序列化及反序列化要求。快速、简洁的 API 设计,大大降低直接使用 JSON 解析库来实现此类功能的代码复杂度。
|
||||
|
||||
## 起源
|
||||
|
||||
把面向对象设计应用到C语言中,是当下很流行的设计思想。由于C语言中没有类,所以一般使用结构体 `struct` 充当类,那么结构体变量就是对象。有了对象之后,很多时候需要考虑对象的序列化及反序列化问题。C语言不像很多高级语言拥有反射等机制,使得对象序列化及反序列化被原生的支持。
|
||||
|
||||
对于C语言来说,序列化为 JSON 字符串是个不错的选择,所以就得使用 [cJSON](https://github.com/kbranigan/cJSON) 这类 JSON 解析库,但是使用后的代码冗余且逻辑性差,所以萌生对cJSON库进行二次封装,实现一个 struct 与 JSON 之间快速互转的库。 struct2json 就诞生于此。下面是 struct2json 主要使用场景:
|
||||
|
||||
- **持久化** :结构体对象序列化为 JSON 对象后,可直接保存至文件、Flash,实现对结构体对象的掉电存储;
|
||||
- **通信** :高级语言对JSON支持的很友好,例如: Javascript、Groovy 就对 JSON 具有原生的支持,所以 JSON 也可作为C语言与其他语言软件之间的通信协议格式及对象传递格式;
|
||||
- **可视化** :序列化为 JSON 后的对象,可以更加直观的展示到控制台或者 UI 上,可用于产品调试、产品二次开发等场景;
|
||||
|
||||
## 如何使用
|
||||
|
||||
### 声明结构体
|
||||
|
||||
如下声明了两个结构体,结构体 `Hometown` 是结构体 `Student` 的子结构体
|
||||
|
||||
```C
|
||||
/* 籍贯 */
|
||||
typedef struct {
|
||||
char name[16];
|
||||
} Hometown;
|
||||
|
||||
/* 学生 */
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint8_t score[8];
|
||||
char name[10];
|
||||
double weight;
|
||||
Hometown hometown;
|
||||
} Student;
|
||||
```
|
||||
|
||||
### 将结构体对象序列化为 JSON 对象
|
||||
|
||||
|使用前([源文件](https://github.com/armink/struct2json/blob/master/docs/zh/assets/not_use_struct2json.c))|使用后([源文件](https://github.com/armink/struct2json/blob/master/docs/zh/assets/used_struct2json.c))|
|
||||
|:-----:|:-----:|
|
||||
|![结构体转JSON-使用前](https://git.oschina.net/Armink/struct2json/raw/master/docs/zh/images/not_use_struct2json.png)| ![结构体转JSON-使用后](https://git.oschina.net/Armink/struct2json/raw/master/docs/zh/images/used_struct2json.png)|
|
||||
|
||||
### 将 JSON 对象反序列化为结构体对象
|
||||
|
||||
|使用前([源文件](https://github.com/armink/struct2json/blob/master/docs/zh/assets/not_use_struct2json_for_json.c))|使用后([源文件](https://github.com/armink/struct2json/blob/master/docs/zh/assets/used_struct2json_for_json.c))|
|
||||
|:-----:|:-----:|
|
||||
|![JSON转结构体-使用前](https://git.oschina.net/Armink/struct2json/raw/master/docs/zh/images/not_use_struct2json_for_json.png)| ![JSON转结构体-使用后](https://git.oschina.net/Armink/struct2json/raw/master/docs/zh/images/used_struct2json_for_json.png)|
|
||||
|
||||
欢迎大家 **fork and pull request**([Github](https://github.com/armink/struct2json)|[OSChina](http://git.oschina.net/armink/struct2json)|[Coding](https://coding.net/u/armink/p/struct2json/git)) 。如果觉得这个开源项目很赞,可以点击[项目主页](https://github.com/armink/struct2json) 右上角的**Star**,同时把它推荐给更多有需要的朋友。
|
||||
|
||||
## 文档
|
||||
|
||||
具体内容参考[`\docs\zh\`](https://github.com/armink/struct2json/tree/master/docs/zh)下的文件。务必保证在 **阅读文档** 后再使用。
|
||||
|
||||
## 许可
|
||||
|
||||
MIT Copyright (c) armink.ztl@gmail.com
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* This file is part of the struct2json Library.
|
||||
*
|
||||
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Function: demo for this library.
|
||||
* Created on: 2015-10-14
|
||||
*/
|
||||
|
||||
#include "s2j.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
char name[16];
|
||||
} Hometown;
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
double weight;
|
||||
uint8_t score[8];
|
||||
char name[10];
|
||||
Hometown hometown;
|
||||
} Student;
|
||||
|
||||
/**
|
||||
* Student JSON object to structure object
|
||||
*
|
||||
* @param json_obj JSON object
|
||||
*
|
||||
* @return structure object
|
||||
*/
|
||||
static void *json_to_struct(cJSON* json_obj) {
|
||||
/* create Student structure object */
|
||||
s2j_create_struct_obj(struct_student, Student);
|
||||
|
||||
/* deserialize data to Student structure object. */
|
||||
s2j_struct_get_basic_element(struct_student, json_obj, int, id);
|
||||
s2j_struct_get_array_element(struct_student, json_obj, int, score);
|
||||
s2j_struct_get_basic_element(struct_student, json_obj, string, name);
|
||||
s2j_struct_get_basic_element(struct_student, json_obj, double, weight);
|
||||
|
||||
/* deserialize data to Student.Hometown structure object. */
|
||||
s2j_struct_get_struct_element(struct_hometown, struct_student, json_hometown, json_obj, Hometown, hometown);
|
||||
s2j_struct_get_basic_element(struct_hometown, json_hometown, string, name);
|
||||
|
||||
/* return Student structure object pointer */
|
||||
return struct_student;
|
||||
}
|
||||
|
||||
/**
|
||||
* Student structure object to JSON object
|
||||
*
|
||||
* @param struct_obj structure object
|
||||
*
|
||||
* @param JSON object
|
||||
*/
|
||||
static cJSON *struct_to_json(void* struct_obj) {
|
||||
Student *struct_student = (Student *)struct_obj;
|
||||
|
||||
/* create Student JSON object */
|
||||
s2j_create_json_obj(json_student);
|
||||
|
||||
/* serialize data to Student JSON object. */
|
||||
s2j_json_set_basic_element(json_student, struct_student, int, id);
|
||||
s2j_json_set_basic_element(json_student, struct_student, double, weight);
|
||||
s2j_json_set_array_element(json_student, struct_student, int, score, 8);
|
||||
s2j_json_set_basic_element(json_student, struct_student, string, name);
|
||||
|
||||
/* serialize data to Student.Hometown JSON object. */
|
||||
s2j_json_set_struct_element(json_hometown, json_student, struct_hometown, struct_student, Hometown, hometown);
|
||||
s2j_json_set_basic_element(json_hometown, struct_hometown, string, name);
|
||||
|
||||
/* return Student JSON object pointer */
|
||||
return json_student;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
static Student orignal_student_obj = {
|
||||
.id = 24,
|
||||
.weight = 71.2,
|
||||
.score = {1, 2, 3, 4, 5, 6, 7, 8},
|
||||
.name = "armink",
|
||||
.hometown.name = "China",
|
||||
};
|
||||
|
||||
/* serialize Student structure object */
|
||||
cJSON *json_student = struct_to_json(&orignal_student_obj);
|
||||
/* deserialize Student structure object */
|
||||
Student *converted_student_obj = json_to_struct(json_student);
|
||||
|
||||
/* compare Student structure object */
|
||||
if(memcmp(&orignal_student_obj, converted_student_obj, sizeof(Student))) {
|
||||
printf("Converted failed!\n");
|
||||
} else {
|
||||
printf("Converted OK!\n");
|
||||
}
|
||||
|
||||
s2j_delete_json_obj(json_student);
|
||||
s2j_delete_struct_obj(converted_student_obj);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
|File or folder name |Description|
|
||||
|:----- |:----|
|
||||
|en |English documents|
|
||||
|zh |中文文档(简体)|
|
|
@ -0,0 +1,194 @@
|
|||
# struct2json API 文档
|
||||
|
||||
---
|
||||
|
||||
所有支持的API接口都在 `\struct2json\inc\s2j.h` 中声明。以下内容较多,建议使用 CTRL+F 搜索。
|
||||
|
||||
## 1、用户使用接口
|
||||
|
||||
### 1.1 初始化
|
||||
|
||||
初始化的struct2json库。
|
||||
|
||||
> 注:目前主要初始化该库及cJSON库所需的内存管理方法。默认使用的 `malloc` 及 `free` 作为内存管理方法,如果使用默认内存管理方式,则无需初始化。
|
||||
|
||||
```C
|
||||
void s2j_init(S2jHook *hook)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|hook |指定的内存管理方法|
|
||||
|
||||
### 1.2 将结构体对象转换(序列化)为JSON对象
|
||||
|
||||
注意:以下API均采用宏定义方式,在使用时与常用API方法形式略有不同,请注意查看Demo。
|
||||
|
||||
#### 1.2.1 创建JSON对象
|
||||
|
||||
```C
|
||||
s2j_create_json_obj(json_obj)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|json_obj |JSON对象|
|
||||
|
||||
#### 1.2.2 转换基本类型元素
|
||||
|
||||
注意:这里的结构体元素基本类型只支持 `int` 、 `string` 及 `double` ,其他类型转换时应考虑选取三者中的其中一种作目标类型,选择标准为两者类型间可被无损相互转换。例如:结构体元素类型为 `uint8_t` 、`uint16_t` 、`int16_t` 、 `size_t` 、`某指针地址` 等类型可以选择 `int` 作为入参。
|
||||
|
||||
```C
|
||||
s2j_json_set_basic_element(to_json, from_struct, type, element)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|to_json |目标JSON对象|
|
||||
|from_struct |源结构体对象|
|
||||
|type |源结构体对象元素类型,这里只支持int、string、double|
|
||||
|element |源结构体对象元素|
|
||||
|
||||
#### 1.2.3 转换数组类型元素
|
||||
|
||||
```C
|
||||
s2j_json_set_array_element(to_json, from_struct, type, element, size)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|to_json |目标JSON对象|
|
||||
|from_struct |源结构体对象|
|
||||
|type |源结构体对象元素的基本类型。参考1.2.2中对基本类型的要求|
|
||||
|element |源结构体对象元素|
|
||||
|size |源结构体对象数组元素的长度|
|
||||
|
||||
#### 1.2.4 转换结构体类型元素(即子结构体)
|
||||
|
||||
```C
|
||||
s2j_json_set_struct_element(child_json, to_json, child_struct, from_struct, type, element)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|child_json |目标JSON对象的子JSON对象|
|
||||
|to_json |目标JSON对象|
|
||||
|child_struct |源结构体对象的子结构体对象|
|
||||
|from_struct |源结构体对象|
|
||||
|type |源结构体对象元素(子结构体)类型|
|
||||
|element |源结构体对象元素|
|
||||
|
||||
例子:
|
||||
```C
|
||||
typedef struct {
|
||||
char name[16];
|
||||
} Hometown;
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
char name[10];
|
||||
Hometown hometown;
|
||||
} Student;
|
||||
|
||||
Student orignal_struct_student = {
|
||||
.id = 24,
|
||||
.name = "armink",
|
||||
.hometown.name = "China",
|
||||
}
|
||||
Student *struct_student = &orignal_struct_student;
|
||||
/* 创建空Student JSON对象 */
|
||||
s2j_create_json_obj(json_student);
|
||||
/* 序列化(转换)Student结构体的id元素 */
|
||||
s2j_json_set_basic_element(json_student, struct_student, int, id);
|
||||
/* 序列化Student结构体的name元素 */
|
||||
s2j_json_set_basic_element(json_student, struct_student, string, name);
|
||||
/* 序列化Student结构体的子结构体hometown元素 */
|
||||
s2j_json_set_struct_element(json_hometown, json_student, struct_hometown, struct_student, Hometown, hometown);
|
||||
/* 序列化Hometown结构体的name元素 */
|
||||
s2j_json_set_basic_element(json_hometown, struct_hometown, string, name);
|
||||
```
|
||||
|
||||
### 1.3 将JSON对象转换(反序列化)为结构体对象
|
||||
|
||||
#### 1.3.1 创建结构体对象
|
||||
|
||||
```C
|
||||
s2j_create_struct_obj(struct_obj, type)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|struct_obj |结构体对象|
|
||||
|type |结构体类型|
|
||||
|
||||
#### 1.3.2 转换基本类型元素
|
||||
|
||||
```C
|
||||
s2j_struct_get_basic_element(to_struct, from_json, type, element)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|to_struct |目标结构体对象|
|
||||
|from_json |源JSON对象|
|
||||
|type |目标结构体对象元素类型。参考1.2.2中对基本类型的要求|
|
||||
|element |目标结构体对象元素|
|
||||
|
||||
#### 1.3.3 转换数组类型元素
|
||||
|
||||
```C
|
||||
s2j_struct_get_array_element(to_struct, from_json, type, element)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|to_struct |目标结构体对象|
|
||||
|from_json |源JSON对象|
|
||||
|type |目标结构体对象元素类型。参考1.2.2中对基本类型的要求|
|
||||
|element |目标结构体对象元素|
|
||||
|
||||
#### 1.3.4 转换结构体类型元素(即子JSON)
|
||||
|
||||
```C
|
||||
s2j_struct_get_struct_element(child_struct, to_struct, child_json, from_json, type, element)
|
||||
```
|
||||
|
||||
|参数 |描述|
|
||||
|:----- |:----|
|
||||
|child_struct |目标结构体对象的子结构体对象|
|
||||
|to_struct |目标结构体对象|
|
||||
|child_json |源JSON对象的子JSON对象|
|
||||
|from_json |源JSON对象|
|
||||
|type |源JSON对象元素(子JSON)类型|
|
||||
|element |源JSON对象元素|
|
||||
|
||||
例子:
|
||||
```C
|
||||
typedef struct {
|
||||
char name[16];
|
||||
} Hometown;
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
char name[10];
|
||||
Hometown hometown;
|
||||
} Student;
|
||||
|
||||
char orignal_json_string_student[] = "{\"id\":24, \"name\":\"armink\", \"hometown\":{\"name\":\"China\"}}";
|
||||
/* 创建Student JSON对象 */
|
||||
cJSON *json_student = cJSON_Parse(orignal_json_string_student);
|
||||
/* 创建空Student结构体对象 */
|
||||
s2j_create_struct_obj(struct_student, Student);
|
||||
/* 反序列化Student结构体的id元素 */
|
||||
s2j_struct_get_basic_element(struct_student, json_student, int, id);
|
||||
/* 反序列化Student结构体的name元素 */
|
||||
s2j_struct_get_basic_element(struct_student, json_student, string, name);
|
||||
/* 反序列化Student结构体的子结构体hometown元素 */
|
||||
s2j_struct_get_struct_element(struct_hometown, struct_student, json_hometown, json_student, Hometown, hometown);
|
||||
/* 反序列化Hometown结构体的name元素 */
|
||||
s2j_struct_get_basic_element(struct_hometown, json_hometown, string, name);
|
||||
```
|
||||
|
||||
## 2、注意
|
||||
|
||||
- 该库只适用于C99及其以上标准编译器
|
|
@ -0,0 +1,30 @@
|
|||
cJSON *struct_to_json(void* struct_obj) {
|
||||
Student *struct_student = (Student *) struct_obj;
|
||||
cJSON *score, *score_element;
|
||||
size_t index = 0;
|
||||
|
||||
/* 创建Student JSON对象 */
|
||||
cJSON *json_student = cJSON_CreateObject();
|
||||
|
||||
/* 序列化数据到Student JSON对象 */
|
||||
cJSON_AddNumberToObject(json_student, "id", struct_student->id);
|
||||
cJSON_AddNumberToObject(json_student, "weight", struct_student->weight);
|
||||
score = cJSON_CreateArray();
|
||||
if (score) {
|
||||
while (index < 8) {
|
||||
score_element = cJSON_CreateNumber(struct_student->score[index++]);
|
||||
cJSON_AddItemToArray(score, score_element);
|
||||
}
|
||||
cJSON_AddItemToObject(json_student, "score", score);
|
||||
}
|
||||
cJSON_AddStringToObject(json_student, "name", struct_student->name);
|
||||
|
||||
/* 序列化数据到Student.Hometown JSON对象 */
|
||||
Hometown *hometown_struct = &(struct_student->hometown);
|
||||
cJSON *hometown_json = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(json_student, "hometown", hometown_json);
|
||||
cJSON_AddStringToObject(hometown_json, "name", hometown_struct->name);
|
||||
|
||||
/* 返回Student JSON对象指针 */
|
||||
return json_student;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
void *json_to_struct(cJSON* json_obj) {
|
||||
cJSON *json_temp, *score, *score_element;
|
||||
Student *struct_student;
|
||||
size_t index = 0, score_size = 0;
|
||||
|
||||
/* 创建Student结构体对象 */
|
||||
struct_student = s2j_malloc(sizeof(Student));
|
||||
if (struct_student) {
|
||||
memset(struct_student, 0, sizeof(Student));
|
||||
}
|
||||
|
||||
/* 反序列化数据到Student结构体对象 */
|
||||
json_temp = cJSON_GetObjectItem(json_obj, "id");
|
||||
if (json_temp) {
|
||||
struct_student->id = json_temp->valueint;
|
||||
}
|
||||
score = cJSON_GetObjectItem(json_obj, "score")
|
||||
if (score) {
|
||||
score_size = cJSON_GetArraySize(score);
|
||||
while (index < score_size) {
|
||||
score_element = cJSON_GetArrayItem(score, index);
|
||||
if (score_element) {
|
||||
struct_student->score[index++] = score_element->valueint;
|
||||
}
|
||||
}
|
||||
}
|
||||
json_temp = cJSON_GetObjectItem(json_obj, "name");
|
||||
if (json_temp) {
|
||||
strcpy(struct_student->name, json_temp->valuestring);
|
||||
}
|
||||
json_temp = cJSON_GetObjectItem(json_obj, "weight");
|
||||
if (json_temp) {
|
||||
struct_student->weight = json_temp->valuedouble;
|
||||
}
|
||||
|
||||
/* 反序列化数据到Student.Hometown结构体对象 */
|
||||
Hometown *struct_hometown = &(struct_student->hometown);
|
||||
cJSON *json_hometown = cJSON_GetObjectItem(json_obj, "hometown");
|
||||
json_temp = cJSON_GetObjectItem(json_hometown, "name");
|
||||
if (json_temp) {
|
||||
strcpy(struct_hometown->name, json_temp->valuestring);
|
||||
}
|
||||
|
||||
/* 返回Student结构体对象指针 */
|
||||
return struct_student;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
cJSON *struct_to_json(void* struct_obj) {
|
||||
Student *struct_student = (Student *)struct_obj;
|
||||
|
||||
/* 创建Student JSON对象 */
|
||||
s2j_create_json_obj(json_student);
|
||||
|
||||
/* 序列化数据到Student JSON对象 */
|
||||
s2j_json_set_basic_element(json_student, struct_student, int, id);
|
||||
s2j_json_set_basic_element(json_student, struct_student, double, weight);
|
||||
s2j_json_set_array_element(json_student, struct_student, int, score, 8);
|
||||
s2j_json_set_basic_element(json_student, struct_student, string, name);
|
||||
|
||||
/* 序列化数据到Student.Hometown JSON对象 */
|
||||
s2j_json_set_struct_element(json_hometown, json_student, struct_hometown, struct_student, Hometown, hometown);
|
||||
s2j_json_set_basic_element(json_hometown, struct_hometown, string, name);
|
||||
|
||||
/* 返回Student JSON对象指针 */
|
||||
return json_student;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
void *json_to_struct(cJSON* json_obj) {
|
||||
/* 创建Student结构体对象 */
|
||||
s2j_create_struct_obj(struct_student, Student);
|
||||
|
||||
/* 反序列化数据到Student结构体对象 */
|
||||
s2j_struct_get_basic_element(struct_student, json_obj, int, id);
|
||||
s2j_struct_get_array_element(struct_student, json_obj, int, score);
|
||||
s2j_struct_get_basic_element(struct_student, json_obj, string, name);
|
||||
s2j_struct_get_basic_element(struct_student, json_obj, double, weight);
|
||||
|
||||
/* 反序列化数据到Student.Hometown结构体对象 */
|
||||
s2j_struct_get_struct_element(struct_hometown, struct_student, json_hometown, json_obj, Hometown, hometown);
|
||||
s2j_struct_get_basic_element(struct_hometown, json_hometown, string, name);
|
||||
|
||||
/* 返回Student结构体对象指针 */
|
||||
return struct_student;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
|
@ -0,0 +1,3 @@
|
|||
|文件名 |描述|
|
||||
|:----- |:----|
|
||||
|api.md |API 说明|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* This file is part of the struct2json Library.
|
||||
*
|
||||
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Function: It is an head file for this library. You can see all be called functions.
|
||||
* Created on: 2015-10-14
|
||||
*/
|
||||
|
||||
#ifndef __S2J_H__
|
||||
#define __S2J_H__
|
||||
|
||||
#include <cJSON/cJSON.h>
|
||||
#include <string.h>
|
||||
#include "s2jdef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* struct2json software version number */
|
||||
#define S2J_SW_VERSION "1.0.3"
|
||||
|
||||
/* Create JSON object */
|
||||
#define s2j_create_json_obj(json_obj) \
|
||||
S2J_CREATE_JSON_OBJECT(json_obj)
|
||||
|
||||
/* Delete JSON object */
|
||||
#define s2j_delete_json_obj(json_obj) \
|
||||
S2J_DELETE_JSON_OBJECT(json_obj)
|
||||
|
||||
/* Set basic type element for JSON object */
|
||||
#define s2j_json_set_basic_element(to_json, from_struct, type, element) \
|
||||
S2J_JSON_SET_BASIC_ELEMENT(to_json, from_struct, type, element)
|
||||
|
||||
/* Set array type element for JSON object */
|
||||
#define s2j_json_set_array_element(to_json, from_struct, type, element, size) \
|
||||
S2J_JSON_SET_ARRAY_ELEMENT(to_json, from_struct, type, element, size)
|
||||
|
||||
/* Set child structure type element for JSON object */
|
||||
#define s2j_json_set_struct_element(child_json, to_json, child_struct, from_struct, type, element) \
|
||||
S2J_JSON_SET_STRUCT_ELEMENT(child_json, to_json, child_struct, from_struct, type, element)
|
||||
|
||||
/* Create structure object */
|
||||
#define s2j_create_struct_obj(struct_obj, type) \
|
||||
S2J_CREATE_STRUCT_OBJECT(struct_obj, type)
|
||||
|
||||
/* Delete structure object */
|
||||
#define s2j_delete_struct_obj(struct_obj) \
|
||||
S2J_DELETE_STRUCT_OBJECT(struct_obj)
|
||||
|
||||
/* Get basic type element for structure object */
|
||||
#define s2j_struct_get_basic_element(to_struct, from_json, type, element) \
|
||||
S2J_STRUCT_GET_BASIC_ELEMENT(to_struct, from_json, type, element)
|
||||
|
||||
/* Get array type element for structure object */
|
||||
#define s2j_struct_get_array_element(to_struct, from_json, type, element) \
|
||||
S2J_STRUCT_GET_ARRAY_ELEMENT(to_struct, from_json, type, element)
|
||||
|
||||
/* Get child structure type element for structure object */
|
||||
#define s2j_struct_get_struct_element(child_struct, to_struct, child_json, from_json, type, element) \
|
||||
S2J_STRUCT_GET_STRUCT_ELEMENT(child_struct, to_struct, child_json, from_json, type, element)
|
||||
|
||||
/* s2j.c */
|
||||
extern S2jHook s2jHook;
|
||||
void s2j_init(S2jHook *hook);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __S2J_H__ */
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* This file is part of the struct2json Library.
|
||||
*
|
||||
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Function: It is an head file for this library.
|
||||
* Created on: 2015-10-14
|
||||
*/
|
||||
|
||||
#ifndef __S2JDEF_H__
|
||||
#define __S2JDEF_H__
|
||||
|
||||
#include <cJSON/cJSON.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} S2jHook, *S2jHook_t;
|
||||
|
||||
#define S2J_STRUCT_GET_int_ELEMENT(to_struct, from_json, _element) \
|
||||
json_temp = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (json_temp) (to_struct)->_element = json_temp->valueint;
|
||||
|
||||
#define S2J_STRUCT_GET_string_ELEMENT(to_struct, from_json, _element) \
|
||||
json_temp = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (json_temp) strcpy((to_struct)->_element, json_temp->valuestring);
|
||||
|
||||
#define S2J_STRUCT_GET_double_ELEMENT(to_struct, from_json, _element) \
|
||||
json_temp = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (json_temp) (to_struct)->_element = json_temp->valuedouble;
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_int_ELEMENT(to_struct, from_json, _element, index) \
|
||||
(to_struct)->_element[index] = from_json->valueint;
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_string_ELEMENT(to_struct, from_json, _element, index) \
|
||||
strcpy((to_struct)->_element[index], from_json->valuestring);
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_double_ELEMENT(to_struct, from_json, _element, index) \
|
||||
(to_struct)->_element[index] = from_json->valuedouble;
|
||||
|
||||
#define S2J_STRUCT_ARRAY_GET_ELEMENT(to_struct, from_json, type, _element, index) \
|
||||
S2J_STRUCT_ARRAY_GET_##type##_ELEMENT(to_struct, from_json, _element, index)
|
||||
|
||||
#define S2J_JSON_SET_int_ELEMENT(to_json, from_struct, _element) \
|
||||
cJSON_AddNumberToObject(to_json, #_element, (from_struct)->_element);
|
||||
|
||||
#define S2J_JSON_SET_double_ELEMENT(to_json, from_struct, _element) \
|
||||
cJSON_AddNumberToObject(to_json, #_element, (from_struct)->_element);
|
||||
|
||||
#define S2J_JSON_SET_string_ELEMENT(to_json, from_struct, _element) \
|
||||
cJSON_AddStringToObject(to_json, #_element, (from_struct)->_element);
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_int_ELEMENT(to_json, from_struct, _element, index) \
|
||||
cJSON_AddItemToArray(to_json, cJSON_CreateNumber((from_struct)->_element[index]));
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_double_ELEMENT(to_json, from_struct, _element, index) \
|
||||
cJSON_AddItemToArray(to_json, cJSON_CreateNumber((from_struct)->_element[index]));
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_string_ELEMENT(to_json, from_struct, _element, index) \
|
||||
cJSON_AddItemToArray(to_json, cJSON_CreateString((from_struct)->_element[index]));
|
||||
|
||||
#define S2J_JSON_ARRAY_SET_ELEMENT(to_json, from_struct, type, _element, index) \
|
||||
S2J_JSON_ARRAY_SET_##type##_ELEMENT(to_json, from_struct, _element, index)
|
||||
|
||||
|
||||
#define S2J_CREATE_JSON_OBJECT(json_obj) \
|
||||
cJSON *json_obj = cJSON_CreateObject();
|
||||
|
||||
#define S2J_DELETE_JSON_OBJECT(json_obj) \
|
||||
cJSON_Delete(json_obj);
|
||||
|
||||
#define S2J_JSON_SET_BASIC_ELEMENT(to_json, from_struct, type, _element) \
|
||||
S2J_JSON_SET_##type##_ELEMENT(to_json, from_struct, _element)
|
||||
|
||||
#define S2J_JSON_SET_ARRAY_ELEMENT(to_json, from_struct, type, _element, size) \
|
||||
{ \
|
||||
cJSON *array; \
|
||||
size_t index = 0; \
|
||||
array = cJSON_CreateArray(); \
|
||||
if (array) { \
|
||||
while (index < size) { \
|
||||
S2J_JSON_ARRAY_SET_ELEMENT(array, from_struct, type, _element, index++); \
|
||||
} \
|
||||
cJSON_AddItemToObject(to_json, #_element, array); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define S2J_JSON_SET_STRUCT_ELEMENT(child_json, to_json, child_struct, from_struct, type, _element) \
|
||||
type *child_struct = &((from_struct)->_element); \
|
||||
cJSON *child_json = cJSON_CreateObject(); \
|
||||
if (child_json) cJSON_AddItemToObject(to_json, #_element, child_json);
|
||||
|
||||
#define S2J_CREATE_STRUCT_OBJECT(struct_obj, type) \
|
||||
cJSON *json_temp; \
|
||||
type *struct_obj = s2jHook.malloc_fn(sizeof(type)); \
|
||||
if (struct_obj) memset(struct_obj, 0, sizeof(type));
|
||||
|
||||
#define S2J_DELETE_STRUCT_OBJECT(struct_obj) \
|
||||
s2jHook.free_fn(struct_obj);
|
||||
|
||||
#define S2J_STRUCT_GET_BASIC_ELEMENT(to_struct, from_json, type, _element) \
|
||||
S2J_STRUCT_GET_##type##_ELEMENT(to_struct, from_json, _element)
|
||||
|
||||
#define S2J_STRUCT_GET_ARRAY_ELEMENT(to_struct, from_json, type, _element) \
|
||||
{ \
|
||||
cJSON *array, *array_element; \
|
||||
size_t index = 0, size = 0; \
|
||||
array = cJSON_GetObjectItem(from_json, #_element); \
|
||||
if (array) { \
|
||||
size = cJSON_GetArraySize(array); \
|
||||
while (index < size) { \
|
||||
array_element = cJSON_GetArrayItem(array, index); \
|
||||
if (array_element) S2J_STRUCT_ARRAY_GET_ELEMENT(to_struct, array_element, type, _element, index++); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define S2J_STRUCT_GET_STRUCT_ELEMENT(child_struct, to_struct, child_json, from_json, type, _element) \
|
||||
type *child_struct = &((to_struct)->_element); \
|
||||
cJSON *child_json = cJSON_GetObjectItem(from_json, #_element);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __S2JDEF_H__ */
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* This file is part of the struct2json Library.
|
||||
*
|
||||
* Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Function: Initialize interface for this library.
|
||||
* Created on: 2015-10-14
|
||||
*/
|
||||
|
||||
#include <s2j.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
S2jHook s2jHook = {
|
||||
.malloc_fn = malloc,
|
||||
.free_fn = free,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct2json library initialize
|
||||
* @note It will initialize cJSON library hooks.
|
||||
*/
|
||||
void s2j_init(S2jHook *hook) {
|
||||
/* initialize cJSON library */
|
||||
cJSON_InitHooks((cJSON_Hooks *)hook);
|
||||
/* initialize hooks */
|
||||
if (hook) {
|
||||
s2jHook.malloc_fn = (hook->malloc_fn) ? hook->malloc_fn : malloc;
|
||||
s2jHook.free_fn = (hook->free_fn) ? hook->free_fn : free;
|
||||
} else {
|
||||
s2jHook.malloc_fn = malloc;
|
||||
s2jHook.free_fn = free;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue