mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2025-07-06 07:44:57 +03:00
Implementation of the JSON-RPC API and the Web Admin interface. (dnobori's internal note: 7579 - 7682)
This commit is contained in:
@ -1127,6 +1127,12 @@ void BuildHamcore(char *dst_filename, char *src_dir, bool unix_only)
|
||||
}
|
||||
}
|
||||
|
||||
if (InStr(rpath, "\\node_modules\\"))
|
||||
{
|
||||
// Exclude node_modules in the hamcore\webroot
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
b = ReadDump(s);
|
||||
|
@ -1408,11 +1408,103 @@ void GetDateTimeStrMilli(char *str, UINT size, SYSTEMTIME *st)
|
||||
st->wMilliseconds);
|
||||
}
|
||||
|
||||
|
||||
// Convert string RFC3339 format (example: 2017-09-27T18:25:55.434-9:00) to UINT64
|
||||
UINT64 DateTimeStrRFC3339ToSystemTime64(char *str)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
if (DateTimeStrRFC3339ToSystemTime(&st, str))
|
||||
{
|
||||
return SystemToUINT64(&st);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert string RFC3339 format (example: 2017-09-27T18:25:55.434-9:00) to SYSTEMTIME
|
||||
bool DateTimeStrRFC3339ToSystemTime(SYSTEMTIME *st, char *str)
|
||||
{
|
||||
bool ok = false;
|
||||
UINT index_plus;
|
||||
char tmp[MAX_PATH];
|
||||
Zero(st, sizeof(SYSTEMTIME));
|
||||
if (st == NULL || str == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
StrCpy(tmp, sizeof(tmp), str);
|
||||
|
||||
index_plus = SearchStrEx(tmp, "+", 0, false);
|
||||
if (index_plus != INFINITE)
|
||||
{
|
||||
tmp[index_plus] = 0;
|
||||
}
|
||||
|
||||
if (StrLen(tmp) >= 19)
|
||||
{
|
||||
if (tmp[4] == '-' && tmp[7] == '-' && tmp[10] == 'T' && tmp[13] == ':' &&
|
||||
tmp[16] == ':')
|
||||
{
|
||||
char str_year[16], str_month[16], str_day[16], str_hour[16], str_minute[16],
|
||||
str_second[16], str_msec[16];
|
||||
|
||||
StrCpy(str_year, sizeof(str_year), tmp + 0);
|
||||
str_year[4] = 0;
|
||||
|
||||
StrCpy(str_month, sizeof(str_month), tmp + 5);
|
||||
str_month[2] = 0;
|
||||
|
||||
StrCpy(str_day, sizeof(str_day), tmp + 8);
|
||||
str_day[2] = 0;
|
||||
|
||||
StrCpy(str_hour, sizeof(str_hour), tmp + 11);
|
||||
str_hour[2] = 0;
|
||||
|
||||
StrCpy(str_minute, sizeof(str_minute), tmp + 14);
|
||||
str_minute[2] = 0;
|
||||
|
||||
StrCpy(str_second, sizeof(str_second), tmp + 17);
|
||||
str_second[2] = 0;
|
||||
|
||||
str_msec[0] = 0;
|
||||
|
||||
if (StrLen(tmp) >= 21 && tmp[19] == '.')
|
||||
{
|
||||
StrCpy(str_msec, sizeof(str_msec), tmp + 20);
|
||||
str_msec[StrLen(tmp) - 21] = 0;
|
||||
while (StrLen(str_msec) < 3)
|
||||
{
|
||||
StrCat(str_msec, sizeof(str_msec), "0");
|
||||
}
|
||||
str_msec[3] = 0;
|
||||
}
|
||||
|
||||
st->wYear = ToInt(str_year);
|
||||
st->wMonth = ToInt(str_month);
|
||||
st->wDay = ToInt(str_day);
|
||||
st->wHour = ToInt(str_hour);
|
||||
st->wMinute = ToInt(str_minute);
|
||||
st->wSecond = ToInt(str_second);
|
||||
st->wMilliseconds = ToInt(str_msec);
|
||||
|
||||
NormalizeSystem(st);
|
||||
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Get the date and time string in RFC3339 format (example: 2017-09-27T18:25:55.434-9:00)
|
||||
void GetDateTimeStrRFC3339(char *str, UINT size, SYSTEMTIME *st, int timezone_min){
|
||||
// Validate arguments
|
||||
if (str == NULL || st == NULL)
|
||||
{
|
||||
ClearStr(str, size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -137,6 +137,8 @@ void GetDateTimeStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
|
||||
void GetDateStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
|
||||
void GetTimeStrMilli64(char *str, UINT size, UINT64 sec64);
|
||||
void GetDateTimeStrRFC3339(char *str, UINT size, SYSTEMTIME *st, int timezone_min);
|
||||
bool DateTimeStrRFC3339ToSystemTime(SYSTEMTIME *st, char *str);
|
||||
UINT64 DateTimeStrRFC3339ToSystemTime64(char *str);
|
||||
UINT64 SafeTime64(UINT64 sec64);
|
||||
bool Run(char *filename, char *arg, bool hide, bool wait);
|
||||
bool RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait);
|
||||
|
@ -347,6 +347,9 @@ typedef struct PRAND PRAND;
|
||||
// Str.h
|
||||
typedef struct TOKEN_LIST TOKEN_LIST;
|
||||
typedef struct INI_ENTRY INI_ENTRY;
|
||||
typedef struct JSON_OBJECT JSON_OBJECT;
|
||||
typedef struct JSON_ARRAY JSON_ARRAY;
|
||||
typedef struct JSON_VALUE JSON_VALUE;
|
||||
|
||||
// Internat.h
|
||||
typedef struct UNI_TOKEN_LIST UNI_TOKEN_LIST;
|
||||
@ -383,6 +386,8 @@ typedef struct INSTANCE INSTANCE;
|
||||
typedef struct VALUE VALUE;
|
||||
typedef struct ELEMENT ELEMENT;
|
||||
typedef struct PACK PACK;
|
||||
typedef struct JSONPACKHINT JSONPACKHINT;
|
||||
typedef struct JSONPACKHINT_ITEM JSONPACKHINT_ITEM;
|
||||
|
||||
// Cfg.h
|
||||
typedef struct FOLDER FOLDER;
|
||||
|
@ -1413,6 +1413,48 @@ bool ReplaceListPointer(LIST *o, void *oldptr, void *newptr)
|
||||
return false;
|
||||
}
|
||||
|
||||
// New string list
|
||||
LIST *NewStrList()
|
||||
{
|
||||
return NewListFast(CompareStr);
|
||||
}
|
||||
|
||||
// Release string list
|
||||
void ReleaseStrList(LIST *o)
|
||||
{
|
||||
UINT i;
|
||||
if (o == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0;i < LIST_NUM(o);i++)
|
||||
{
|
||||
char *s = LIST_DATA(o, i);
|
||||
Free(s);
|
||||
}
|
||||
|
||||
ReleaseList(o);
|
||||
}
|
||||
|
||||
// Add a string distinct to the string list
|
||||
bool AddStrToStrListDistinct(LIST *o, char *str)
|
||||
{
|
||||
if (o == NULL || str == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsInListStr(o, str) == false)
|
||||
{
|
||||
Add(o, CopyStr(str));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Examine whether a string items are present in the list
|
||||
bool IsInListStr(LIST *o, char *str)
|
||||
{
|
||||
@ -2948,6 +2990,43 @@ void WriteBufBuf(BUF *b, BUF *bb)
|
||||
WriteBuf(b, bb->Buf, bb->Size);
|
||||
}
|
||||
|
||||
// Write the buffer (from the offset) to a buffer
|
||||
void WriteBufBufWithOffset(BUF *b, BUF *bb)
|
||||
{
|
||||
// Validate arguments
|
||||
if (b == NULL || bb == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteBuf(b, ((UCHAR *)bb->Buf) + bb->Current, bb->Size - bb->Current);
|
||||
}
|
||||
|
||||
// Skip UTF-8 BOM
|
||||
bool BufSkipUtf8Bom(BUF *b)
|
||||
{
|
||||
if (b == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SeekBufToBegin(b);
|
||||
|
||||
if (b->Size >= 3)
|
||||
{
|
||||
UCHAR *data = b->Buf;
|
||||
|
||||
if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)
|
||||
{
|
||||
SeekBuf(b, 3, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read into a buffer from the buffer
|
||||
BUF *ReadBufFromBuf(BUF *b, UINT size)
|
||||
{
|
||||
|
@ -208,7 +208,9 @@ BUF *NewBufFromMemory(void *buf, UINT size);
|
||||
void ClearBuf(BUF *b);
|
||||
void WriteBuf(BUF *b, void *buf, UINT size);
|
||||
void WriteBufBuf(BUF *b, BUF *bb);
|
||||
void WriteBufBufWithOffset(BUF *b, BUF *bb);
|
||||
UINT ReadBuf(BUF *b, void *buf, UINT size);
|
||||
bool BufSkipUtf8Bom(BUF *b);
|
||||
BUF *ReadBufFromBuf(BUF *b, UINT size);
|
||||
void AdjustBufSize(BUF *b, UINT new_size);
|
||||
void SeekBuf(BUF *b, UINT offset, int mode);
|
||||
@ -357,5 +359,9 @@ void CleanupSharedBuffer(SHARED_BUFFER *b);
|
||||
void AppendBufUtf8(BUF *b, wchar_t *str);
|
||||
void AppendBufStr(BUF *b, char *str);
|
||||
|
||||
LIST *NewStrList();
|
||||
void ReleaseStrList(LIST *o);
|
||||
bool AddStrToStrListDistinct(LIST *o, char *str);
|
||||
|
||||
#endif // MEMORY_H
|
||||
|
||||
|
@ -7229,6 +7229,12 @@ bool IsIP4(IP *ip)
|
||||
return (IsIP6(ip) ? false : true);
|
||||
}
|
||||
|
||||
// Copy the IP address
|
||||
void CopyIP(IP *dst, IP *src)
|
||||
{
|
||||
Copy(dst, src, sizeof(IP));
|
||||
}
|
||||
|
||||
// Get the number of clients connected from the specified IP address
|
||||
UINT GetNumIpClient(IP *ip)
|
||||
{
|
||||
@ -11368,6 +11374,50 @@ void InitSockSet(SOCKSET *set)
|
||||
Zero(set, sizeof(SOCKSET));
|
||||
}
|
||||
|
||||
// Receive data and discard all of them
|
||||
bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure)
|
||||
{
|
||||
static UCHAR buffer[4096];
|
||||
UINT recv_size, sz, ret;
|
||||
if (sock == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (sock->AsyncMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
recv_size = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
sz = MIN(size - recv_size, sizeof(buffer));
|
||||
ret = Recv(sock, buffer, sz, secure);
|
||||
if (ret == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (ret == SOCK_LATER)
|
||||
{
|
||||
// I suppose that this is safe because the RecvAll() function is used only
|
||||
// if the sock->AsyncMode == true. And the Recv() function may return
|
||||
// SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
|
||||
// Recv() function in the RecvAll() function never returns SOCK_LATER.
|
||||
return false;
|
||||
}
|
||||
recv_size += ret;
|
||||
if (recv_size >= size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receive all by TCP
|
||||
bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
|
||||
{
|
||||
|
@ -953,6 +953,7 @@ UINT GetContentLength(HTTP_HEADER *header);
|
||||
void GetHttpDateStr(char *str, UINT size, UINT64 t);
|
||||
bool HttpSendForbidden(SOCK *s, char *target, char *server_id);
|
||||
bool HttpSendNotFound(SOCK *s, char *target);
|
||||
bool HttpSendBody(SOCK *s, void *data, UINT size, char *contents_type);
|
||||
bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version);
|
||||
bool HttpServerSend(SOCK *s, PACK *p);
|
||||
bool HttpClientSend(SOCK *s, PACK *p);
|
||||
@ -1193,6 +1194,7 @@ void SendAdd(SOCK *sock, void *data, UINT size);
|
||||
bool SendNow(SOCK *sock, int secure);
|
||||
bool RecvAll(SOCK *sock, void *data, UINT size, bool secure);
|
||||
bool RecvAllEx(SOCK *sock, void **data_new_ptr, UINT size, bool secure);
|
||||
bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure);
|
||||
void InitSockSet(SOCKSET *set);
|
||||
void AddSockSet(SOCKSET *set, SOCK *sock);
|
||||
CANCEL *NewCancel();
|
||||
@ -1308,6 +1310,7 @@ void SocketTimeoutThread(THREAD *t, void *param);
|
||||
SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock);
|
||||
void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp);
|
||||
|
||||
void CopyIP(IP *dst, IP *src);
|
||||
bool IsIP6(IP *ip);
|
||||
bool IsIP4(IP *ip);
|
||||
void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr);
|
||||
|
1006
src/Mayaqua/Pack.c
1006
src/Mayaqua/Pack.c
File diff suppressed because it is too large
Load Diff
@ -55,12 +55,38 @@ struct ELEMENT
|
||||
UINT num_value; // Number of values (>=1)
|
||||
UINT type; // Type
|
||||
VALUE **values; // List of pointers to the value
|
||||
bool JsonHint_IsArray;
|
||||
bool JsonHint_IsBool;
|
||||
bool JsonHint_IsDateTime;
|
||||
bool JsonHint_IsIP;
|
||||
char JsonHint_GroupName[MAX_ELEMENT_NAME_LEN + 1];
|
||||
};
|
||||
|
||||
// PACK object
|
||||
struct PACK
|
||||
{
|
||||
LIST *elements; // Element list
|
||||
LIST *json_subitem_names; // JSON sub-item names
|
||||
char CurrentJsonHint_GroupName[MAX_ELEMENT_NAME_LEN + 1];
|
||||
};
|
||||
|
||||
|
||||
#define MAX_JSONPACK_HINT_ITEMS 64
|
||||
#define JSONPACK_HINT_TYPE_ARRAY 1
|
||||
|
||||
// JSON/PACK converter hint element
|
||||
struct JSONPACKHINT_ITEM
|
||||
{
|
||||
UINT Type;
|
||||
char ArrayNumNameInPack[MAX_ELEMENT_NAME_LEN + 1];
|
||||
char ArrayMembersInPack[MAX_SIZE + 1];
|
||||
};
|
||||
|
||||
// JSON/PACK converter hint
|
||||
struct JSONPACKHINT
|
||||
{
|
||||
UINT NumHints;
|
||||
JSONPACKHINT_ITEM Hints[MAX_JSONPACK_HINT_ITEMS];
|
||||
};
|
||||
|
||||
|
||||
@ -100,21 +126,23 @@ TOKEN_LIST *GetPackElementNames(PACK *p);
|
||||
|
||||
X *PackGetX(PACK *p, char *name);
|
||||
K *PackGetK(PACK *p, char *name);
|
||||
void PackAddX(PACK *p, char *name, X *x);
|
||||
void PackAddK(PACK *p, char *name, K *k);
|
||||
void PackAddStr(PACK *p, char *name, char *str);
|
||||
void PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total);
|
||||
void PackAddUniStr(PACK *p, char *name, wchar_t *unistr);
|
||||
void PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total);
|
||||
void PackAddInt(PACK *p, char *name, UINT i);
|
||||
void PackAddNum(PACK *p, char *name, UINT num);
|
||||
void PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total);
|
||||
void PackAddInt64(PACK *p, char *name, UINT64 i);
|
||||
void PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total);
|
||||
void PackAddData(PACK *p, char *name, void *data, UINT size);
|
||||
void PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total);
|
||||
void PackAddBuf(PACK *p, char *name, BUF *b);
|
||||
void PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total);
|
||||
ELEMENT *PackAddX(PACK *p, char *name, X *x);
|
||||
ELEMENT *PackAddK(PACK *p, char *name, K *k);
|
||||
ELEMENT *PackAddStr(PACK *p, char *name, char *str);
|
||||
ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total);
|
||||
ELEMENT *PackAddUniStr(PACK *p, char *name, wchar_t *unistr);
|
||||
ELEMENT *PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total);
|
||||
ELEMENT *PackAddInt(PACK *p, char *name, UINT i);
|
||||
ELEMENT *PackAddNum(PACK *p, char *name, UINT num);
|
||||
ELEMENT *PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total);
|
||||
ELEMENT *PackAddInt64(PACK *p, char *name, UINT64 i);
|
||||
ELEMENT *PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total);
|
||||
ELEMENT *PackAddTime64(PACK *p, char *name, UINT64 i);
|
||||
ELEMENT *PackAddTime64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total);
|
||||
ELEMENT *PackAddData(PACK *p, char *name, void *data, UINT size);
|
||||
ELEMENT *PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total);
|
||||
ELEMENT *PackAddBuf(PACK *p, char *name, BUF *b);
|
||||
ELEMENT *PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total);
|
||||
bool PackGetStr(PACK *p, char *name, char *str, UINT size);
|
||||
bool PackGetStrEx(PACK *p, char *name, char *str, UINT size, UINT index);
|
||||
bool PackGetUniStr(PACK *p, char *name, wchar_t *unistr, UINT size);
|
||||
@ -133,23 +161,38 @@ bool PackGetDataEx(PACK *p, char *name, void *data, UINT index);
|
||||
BUF *PackGetBuf(PACK *p, char *name);
|
||||
BUF *PackGetBufEx(PACK *p, char *name, UINT index);
|
||||
bool PackGetBool(PACK *p, char *name);
|
||||
void PackAddBool(PACK *p, char *name, bool b);
|
||||
void PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total);
|
||||
ELEMENT *PackAddBool(PACK *p, char *name, bool b);
|
||||
ELEMENT *PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total);
|
||||
bool PackGetBoolEx(PACK *p, char *name, UINT index);
|
||||
void PackAddIp(PACK *p, char *name, IP *ip);
|
||||
void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total);
|
||||
void PackAddIpEx2(PACK *p, char *name, IP *ip, UINT index, UINT total, bool is_single);
|
||||
bool PackGetIp(PACK *p, char *name, IP *ip);
|
||||
bool PackGetIpEx(PACK *p, char *name, IP *ip, UINT index);
|
||||
UINT PackGetIp32(PACK *p, char *name);
|
||||
UINT PackGetIp32Ex(PACK *p, char *name, UINT index);
|
||||
void PackAddIp32(PACK *p, char *name, UINT ip32);
|
||||
void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total);
|
||||
void PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total);
|
||||
void PackAddIp32Ex2(PACK *p, char *name, UINT ip32, UINT index, UINT total, bool is_single);
|
||||
ELEMENT *PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total);
|
||||
bool PackGetIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index);
|
||||
void PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr);
|
||||
ELEMENT *PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr);
|
||||
bool PackGetIp6Addr(PACK *p, char *name, IPV6_ADDR *addr);
|
||||
bool PackGetData2(PACK *p, char *name, void *data, UINT size);
|
||||
bool PackGetDataEx2(PACK *p, char *name, void *data, UINT size, UINT index);
|
||||
bool PackIsValueExists(PACK *p, char *name);
|
||||
void PackSetCurrentJsonGroupName(PACK *p, char *json_group_name);
|
||||
ELEMENT *ElementNullSafe(ELEMENT *p);
|
||||
|
||||
JSON_VALUE *PackToJson(PACK *p);
|
||||
char *PackToJsonStr(PACK *p);
|
||||
|
||||
PACK *JsonToPack(JSON_VALUE *v);
|
||||
PACK *JsonStrToPack(char *str);
|
||||
|
||||
void PackArrayElementToJsonArray(JSON_ARRAY *ja, PACK *p, ELEMENT *e, UINT index);
|
||||
void PackElementToJsonObject(JSON_OBJECT *o, PACK *p, ELEMENT *e, UINT index);
|
||||
char *DetermineJsonSuffixForPackElement(ELEMENT *e);
|
||||
bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index, UINT total, bool is_single);
|
||||
|
||||
#endif // PACK_H
|
||||
|
2116
src/Mayaqua/Str.c
2116
src/Mayaqua/Str.c
File diff suppressed because it is too large
Load Diff
@ -79,7 +79,9 @@ void BinToStrW(wchar_t *str, UINT str_size, void *data, UINT data_size);
|
||||
void PrintBin(void *data, UINT size);
|
||||
bool StartWith(char *str, char *key);
|
||||
bool EndWith(char *str, char *key);
|
||||
bool TrimEndWith(char *dst, UINT dst_size, char *str, char *key);
|
||||
UINT64 ToInt64(char *str);
|
||||
UINT64 Json_ToInt64Ex(char *str, char **endptr, bool *error);
|
||||
void ToStr64(char *str, UINT64 value);
|
||||
TOKEN_LIST *ParseCmdLine(char *str);
|
||||
TOKEN_LIST *CopyToken(TOKEN_LIST *src);
|
||||
@ -128,6 +130,259 @@ LIST *StrToIntList(char *str, bool sorted);
|
||||
void NormalizeIntListStr(char *dst, UINT dst_size, char *src, bool sorted, char *separate_str);
|
||||
void ClearStr(char *str, UINT str_size);
|
||||
void SetStrCaseAccordingToBits(char *str, UINT bits);
|
||||
char *UrlDecode(char *url_str);
|
||||
|
||||
|
||||
// *** JSON strings support
|
||||
// Original source code from Parson ( http://kgabis.github.com/parson/ )
|
||||
// Modified by dnobori
|
||||
/*
|
||||
Parson ( http://kgabis.github.com/parson/ )
|
||||
Copyright (c) 2012 - 2017 Krzysztof Gabis
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
/* Type definitions */
|
||||
typedef union JSON_VALUE_UNION {
|
||||
char *string;
|
||||
UINT64 number;
|
||||
JSON_OBJECT *object;
|
||||
JSON_ARRAY *array;
|
||||
int boolean;
|
||||
int null;
|
||||
} JSON_VALUE_UNION;
|
||||
|
||||
struct JSON_VALUE {
|
||||
JSON_VALUE *parent;
|
||||
UINT type;
|
||||
JSON_VALUE_UNION value;
|
||||
};
|
||||
|
||||
struct JSON_OBJECT {
|
||||
JSON_VALUE *wrapping_value;
|
||||
char **names;
|
||||
JSON_VALUE **values;
|
||||
UINT count;
|
||||
UINT capacity;
|
||||
};
|
||||
|
||||
struct JSON_ARRAY {
|
||||
JSON_VALUE *wrapping_value;
|
||||
JSON_VALUE **items;
|
||||
UINT count;
|
||||
UINT capacity;
|
||||
};
|
||||
|
||||
|
||||
enum JSON_TYPES {
|
||||
JSON_TYPE_ERROR = -1,
|
||||
JSON_TYPE_NULL = 1,
|
||||
JSON_TYPE_STRING = 2,
|
||||
JSON_TYPE_NUMBER = 3,
|
||||
JSON_TYPE_OBJECT = 4,
|
||||
JSON_TYPE_ARRAY = 5,
|
||||
JSON_TYPE_BOOL = 6
|
||||
};
|
||||
typedef unsigned int UINT;
|
||||
|
||||
enum JSON_RETS {
|
||||
JSON_RET_OK = 0,
|
||||
JSON_RET_ERROR = -1
|
||||
};
|
||||
|
||||
typedef void * (*JSON_Malloc_Function)(UINT);
|
||||
typedef void(*JSON_Free_Function)(void *);
|
||||
|
||||
/* Call only once, before calling any other function from parson API. If not called, malloc and free
|
||||
from stdlib will be used for all allocations */
|
||||
void JsonSetAllocationFunctions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun);
|
||||
|
||||
/* Parses first JSON value in a string, returns NULL in case of error */
|
||||
JSON_VALUE * JsonParseString(char *string);
|
||||
|
||||
/* Parses first JSON value in a string and ignores comments (/ * * / and //),
|
||||
returns NULL in case of error */
|
||||
JSON_VALUE * JsonParseStringWithComments(char *string);
|
||||
|
||||
/* Serialization */
|
||||
UINT JsonGetSerializationSize(JSON_VALUE *value); /* returns 0 on fail */
|
||||
UINT JsonSerializeToBuffer(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes);
|
||||
char * JsonSerializeToString(JSON_VALUE *value);
|
||||
|
||||
/* Pretty serialization */
|
||||
UINT JsonGetSerializationSizePretty(JSON_VALUE *value); /* returns 0 on fail */
|
||||
UINT JsonSerializeToBufferPretty(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes);
|
||||
char * JsonSerializeToStringPretty(JSON_VALUE *value);
|
||||
char *JsonToStr(JSON_VALUE *v);
|
||||
|
||||
void JsonFreeString(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
|
||||
|
||||
/* Comparing */
|
||||
int JsonCmp(JSON_VALUE *a, JSON_VALUE *b);
|
||||
|
||||
/* Validation
|
||||
This is *NOT* JSON Schema. It validates json by checking if object have identically
|
||||
named fields with matching types.
|
||||
For example schema {"name":"", "age":0} will validate
|
||||
{"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"},
|
||||
but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}.
|
||||
In case of arrays, only first value in schema is checked against all values in tested array.
|
||||
Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays,
|
||||
null validates values of every type.
|
||||
*/
|
||||
UINT JsonValidate(JSON_VALUE *schema, JSON_VALUE *value);
|
||||
|
||||
/*
|
||||
* JSON Object
|
||||
*/
|
||||
JSON_VALUE * JsonGet(JSON_OBJECT *object, char *name);
|
||||
char * JsonGetStr(JSON_OBJECT *object, char *name);
|
||||
JSON_OBJECT * JsonGetObj(JSON_OBJECT *object, char *name);
|
||||
JSON_ARRAY * JsonGetArray(JSON_OBJECT *object, char *name);
|
||||
UINT64 JsonGetNumber(JSON_OBJECT *object, char *name); /* returns 0 on fail */
|
||||
bool JsonGetBool(JSON_OBJECT *object, char *name); /* returns 0 on fail */
|
||||
|
||||
/* dotget functions enable addressing values with dot notation in nested objects,
|
||||
just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
|
||||
Because valid names in JSON can contain dots, some values may be inaccessible
|
||||
this way. */
|
||||
JSON_VALUE * JsonDotGet(JSON_OBJECT *object, char *name);
|
||||
char * JsonDotGetStr(JSON_OBJECT *object, char *name);
|
||||
JSON_OBJECT * JsonDotGetObj(JSON_OBJECT *object, char *name);
|
||||
JSON_ARRAY * JsonDotGetArray(JSON_OBJECT *object, char *name);
|
||||
UINT64 JsonDotGetNumber(JSON_OBJECT *object, char *name); /* returns 0 on fail */
|
||||
bool JsonDotGetBool(JSON_OBJECT *object, char *name); /* returns -1 on fail */
|
||||
|
||||
/* Functions to get available names */
|
||||
UINT JsonGetCount(JSON_OBJECT *object);
|
||||
char * JsonGetName(JSON_OBJECT *object, UINT index);
|
||||
JSON_VALUE * JsonGetValueAt(JSON_OBJECT *object, UINT index);
|
||||
JSON_VALUE * JsonGetWrappingValue(JSON_OBJECT *object);
|
||||
|
||||
/* Functions to check if object has a value with a specific name. Returned value is 1 if object has
|
||||
* a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */
|
||||
int JsonIsExists(JSON_OBJECT *object, char *name);
|
||||
int JsonIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type);
|
||||
|
||||
int JsonDotIsExists(JSON_OBJECT *object, char *name);
|
||||
int JsonDotIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type);
|
||||
|
||||
/* Creates new name-value pair or frees and replaces old value with a new one.
|
||||
* json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
UINT JsonSet(JSON_OBJECT *object, char *name, JSON_VALUE *value);
|
||||
UINT JsonSetStr(JSON_OBJECT *object, char *name, char *string);
|
||||
UINT JsonSetUniStr(JSON_OBJECT *object, char *name, wchar_t *string);
|
||||
UINT JsonSetNumber(JSON_OBJECT *object, char *name, UINT64 number);
|
||||
UINT JsonSetBool(JSON_OBJECT *object, char *name, int boolean);
|
||||
UINT JsonSetNull(JSON_OBJECT *object, char *name);
|
||||
UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size);
|
||||
|
||||
/* Works like dotget functions, but creates whole hierarchy if necessary.
|
||||
* json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
UINT JsonDotSet(JSON_OBJECT *object, char *name, JSON_VALUE *value);
|
||||
UINT JsonDotSetStr(JSON_OBJECT *object, char *name, char *string);
|
||||
UINT JsonDotSetNumber(JSON_OBJECT *object, char *name, UINT64 number);
|
||||
UINT JsonDotSetBool(JSON_OBJECT *object, char *name, int boolean);
|
||||
UINT JsonDotSetNull(JSON_OBJECT *object, char *name);
|
||||
|
||||
/* Frees and removes name-value pair */
|
||||
UINT JsonDelete(JSON_OBJECT *object, char *name);
|
||||
|
||||
/* Works like dotget function, but removes name-value pair only on exact match. */
|
||||
UINT JsonDotDelete(JSON_OBJECT *object, char *key);
|
||||
|
||||
/* Removes all name-value pairs in object */
|
||||
UINT JsonDeleteAll(JSON_OBJECT *object);
|
||||
|
||||
/*
|
||||
*JSON Array
|
||||
*/
|
||||
JSON_VALUE * JsonArrayGet(JSON_ARRAY *array, UINT index);
|
||||
char * JsonArrayGetStr(JSON_ARRAY *array, UINT index);
|
||||
JSON_OBJECT * JsonArrayGetObj(JSON_ARRAY *array, UINT index);
|
||||
JSON_ARRAY * JsonArrayGetArray(JSON_ARRAY *array, UINT index);
|
||||
UINT64 JsonArrayGetNumber(JSON_ARRAY *array, UINT index); /* returns 0 on fail */
|
||||
bool JsonArrayGetBool(JSON_ARRAY *array, UINT index); /* returns 0 on fail */
|
||||
UINT JsonArrayGetCount(JSON_ARRAY *array);
|
||||
JSON_VALUE * JsonArrayGetWrappingValue(JSON_ARRAY *array);
|
||||
|
||||
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
|
||||
* Order of values in array may change during execution. */
|
||||
UINT JsonArrayDelete(JSON_ARRAY *array, UINT i);
|
||||
|
||||
/* Frees and removes from array value at given index and replaces it with given one.
|
||||
* Does nothing and returns JSONFailure if index doesn't exist.
|
||||
* json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
UINT JsonArrayReplace(JSON_ARRAY *array, UINT i, JSON_VALUE *value);
|
||||
UINT JsonArrayReplaceStr(JSON_ARRAY *array, UINT i, char* string);
|
||||
UINT JsonArrayReplaceNumber(JSON_ARRAY *array, UINT i, UINT64 number);
|
||||
UINT JsonArrayReplaceBool(JSON_ARRAY *array, UINT i, int boolean);
|
||||
UINT JsonArrayReplaceNull(JSON_ARRAY *array, UINT i);
|
||||
|
||||
/* Frees and removes all values from array */
|
||||
UINT JsonArrayDeleteAll(JSON_ARRAY *array);
|
||||
|
||||
/* Appends new value at the end of array.
|
||||
* json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||
UINT JsonArrayAdd(JSON_ARRAY *array, JSON_VALUE *value);
|
||||
UINT JsonArrayAddStr(JSON_ARRAY *array, char *string);
|
||||
UINT JsonArrayAddUniStr(JSON_ARRAY *array, wchar_t *string);
|
||||
UINT JsonArrayAddNumber(JSON_ARRAY *array, UINT64 number);
|
||||
UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size);
|
||||
UINT JsonArrayAddBool(JSON_ARRAY *array, int boolean);
|
||||
UINT JsonArrayAddNull(JSON_ARRAY *array);
|
||||
|
||||
|
||||
/*
|
||||
*JSON Value
|
||||
*/
|
||||
JSON_VALUE * JsonNewObject(void);
|
||||
JSON_VALUE * JsonNewArray(void);
|
||||
JSON_VALUE * JsonNewStr(char *string); /* copies passed string */
|
||||
JSON_VALUE * JsonNewNumber(UINT64 number);
|
||||
JSON_VALUE * JsonNewBool(int boolean);
|
||||
JSON_VALUE * JsonNewNull(void);
|
||||
JSON_VALUE * JsonDeepCopy(JSON_VALUE *value);
|
||||
void JsonFree(JSON_VALUE *value);
|
||||
|
||||
UINT JsonValueGetType(JSON_VALUE *value);
|
||||
JSON_OBJECT * JsonValueGetObject(JSON_VALUE *value);
|
||||
JSON_ARRAY * JsonValueGetArray(JSON_VALUE *value);
|
||||
char * JsonValueGetStr(JSON_VALUE *value);
|
||||
UINT64 JsonValueGetNumber(JSON_VALUE *value);
|
||||
bool JsonValueGetBool(JSON_VALUE *value);
|
||||
JSON_VALUE * JsonValueGetParent(JSON_VALUE *value);
|
||||
|
||||
/* Same as above, but shorter */
|
||||
UINT JsonType(JSON_VALUE *value);
|
||||
JSON_OBJECT * JsonObject(JSON_VALUE *value);
|
||||
JSON_ARRAY * JsonArray(JSON_VALUE *value);
|
||||
char * JsonString(JSON_VALUE *value);
|
||||
UINT64 JsonNumber(JSON_VALUE *value);
|
||||
int JsonBool(JSON_VALUE *value);
|
||||
|
||||
void SystemTimeToJsonStr(char *dst, UINT size, SYSTEMTIME *t);
|
||||
void SystemTime64ToJsonStr(char *dst, UINT size, UINT64 t);
|
||||
|
||||
JSON_VALUE *StrToJson(char *str);
|
||||
|
||||
#endif // STR_H
|
||||
|
||||
|
Reference in New Issue
Block a user