This commit is contained in:
wuhuanzheng 2019-06-26 16:15:45 +08:00
commit c22ad8f5d9
37 changed files with 1630 additions and 89 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "libs/src/cJSON"]
path = libs/src/cJSON
url = https://github.com/DaveGamble/cJSON.git

91
Common/s2j/s2j.h Normal file
View File

@ -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__ */

150
Common/s2j/s2jdef.h Normal file
View File

@ -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__ */

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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++;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

1
libs/src/cJSON Submodule

@ -0,0 +1 @@
Subproject commit 3c8935676a97c7c97bf006db8312875b4f292f6c

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,4 @@
|File or folder name |Description|
|:----- |:----|
|en |English documents|
|zh |中文文档(简体)|

View File

@ -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及其以上标准编译器

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,3 @@
|文件名 |描述|
|:----- |:----|
|api.md |API 说明|

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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;
}
}