diff options
| author | lijia <[email protected]> | 2024-05-24 22:47:32 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2024-06-03 11:08:06 +0800 |
| commit | 1c232f0176c43c93c3e787ac83f3573bf42c58f1 (patch) | |
| tree | 734c31a97ec38847972b70a18ec075fd415bb5f6 /src/http_decoder_string.cpp | |
| parent | 22d071e23ff423242f51dce2eab1477b5fb9d106 (diff) | |
Adapt to stellar2.0;update API,add HDR_END,BODY_END,TRANSACTION_NEW,FREE msg.v2.0.2
Diffstat (limited to 'src/http_decoder_string.cpp')
| -rw-r--r-- | src/http_decoder_string.cpp | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/src/http_decoder_string.cpp b/src/http_decoder_string.cpp new file mode 100644 index 0000000..e10b4a0 --- /dev/null +++ b/src/http_decoder_string.cpp @@ -0,0 +1,258 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "http_decoder_inc.h" + +static const char *string_state_to_desc(enum string_state state) +{ + switch (state) { + case STRING_STATE_INIT: + return "init"; + break; + case STRING_STATE_REFER: + return "refer"; + break; + case STRING_STATE_CACHE: + return "cache"; + break; + case STRING_STATE_COMMIT: + return "commit"; + break; + default: + return "unknown"; + break; + } +} + +void http_decoder_string_refer(struct http_decoder_string *rstr, + const char *at, size_t length) +{ + if (NULL == rstr) { + return; + } + + switch (rstr->state) { + case STRING_STATE_INIT: + case STRING_STATE_CACHE: + rstr->refer.str = (char *)at; + rstr->refer.str_len = length; + break; + default: + abort(); + break; + } + + rstr->state = STRING_STATE_REFER; +} + +static void string_refer2cache(struct http_decoder_string *rstr) +{ + if (0 == rstr->refer.str_len) { + return; + } + if (rstr->cache.str_len >= rstr->max_cache_size) { + return; + } + + size_t length = rstr->cache.str_len + rstr->refer.str_len; + if (length > rstr->max_cache_size) { + length = rstr->max_cache_size; + } + + if (NULL == rstr->cache.str) { + rstr->cache.str = CALLOC(char, length + 1); + memcpy(rstr->cache.str, rstr->refer.str, length); + } else { + rstr->cache.str = REALLOC(char, rstr->cache.str, length + 1); + memcpy(rstr->cache.str + rstr->cache.str_len, rstr->refer.str, + (length - rstr->cache.str_len)); + } + + rstr->cache.str_len = length; + rstr->refer.str = NULL; + rstr->refer.str_len = 0; +} + +static void string_commit2cache(struct http_decoder_string *rstr) +{ + if (rstr->cache.str_len == rstr->commit.str_len && + rstr->cache.str == rstr->commit.str) { + rstr->commit.str = NULL; + rstr->commit.str_len = 0; + return; + } + + //Only http header key need to backward to cache + size_t length = 0; + if (rstr->commit.str_len > rstr->max_cache_size) { + length = rstr->max_cache_size; + } else { + length = rstr->commit.str_len; + } + + if (length > 0) { + if (NULL == rstr->cache.str) { + rstr->cache.str = CALLOC(char, length + 1); + } else { + abort(); + } + memcpy(rstr->cache.str, rstr->commit.str, length); + rstr->cache.str_len = length; + + rstr->commit.str = NULL; + rstr->commit.str_len = 0; + } +} + +void http_decoder_string_cache(struct http_decoder_string *rstr) +{ + if (NULL == rstr) { + return; + } + + switch (rstr->state) { + case STRING_STATE_REFER: + string_refer2cache(rstr); + break; + case STRING_STATE_CACHE: + break; + case STRING_STATE_COMMIT: + //commit backward to cache + string_commit2cache(rstr); + break; + default: + abort(); + break; + } + rstr->state = STRING_STATE_CACHE; +} + +void http_decoder_string_commit(struct http_decoder_string *rstr) +{ + if (NULL == rstr) { + return; + } + + switch (rstr->state) { + case STRING_STATE_REFER: + if (rstr->cache.str_len) { + http_decoder_string_cache(rstr); + + rstr->commit.str = rstr->cache.str; + rstr->commit.str_len = rstr->cache.str_len; + // not overwrite rstr->cache.str + } else { + rstr->commit.str = rstr->refer.str; + rstr->commit.str_len = rstr->refer.str_len; + + rstr->refer.str = NULL; + rstr->refer.str_len = 0; + } + break; + case STRING_STATE_CACHE: + rstr->commit.str = rstr->cache.str; + rstr->commit.str_len = rstr->cache.str_len; + // not overwrite rstr->cache.str + break; + default: + //abort(); + break; + } + + rstr->state = STRING_STATE_COMMIT; +} + +void http_decoder_string_reset(struct http_decoder_string *rstr) +{ + assert(rstr); + + switch (rstr->state) { + case STRING_STATE_INIT: + case STRING_STATE_REFER: + case STRING_STATE_CACHE: + case STRING_STATE_COMMIT: + FREE(rstr->cache.str); + memset(rstr, 0, sizeof(struct http_decoder_string)); + break; + default: + abort(); + break; + } + + rstr->state = STRING_STATE_INIT; +} + + +void http_decoder_string_init(struct http_decoder_string *rstr, + size_t max_cache_size) +{ + rstr->max_cache_size = max_cache_size; +} + +void http_decoder_string_reinit(struct http_decoder_string *rstr) +{ + if (rstr->state == STRING_STATE_CACHE) { + return; + } + + if (rstr->state == STRING_STATE_COMMIT && + rstr->cache.str == rstr->commit.str && + rstr->cache.str_len == rstr->commit.str_len) { + return; + } + + if (rstr->cache.str != NULL) { + FREE(rstr->cache.str); + rstr->cache.str_len = 0; + } + + rstr->refer.str = NULL; + rstr->refer.str_len = 0; + rstr->commit.str = NULL; + rstr->commit.str_len = 0; + rstr->state = STRING_STATE_INIT; +} + +enum string_state http_decoder_string_state(const struct http_decoder_string *rstr) +{ + return rstr->state; +} + +int http_decoder_string_get(const struct http_decoder_string *rstr, struct hstring *out) +{ + if (NULL == rstr || NULL == out) { + return -1; + } + + if (http_decoder_string_state(rstr) == STRING_STATE_COMMIT) { + out->str = rstr->commit.str; + out->str_len = rstr->commit.str_len; + } else { + out->str = NULL; + out->str_len = 0; + } + + return 0; +} + +void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc) +{ + if (NULL == rstr) { + return; + } + + char *refer_str = safe_dup(rstr->refer.str, rstr->refer.str_len); + char *cache_str = safe_dup(rstr->cache.str, rstr->cache.str_len); + char *commit_str = safe_dup(rstr->commit.str, rstr->commit.str_len); + + printf("%s: state: %s, refer: {len: %02zu, str: %s}, cache: {len: %02zu, str: %s}, commit: {len: %02zu, str: %s}\n", + desc, string_state_to_desc(rstr->state), + rstr->refer.str_len, refer_str, + rstr->cache.str_len, cache_str, + rstr->commit.str_len, commit_str); + + FREE(refer_str); + FREE(cache_str); + FREE(commit_str); +}
\ No newline at end of file |
