aboutsummaryrefslogtreecommitdiff
path: root/project/dclib
diff options
context:
space:
mode:
Diffstat (limited to 'project/dclib')
-rw-r--r--project/dclib/dclib-basics.c65
-rw-r--r--project/dclib/dclib-basics.h136
-rw-r--r--project/dclib/dclib-file.c182
-rw-r--r--project/dclib/dclib-network.c4
-rw-r--r--project/dclib/dclib-numeric.c146
5 files changed, 300 insertions, 233 deletions
diff --git a/project/dclib/dclib-basics.c b/project/dclib/dclib-basics.c
index 1aab8cb..4a166df 100644
--- a/project/dclib/dclib-basics.c
+++ b/project/dclib/dclib-basics.c
@@ -2338,11 +2338,13 @@ void MoveMemList ( mem_list_t *dest, mem_list_t *src )
///////////////////////////////////////////////////////////////////////////////
-void GrowBufMemList ( mem_list_t *ml, uint need_size )
+void NeedBufMemList ( mem_list_t *ml, uint need_size, uint extra_size )
{
+ need_size += ml->buf_used;
if ( ml->buf_size < need_size )
{
- PRINT("MEM-LIST: MALLOC/BUF(%u)\n",need_size);
+ need_size = GetGoodAllocSize(need_size+extra_size);
+ PRINT("MEM-LIST: MALLOC/BUF(%u/%u>%u)\n",ml->buf_used,ml->buf_size,need_size);
char *new_buf = MALLOC(need_size);
//--- copy existing strings
@@ -2351,34 +2353,35 @@ void GrowBufMemList ( mem_list_t *ml, uint need_size )
mem_t *dest = ml->list;
uint i;
for ( i = 0; i < ml->used; i++, dest++ )
- if ( dest->len )
+ if (dest->len)
{
memcpy(bufptr,dest->ptr,dest->len);
dest->ptr = bufptr;
bufptr += dest->len;
*bufptr++ = 0;
DASSERT( bufptr <= new_buf + need_size );
- noPRINT("OLD: %p,%u\n",dest->ptr,dest->len);
}
FREE(ml->buf);
- ml->buf = new_buf;
+ ml->buf = new_buf;
ml->buf_used = bufptr - new_buf;
+ ml->buf_size = need_size;
}
}
///////////////////////////////////////////////////////////////////////////////
-void PrepareMemList ( mem_list_t *ml, uint n_elem, uint buf_size )
+void NeedElemMemList ( mem_list_t *ml, uint need_elem, uint need_size )
{
DASSERT(ml);
- if ( ml->size < n_elem )
+ need_elem += ml->used;
+ if ( ml->size < need_elem )
{
- ml->size = n_elem;
+ ml->size = GetGoodAllocSize2(need_elem,sizeof(*ml->list));
PRINT("MEM-LIST: REALLOC/LIST(%u)\n",ml->size);
ml->list = REALLOC(ml->list,sizeof(*ml->list)*ml->size);
}
- GrowBufMemList(ml,buf_size);
+ NeedBufMemList(ml,need_size,0);
}
///////////////////////////////////////////////////////////////////////////////
@@ -2390,10 +2393,7 @@ void InsertMemListN
int pos, // insert position => CheckIndex1()
const mem_t *src, // source list
uint src_len, // number of elements in source list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
DASSERT(ml);
@@ -2411,8 +2411,13 @@ void InsertMemListN
need_size += sptr->len + 1; // always terminate with NULL
add_elem++;
}
- else if ( !src_ignore || src_ignore == 1 && sptr->ptr || src_ignore == 3 )
+ else if ( src_ignore == MEMLM_ALL
+ || src_ignore == MEMLM_IGN_NULL && sptr->ptr
+ || src_ignore == MEMLM_REPL_NULL
+ )
+ {
add_elem++;
+ }
}
if (!add_elem)
@@ -2436,8 +2441,8 @@ void InsertMemListN
need_size += ml->buf_used + 20;
need_size += need_size/10;
- // don't use GrowBufMemList() here, because the old buffer is needed
- // BUT: char old_buf = ml->buf; ml->buf = 0; GrowBufMemList(ml,need_size)
+ // don't use NeedBufMemList() here, because the old buffer is needed
+ // BUT POSSIBLE: char old_buf = ml->buf; ml->buf = 0; GrowBufMemList(ml,need_size)
PRINT("MEM-LIST: MALLOC/BUF(%u)\n",need_size);
bufptr = new_buf = MALLOC(need_size);
@@ -2492,14 +2497,14 @@ void InsertMemListN
dest++;
DASSERT( dest <= ml->list + ml->used );
}
- else if ( !src_ignore || src_ignore == 1 && sptr->ptr )
+ else if ( src_ignore == MEMLM_ALL || src_ignore == MEMLM_IGN_NULL && sptr->ptr )
{
dest->ptr = sptr->ptr ? EmptyString : NULL;
dest->len = 0;
dest++;
DASSERT( dest <= ml->list + ml->used );
}
- else if ( src_ignore == 3 )
+ else if ( src_ignore == MEMLM_REPL_NULL )
{
dest->ptr = EmptyString;
dest->len = 0;
@@ -2533,10 +2538,7 @@ void CatMemListN
mem_list_t *dest, // valid destination mem_list
const mem_list_t **src_list, // list with mem lists, element may be NULL
uint n_src_list, // number of elements in 'src'
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
DASSERT(dest);
@@ -2565,8 +2567,13 @@ void CatMemListN
need_size += sptr->len + 1; // always terminate with NULL
need_elem++;
}
- else if ( !src_ignore || src_ignore == 1 && sptr->ptr || src_ignore == 3 )
+ else if ( src_ignore == MEMLM_ALL
+ || src_ignore == MEMLM_IGN_NULL && sptr->ptr
+ || src_ignore == MEMLM_REPL_NULL
+ )
+ {
need_elem++;
+ }
}
}
@@ -2613,14 +2620,14 @@ void CatMemListN
listptr++;
DASSERT( listptr <= new_list + need_elem );
}
- else if ( !src_ignore || src_ignore == 1 && sptr->ptr )
+ else if ( src_ignore == MEMLM_ALL || src_ignore == MEMLM_IGN_NULL && sptr->ptr )
{
listptr->ptr = sptr->ptr ? EmptyString : NULL;
listptr->len = 0;
listptr++;
DASSERT( listptr <= new_list + need_elem );
}
- else if ( src_ignore == 3 )
+ else if ( src_ignore == MEMLM_REPL_NULL )
{
listptr->ptr = EmptyString;
listptr->len = 0;
@@ -3609,10 +3616,11 @@ uint SplitByCharMemList
if (init_ml)
InitializeMemList(ml);
ml->used = 0;
+ ml->buf_used = 0;
+ NeedBufMemList(ml,source.len+1,0);
if ( max_fields <= 0 )
max_fields = INT_MAX;
- GrowBufMemList(ml,source.len+1);
ccp src = source.ptr;
ccp end = src + source.len;
@@ -3654,10 +3662,11 @@ uint SplitByTextMemList
if (init_ml)
InitializeMemList(ml);
ml->used = 0;
+ ml->buf_used = 0;
+ NeedBufMemList(ml,source.len+1,0);
if ( max_fields <= 0 )
max_fields = INT_MAX;
- GrowBufMemList(ml,source.len+1);
ccp src = source.ptr;
ccp end = src + source.len;
@@ -5907,7 +5916,7 @@ void RestoreStateStringField
ParamFieldItem_t *pfi = GetParamField(rs,name);
if (pfi)
{
- mem_t mem = DecodeByModeMem(0,0,pfi->data,-1,emode);
+ mem_t mem = DecodeByModeMem(0,0,pfi->data,-1,emode,0);
AppendStringField(sf,mem.ptr,true);
}
}
diff --git a/project/dclib/dclib-basics.h b/project/dclib/dclib-basics.h
index 498191e..96053d6 100644
--- a/project/dclib/dclib-basics.h
+++ b/project/dclib/dclib-basics.h
@@ -774,7 +774,7 @@ typedef struct mem_list_t
{
mem_t *list; // List of mem_t objects.
// Elements are always terminated with NULL.
- // Content is stored in 'buf' or points to EmptyString.
+ // Content is NULL or EmptyString or stored in 'buf'
uint used; // Number of active 'list' elements
uint size; // Number of alloced 'list' elements
@@ -786,13 +786,25 @@ typedef struct mem_list_t
mem_list_t;
//-----------------------------------------------------------------------------
+// [[mem_list_mode_t]]
+
+typedef enum mem_list_mode_t
+{
+ MEMLM_ALL, // insert all
+ MEMLM_IGN_NULL, // ignore NULL
+ MEMLM_IGN_EMPTY, // ignore NULL and empty
+ MEMLM_REPL_NULL, // replace NULL by EmptyString
+}
+mem_list_mode_t;
+
+//-----------------------------------------------------------------------------
void InitializeMemList ( mem_list_t *ml );
void ResetMemList ( mem_list_t *ml );
void MoveMemList ( mem_list_t *dest, mem_list_t *src );
-void GrowBufMemList ( mem_list_t *ml, uint need_size );
-void PrepareMemList ( mem_list_t *ml, uint n_elem, uint buf_size );
+void NeedBufMemList ( mem_list_t *ml, uint need_size, uint extra_size );
+void NeedElemMemList ( mem_list_t *ml, uint n_elem, uint need_size );
//-----------------------------------------------------------------------------
@@ -802,10 +814,7 @@ void InsertMemListN
int pos, // insert position => CheckIndex1()
const mem_t *src, // source list
uint src_len, // number of elements in source list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
);
//-----------------------------------------------------------------------------
@@ -815,10 +824,7 @@ static inline void InsertMemList2
mem_list_t *ml, // valid destination mem_list
int pos, // insert position => CheckIndex1()
const mem_list_t *src, // source mem_list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
DASSERT(src);
@@ -832,10 +838,7 @@ static inline void AppendMemListN
mem_list_t *ml, // valid destination mem_list
const mem_t *src, // source list
uint src_len, // number of elements in source list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
DASSERT(ml);
@@ -848,10 +851,7 @@ static inline void AppendMemList2
(
mem_list_t *ml, // valid destination mem_list
const mem_list_t *src, // source mem_list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
DASSERT(ml);
@@ -866,10 +866,7 @@ static inline void AssignMemListN
mem_list_t *ml, // valid destination mem_list
const mem_t *src, // source list
uint src_len, // number of elements in source list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
DASSERT(ml);
@@ -883,10 +880,7 @@ static inline void AssignMemList2
(
mem_list_t *ml, // valid destination mem_list
const mem_list_t *src, // source mem_list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
DASSERT(ml);
@@ -902,10 +896,7 @@ void CatMemListN
mem_list_t *dest, // valid destination mem_list
const mem_list_t **src_list, // list with mem lists, element may be NULL
uint n_src_list, // number of elements in 'src'
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
);
//-----------------------------------------------------------------------------
@@ -915,10 +906,7 @@ static inline void CatMemList2
mem_list_t *dest, // valid destination mem_list
const mem_list_t *src1, // source mem_list
const mem_list_t *src2, // source mem_list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
const mem_list_t *ml[2] = { src1, src2 };
@@ -933,10 +921,7 @@ static inline void CatMemList3
const mem_list_t *src1, // source mem_list
const mem_list_t *src2, // source mem_list
const mem_list_t *src3, // source mem_list
- uint src_ignore // 0: insert all
- // 1: ignore NULL
- // 2: ignore NULL and empty
- // 3: replace NULL by EmptyString
+ mem_list_mode_t src_ignore // how to manage NULL and empty strings
)
{
const mem_list_t *ml[3] = { src1, src2, src3 };
@@ -2137,7 +2122,9 @@ EncodeMode_t;
// [[doxygen]]
static inline bool NeedsQuotesByEncoding ( EncodeMode_t em )
- { return em < ENCODE_BASE64 || em > ENCODE_BASE64XML; }
+ { return em > ENCODE_OFF && em < ENCODE_BASE64 || em > ENCODE_BASE64XML; }
+
+ccp GetEncodingName ( EncodeMode_t em );
///////////////////////////////////////////////////////////////////////////////
// [[DecodeType_t]]
@@ -2299,14 +2286,15 @@ static inline uint DecodeJSON
(
// returns the number of valid bytes in 'buf'
- char *buf, // valid destination buffer
- uint buf_size, // size of 'buf', >= 3
- ccp source, // NULL or string to decode
- int source_len, // length of 'source'. If -1, str is NULL terminated
- uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
+ char *buf, // valid destination buffer
+ uint buf_size, // size of 'buf', >= 3
+ ccp source, // NULL or string to decode
+ int source_len, // length of 'source'. If -1, str is NULL terminated
+ int quote, // 0:none, -1:auto, >0: quotation char
+ uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
)
{
- return ScanEscapedString(buf,buf_size,source,source_len,true,0,scanned_len);
+ return ScanEscapedString(buf,buf_size,source,source_len,true,quote,scanned_len);
}
//-----------------------------------------------------------------------------
@@ -2317,8 +2305,9 @@ mem_t DecodeJSONCirc
// with valid pointer and null terminated.
// If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
- ccp source, // NULL or string to decode
- int source_len // length of 'source'. If -1, str is NULL terminated
+ ccp source, // NULL or string to decode
+ int source_len, // length of 'source'. If -1, str is NULL terminated
+ int quote // 0:none, -1:auto, >0: quotation char
);
///////////////////////////////////////////////////////////////////////////////
@@ -2372,34 +2361,51 @@ uint DecodeByMode
uint buf_size, // size of 'buf', >= 3
ccp source, // string to decode
int slen, // length of string. if -1, str is null terminated
- EncodeMode_t emode // encoding mode
+ EncodeMode_t emode, // encoding mode
+ uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
);
///////////////////////////////////////////////////////////////////////////////
-uint EncodeByMode
+mem_t DecodeByModeMem
(
- // returns the number of valid bytes in 'buf'. Result is NULL-terminated.
+ // Returns the decoded 'source'. Result is NULL-terminated.
+ // It points either to 'buf' or is alloced (on buf==NULL or too less space)
+ // If alloced (mem.ptr!=buf) => call FreeMem(&mem)
- char *buf, // valid destination buffer
- uint buf_size, // size of 'buf', >= 4
- ccp source, // string to encode
+ char *buf, // NULL or destination buffer
+ uint buf_size, // size of 'buf'
+ ccp source, // string to decode
int slen, // length of string. if -1, str is null terminated
- EncodeMode_t emode // encoding mode
+ EncodeMode_t emode, // encoding mode
+ uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
);
///////////////////////////////////////////////////////////////////////////////
-mem_t DecodeByModeMem
+uint DecodeByModeMemList
(
- // Returns the decoded 'source'. Result is NULL-terminated.
- // It points either to 'buf' or is alloced (on buf==NULL or to less space)
- // If alloced (mem.ptr!=buf) => call FreeMem(&mem)
+ // returns the number of scanned strings
- char *buf, // NULL or destination buffer
- uint buf_size, // size of 'buf'
+ mem_list_t *res, // result
+ uint res_mode, // 0:append, 1:clear, 2:init
ccp source, // string to decode
int slen, // length of string. if -1, str is null terminated
+ EncodeMode_t emode, // encoding mode
+ uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
+);
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+uint EncodeByMode
+(
+ // returns the number of valid bytes in 'buf'. Result is NULL-terminated.
+
+ char *buf, // valid destination buffer
+ uint buf_size, // size of 'buf', >= 4
+ ccp source, // string to encode
+ int slen, // length of string. if -1, str is null terminated
EncodeMode_t emode // encoding mode
);
@@ -2408,7 +2414,7 @@ mem_t DecodeByModeMem
mem_t EncodeByModeMem
(
// Returns the encoded 'source'. Result is NULL-terminated.
- // It points either to 'buf' or is alloced (on buf==NULL or to less space)
+ // It points either to 'buf' or is alloced (on buf==NULL or too less space)
// If alloced (mem.ptr!=buf) => call FreeMem(&mem)
char *buf, // NULL or destination buffer
@@ -4824,7 +4830,7 @@ int GetParamFieldBUF
mem_t GetParamFieldMEM
(
// Returns the decoded 'source'. Result is NULL-terminated.
- // It points either to 'buf' or is alloced (on buf==NULL or to less space)
+ // It points either to 'buf' or is alloced (on buf==NULL or too less space)
// If alloced (mem.ptr!=buf) => call FreeMem(&mem)
char *buf, // buffer to store result
@@ -4910,11 +4916,9 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_FLOAT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_FLOAT,0)
#define DEF_SRT_XFLOAT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_XFLOAT,0)
-#if defined(TEST) || defined(DEBUG)
#define DEF_SRT_STR_SIZE_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_STRING_SIZE,e)
#define DEF_SRT_STR_ALLOC_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_STRING_ALLOC,e)
#define DEF_SRT_MEM_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_MEM,e)
-#endif
//--- auto array
@@ -4929,11 +4933,9 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_FLOAT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_FLOAT,0)
#define DEF_SRT_XFLOAT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_XFLOAT,0)
-#if defined(TEST) || defined(DEBUG)
#define DEF_SRT_STR_SIZE_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_STRING_SIZE,e)
#define DEF_SRT_STR_ALLOC_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_STRING_ALLOC,e)
#define DEF_SRT_MEM_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_MEM,e)
-#endif
//--- special
diff --git a/project/dclib/dclib-file.c b/project/dclib/dclib-file.c
index eb4f9ea..0cd2478 100644
--- a/project/dclib/dclib-file.c
+++ b/project/dclib/dclib-file.c
@@ -4414,7 +4414,7 @@ int GetParamFieldBUF
if (!it)
return not_found ? StringCopyS(buf,buf_size,not_found) - buf : -1;
- return DecodeByMode(buf,buf_size,(ccp)it->data,-1,decode);
+ return DecodeByMode(buf,buf_size,(ccp)it->data,-1,decode,0);
}
///////////////////////////////////////////////////////////////////////////////
@@ -4422,7 +4422,7 @@ int GetParamFieldBUF
mem_t GetParamFieldMEM
(
// Returns the decoded 'source'. Result is NULL-terminated.
- // It points either to 'buf' or is alloced (on buf==NULL or to less space)
+ // It points either to 'buf' or is alloced (on buf==NULL or too less space)
// If alloced (mem.ptr!=buf) => call FreeMem(&mem)
char *buf, // buffer to store result
@@ -4440,7 +4440,7 @@ mem_t GetParamFieldMEM
ParamFieldItem_t *it = GetParamField(rs,name);
return it
- ? DecodeByModeMem(buf,buf_size,(ccp)it->data,-1,decode)
+ ? DecodeByModeMem(buf,buf_size,(ccp)it->data,-1,decode,0)
: not_found;
}
@@ -4505,7 +4505,6 @@ static void print_scs_name ( FILE *f, int fw, int use_tab, ccp format, ... )
static u64 SCS_get_uint ( const u8* data, int idx, const SaveRestoreTab_t *srt )
{
DASSERT(srt);
- DASSERT(srt->var);
switch(srt->size)
{
@@ -4522,7 +4521,6 @@ static u64 SCS_get_uint ( const u8* data, int idx, const SaveRestoreTab_t *srt )
static s64 SCS_get_int ( const u8* data, int idx, const SaveRestoreTab_t *srt )
{
DASSERT(srt);
- DASSERT(srt->var);
switch(srt->size)
{
@@ -4538,13 +4536,26 @@ static s64 SCS_get_int ( const u8* data, int idx, const SaveRestoreTab_t *srt )
static void SCS_save_string ( FILE *f, ccp src, int slen, EncodeMode_t emode )
{
- char buf[4000];
- mem_t res = EncodeByModeMem(buf,sizeof(buf),src,slen,emode);
+ if (!src)
+ fputc('%',f);
+ else
+ {
+ char buf[4000];
+ mem_t res = EncodeByModeMem(buf,sizeof(buf),src,slen,emode);
+
+ if (res.len)
+ {
+ const bool quote = NeedsQuotesByEncoding(emode);
+ if (quote)
+ fputc('"',f);
+ fwrite(res.ptr,1,res.len,f);
+ if (quote)
+ fputc('"',f);
+ }
- fwrite(res.ptr,1,res.len,f);
- fputc('\n',f);
- if ( res.ptr != buf )
- FreeMem(&res);
+ if ( res.ptr != buf )
+ FreeMem(&res);
+ }
}
//-----------------------------------------------------------------------------
@@ -4592,9 +4603,6 @@ void SaveCurrentStateByTable
}
const int use_tab = (fw_name&7) ? 0 : (fw_name/8)*8+7;
-
- //-------------------------------------------------------------------------
-
const u8 *data = data0;
for ( ; srt->type != SRT__TERM; srt++ )
@@ -4779,6 +4787,7 @@ void SaveCurrentStateByTable
{
print_scs_name(f,fw_name,use_tab,"%s%s@%u",prefix,srt->name,i);
SCS_save_string(f,*ptr,-1,srt->emode);
+ fputc('\n',f);
}
break;
}
@@ -4796,6 +4805,7 @@ void SaveCurrentStateByTable
print_scs_name(f,fw_name,use_tab,"%s%s@%u",prefix,srt->name,i);
fprintf(f,"%d ",ptr->num);
SCS_save_string(f,ptr->key,-1,srt->emode);
+ fputc('\n',f);
}
break;
}
@@ -4806,13 +4816,6 @@ void SaveCurrentStateByTable
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-#if defined(TEST) && 1
- #define X_DEVELOP 1
-#else
- #define X_DEVELOP 0
-#endif
-
-
void RestoreStateByTable
(
RestoreState_t *rs, // info data, can be modified (cleaned after call)
@@ -4824,72 +4827,7 @@ void RestoreStateByTable
DASSERT(rs);
DASSERT(srt);
- //-------------------------------------------------------------------------
-
-#if X_DEVELOP
-
- mem_t get_string
- ( mem_t *param, ccp *p_ptr, char *buf, uint bufsize, EncodeMode_t emode )
- {
- DASSERT(param);
- DASSERT(p_ptr);
-
- ccp ptr;
- if (!*p_ptr)
- ptr = param->ptr;
- else
- {
- ptr = *p_ptr;
- if ( *ptr != ',' )
- return NullMem;
- ptr++;
- }
-
- if ( *ptr == '%' )
- {
- *p_ptr = ptr;
- return NullMem;
- }
-
- uint len;
- ccp start, end = param->ptr + param->len;
- if ( *ptr == '"' )
- {
- start = ++ptr;
- for (;;)
- {
- if ( ptr == end )
- {
- len = ptr - start;
- break;
- }
-
- const char ch = *ptr++;
- if ( ch == '\\' && ptr < end )
- ptr++;
- else if ( ch == '"' )
- {
- len = ptr-start-1;
- break;
- }
- }
- }
- else
- {
- start = ptr;
- while ( ptr < end && *ptr != ',' )
- ptr++;
- len = ptr - start;
- }
-
- *p_ptr = ptr;
- return MemByStringS(start,len);
- }
-#endif
-
- //-------------------------------------------------------------------------
-
- char buf[4000];
+ char buf[4000]; // ???
if (!prefix)
prefix = EmptyString;
@@ -4993,59 +4931,63 @@ void RestoreStateByTable
//-----
case SRT_STRING_SIZE:
-#if X_DEVELOP
{
ParamFieldItem_t *it = GetParamField(rs,buf);
- mem_t param = it ? MemByString((ccp)it->data) : EmptyMem;
- PRINT1("param: [%u] |%.*s|\n",param.len,param.len,param.ptr);
- ccp ptr = 0;
- uint i;
- for ( i = 0; i < srt->n_elem; i++ )
- {
- mem_t str = get_string(&param,&ptr,buf,sizeof(buf),srt->emode);
- PRINT1("str: [%d,%u] |%.*s|\n",str.ptr!=0,str.len,str.len,str.ptr);
- //if ( str.ptr != buf ) FreeMem(&str);
- }
- break;
- }
-#else
- {
+ mem_list_t ml;
+ DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
+
char *val = (char*)(data+srt->offset);
- mem_t res = GetParamFieldMEM(buf,sizeof(buf),rs,buf,
- srt->emode,MemByString(val));
- StringCopyS(val,srt->size,res.ptr);
- if ( res.ptr != buf && res.ptr != val )
- FreeString(res.ptr);
+ uint i;
+ for ( i = 0; i < srt->n_elem; i++, val += srt->size )
+ StringCopyS( val, srt->size, i<ml.used ? ml.list[i].ptr : 0 );
+ ResetMemList(&ml);
break;
}
-#endif
case SRT_STRING_ALLOC:
{
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ mem_list_t ml;
+ DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
+
ccp *val = (ccp*)(data+srt->offset);
- mem_t res = GetParamFieldMEM(buf,sizeof(buf),rs,buf,
- srt->emode,MemByString0(*val));
- if ( res.ptr != *val )
+ uint i;
+ for ( i = 0; i < srt->n_elem; i++, val++ )
{
FreeString(*val);
- *val = MEMDUP(res.ptr,res.len);
+ *val = 0;
+ if ( i < ml.used )
+ {
+ mem_t *m = ml.list+i;
+ if ( m->ptr )
+ *val = m->ptr == EmptyString ? EmptyString : MEMDUP(m->ptr,m->len);
+ }
}
- else if ( res.ptr != buf )
- FreeString(res.ptr);
+ ResetMemList(&ml);
break;
}
case SRT_MEM:
{
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ mem_list_t ml;
+ DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
+
mem_t *val = (mem_t*)(data+srt->offset);
- mem_t res = GetParamFieldMEM(buf,sizeof(buf),rs,buf,srt->emode,*val);
- if ( res.ptr != val->ptr )
+ uint i;
+ for ( i = 0; i < srt->n_elem; i++, val++ )
{
FreeString(val->ptr);
- *val = res.ptr == buf ? DupMem(res) : res;
+ val->ptr = 0;
+ val->len = 0;
+ if ( i < ml.used )
+ {
+ mem_t *m = ml.list+i;
+ if ( m->ptr )
+ *val = m->ptr == EmptyString ? EmptyMem : DupMem(*m);
+ }
}
- else if ( res.ptr != buf )
- FreeString(res.ptr);
+ ResetMemList(&ml);
break;
}
@@ -5087,7 +5029,7 @@ void RestoreStateByTable
if ( *str == ' ' ) // space should always exist
str++;
- mem_t res = DecodeByModeMem(buf,sizeof(buf),str,-1,srt->emode);
+ mem_t res = DecodeByModeMem(buf,sizeof(buf),str,-1,srt->emode,0);
InsertParamField(sf,res.ptr,false,num,0);
if ( res.ptr != buf )
FreeString(res.ptr);
diff --git a/project/dclib/dclib-network.c b/project/dclib/dclib-network.c
index eec0030..c7b5914 100644
--- a/project/dclib/dclib-network.c
+++ b/project/dclib/dclib-network.c
@@ -1708,8 +1708,8 @@ void InitializeTCPStream ( TCPStream_t *ts, int sock )
ts->poll_index = M1(ts->poll_index);
LOG_TCP_STREAM(ts,0,"%s","INIT()");
INC_TCP_INDENT;
- InitializeGrowBuffer(&ts->ibuf,0x800);
- InitializeGrowBuffer(&ts->obuf,0x800);
+ InitializeGrowBuffer(&ts->ibuf,0x4000);
+ InitializeGrowBuffer(&ts->obuf,0x4000);
DEC_TCP_INDENT;
}
diff --git a/project/dclib/dclib-numeric.c b/project/dclib/dclib-numeric.c
index 9ffa16c..379e021 100644
--- a/project/dclib/dclib-numeric.c
+++ b/project/dclib/dclib-numeric.c
@@ -859,6 +859,25 @@ int CheckIndex2End ( int max, int * p_begin, int * p_end )
/////////////// encoding/decoding ///////////////
///////////////////////////////////////////////////////////////////////////////
+ccp GetEncodingName ( EncodeMode_t em )
+{
+ static const char tab[][7] =
+ {
+ "OFF",
+ "ANSI",
+ "UTF8",
+ "BASE64",
+ "URL64",
+ "STAR64",
+ "XML64",
+ "JSON",
+ };
+
+ return (uint)em < sizeof(tab)/sizeof(*tab) ? tab[em] : PrintCircBuf("%d",em);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
char * PrintEscapedString
(
// returns 'buf'
@@ -1499,13 +1518,14 @@ mem_t DecodeJSONCirc
// with valid pointer and null terminated.
// If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
- ccp source, // NULL or string to decode
- int source_len // length of 'source'. If -1, str is NULL terminated
+ ccp source, // NULL or string to decode
+ int source_len, // length of 'source'. If -1, str is NULL terminated
+ int quote // 0:none, -1:auto, >0: quotation char
)
{
char buf[CIRC_BUF_MAX_ALLOC+10];
mem_t mem;
- mem.len = DecodeJSON(buf,sizeof(buf),source,source_len,0);
+ mem.len = DecodeJSON(buf,sizeof(buf),source,source_len,quote,0);
if ( mem.len < CIRC_BUF_MAX_ALLOC )
mem.ptr = CopyCircBuf(buf,mem.len+1);
else
@@ -1527,7 +1547,8 @@ uint DecodeByMode
uint buf_size, // size of 'buf', >= 3
ccp source, // string to decode
int slen, // length of string. if -1, str is null terminated
- EncodeMode_t emode // encoding mode
+ EncodeMode_t emode, // encoding mode
+ uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
)
{
DASSERT(buf);
@@ -1539,7 +1560,7 @@ uint DecodeByMode
if ( buf_size < 4 )
{
char temp[4];
- len = DecodeByMode(temp,sizeof(temp),source,slen,emode);
+ len = DecodeByMode(temp,sizeof(temp),source,slen,emode,scanned_len);
memcpy(buf,temp,buf_size);
goto term;
}
@@ -1548,28 +1569,28 @@ uint DecodeByMode
switch (emode)
{
case ENCODE_STRING:
- len = ScanEscapedString(buf,buf_size,source,slen,false,0,0);
+ len = ScanEscapedString(buf,buf_size,source,slen,false,-1,scanned_len);
break;
case ENCODE_UTF8:
- len = ScanEscapedString(buf,buf_size,source,slen,true,0,0);
+ len = ScanEscapedString(buf,buf_size,source,slen,true,-1,scanned_len);
break;
case ENCODE_BASE64:
- len = DecodeBase64(buf,buf_size-1,source,slen,TableDecode64,true,0);
+ len = DecodeBase64(buf,buf_size-1,source,slen,TableDecode64,true,scanned_len);
break;
case ENCODE_BASE64URL:
case ENCODE_BASE64STAR:
- len = DecodeBase64(buf,buf_size-1,source,slen,TableDecode64url,true,0);
+ len = DecodeBase64(buf,buf_size-1,source,slen,TableDecode64url,true,scanned_len);
break;
case ENCODE_BASE64XML:
- len = DecodeBase64(buf,buf_size-1,source,slen,TableDecode64xml,true,0);
+ len = DecodeBase64(buf,buf_size-1,source,slen,TableDecode64xml,true,scanned_len);
break;
case ENCODE_JSON:
- len = DecodeJSON(buf,buf_size,source,slen,0);
+ len = DecodeJSON(buf,buf_size,source,slen,-1,scanned_len);
break;
default:
@@ -1577,6 +1598,8 @@ uint DecodeByMode
len = StringCopyS(buf,buf_size,source) - buf;
else
len = StringCopySM(buf,buf_size,source,slen) - buf;
+ if (scanned_len)
+ *scanned_len = len;
break;
}
@@ -1594,14 +1617,15 @@ uint DecodeByMode
mem_t DecodeByModeMem
(
// Returns the decoded 'source'. Result is NULL-terminated.
- // It points either to 'buf' or is alloced (on buf==NULL or to less space)
+ // It points either to 'buf' or is alloced (on buf==NULL or too less space)
// If alloced (mem.ptr!=buf) => call FreeMem(&mem)
char *buf, // NULL or destination buffer
uint buf_size, // size of 'buf'
ccp source, // string to decode
int slen, // length of string. if -1, str is null terminated
- EncodeMode_t emode // encoding mode
+ EncodeMode_t emode, // encoding mode
+ uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
)
{
DASSERT( source || !slen );
@@ -1639,7 +1663,7 @@ mem_t DecodeByModeMem
}
mem_t mem;
- mem.len = DecodeByMode(buf,buf_size,source,slen,emode);
+ mem.len = DecodeByMode(buf,buf_size,source,slen,emode,scanned_len);
if ( alloced && mem.len+10 < buf_size )
buf = REALLOC( buf, mem.len+1 );
mem.ptr = buf;
@@ -1648,6 +1672,96 @@ mem_t DecodeByModeMem
///////////////////////////////////////////////////////////////////////////////
+uint DecodeByModeMemList
+(
+ // returns the number of scanned strings
+
+ mem_list_t *res, // result
+ uint res_mode, // 0:append, 1:clear, 2:init
+ ccp source, // string to decode
+ int slen, // length of string. if -1, str is null terminated
+ EncodeMode_t emode, // encoding mode
+ uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
+)
+{
+ DASSERT(res);
+ if ( res_mode > 1 )
+ InitializeMemList(res);
+ else if ( res_mode > 0 )
+ ResetMemList(res);
+
+ if (!source)
+ {
+ if (scanned_len)
+ *scanned_len = 0;
+ return 0;
+ }
+
+ ccp src = source;
+ if ( slen < 0 )
+ slen = strlen(src);
+ NeedBufMemList(res,slen,0);
+ ccp end = src + slen;
+
+ char buf[4000];
+
+ uint count;
+ for ( count = 1;; count++ )
+ {
+ if ( emode != ENCODE_OFF )
+ while ( src < end && (uchar)*src <= ' ' )
+ src++;
+
+ if ( src >= end )
+ {
+ AppendMemListN(res,&EmptyMem,1,MEMLM_ALL);
+ break;
+ }
+
+ if ( *src == ',' )
+ AppendMemListN(res,&EmptyMem,1,MEMLM_ALL);
+ else if ( *src == '%' )
+ {
+ AppendMemListN(res,&NullMem,1,MEMLM_ALL);
+ src++;
+ }
+ else if ( emode == ENCODE_OFF )
+ {
+ mem_t mem;
+ mem.ptr = src;
+ src = memchr(src,',',end-src);
+ if (!src)
+ src = end;
+ mem.len = src - mem.ptr;
+ AppendMemListN(res,&mem,1,MEMLM_ALL);
+ }
+ else
+ {
+ uint scanned;
+ mem_t mem = DecodeByModeMem(buf,sizeof(buf),src,end-src,emode,&scanned);
+ src += scanned;
+
+ AppendMemListN(res,&mem,1,MEMLM_ALL);
+ if ( mem.ptr != buf )
+ FreeString(mem.ptr);
+ }
+
+ while ( src < end && (uchar)*src <= ' ' )
+ src++;
+ if ( src >= end || *src != ',' )
+ break;
+ src++;
+ }
+
+ //--- terminate
+
+ if (scanned_len)
+ *scanned_len = src - source;
+ return count;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
uint EncodeByMode
(
// returns the number of valid bytes in 'buf'. Result is NULL-terminated.
@@ -1722,7 +1836,7 @@ uint EncodeByMode
mem_t EncodeByModeMem
(
// Returns the encoded 'source'. Result is NULL-terminated.
- // It points either to 'buf' or is alloced (on buf==NULL or to less space)
+ // It points either to 'buf' or is alloced (on buf==NULL or too less space)
// If alloced (mem.ptr!=buf) => call FreeMem(&mem)
char *buf, // NULL or destination buffer
@@ -1732,7 +1846,7 @@ mem_t EncodeByModeMem
EncodeMode_t emode // encoding mode
)
{
- DASSERT( source || !slen );
+ DASSERT( source || slen <= 0 );
DASSERT( (uint)emode < ENCODE__N );
if ( slen < 0 )