mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
added state op return codes for psyc_parse, added stateop to PsycPacket
This commit is contained in:
parent
27dbed5dc7
commit
af6106c125
9 changed files with 91 additions and 91 deletions
|
@ -8,28 +8,9 @@ const PSYC_CONTENT_SIZE_THRESHOLD = 444;
|
||||||
/* beyond this a modifier value length must be provided */
|
/* beyond this a modifier value length must be provided */
|
||||||
const PSYC_MODIFIER_SIZE_THRESHOLD = 404;
|
const PSYC_MODIFIER_SIZE_THRESHOLD = 404;
|
||||||
|
|
||||||
const C_GLYPH_PACKET_DELIMITER = '|';
|
const PSYC_PACKET_DELIMITER_CHAR = '|';
|
||||||
const S_GLYPH_PACKET_DELIMITER = "|";
|
|
||||||
const PSYC_PACKET_DELIMITER = "\n|\n";
|
const PSYC_PACKET_DELIMITER = "\n|\n";
|
||||||
|
|
||||||
const C_GLYPH_SEPARATOR_KEYWORD = '_';
|
|
||||||
const S_GLYPH_SEPARATOR_KEYWORD = "_";
|
|
||||||
|
|
||||||
const C_GLYPH_OPERATOR_SET = ':';
|
|
||||||
const S_GLYPH_OPERATOR_SET = ":";
|
|
||||||
|
|
||||||
const C_GLYPH_OPERATOR_ASSIGN = '=';
|
|
||||||
const S_GLYPH_OPERATOR_ASSIGN = "=";
|
|
||||||
|
|
||||||
const C_GLYPH_OPERATOR_AUGMENT = '+';
|
|
||||||
const S_GLYPH_OPERATOR_AUGMENT = "+";
|
|
||||||
|
|
||||||
const C_GLYPH_OPERATOR_DIMINISH = '-';
|
|
||||||
const S_GLYPH_OPERATOR_DIMINISH = "-";
|
|
||||||
|
|
||||||
const C_GLYPH_OPERATOR_QUERY = '?';
|
|
||||||
const S_GLYPH_OPERATOR_QUERY = "?";
|
|
||||||
|
|
||||||
/* might move into routing.h or something */
|
/* might move into routing.h or something */
|
||||||
const PSYC_ROUTING = 1;
|
const PSYC_ROUTING = 1;
|
||||||
const PSYC_ROUTING_MERGE = 2;
|
const PSYC_ROUTING_MERGE = 2;
|
||||||
|
|
|
@ -63,6 +63,13 @@ typedef enum
|
||||||
PSYC_OPERATOR_QUERY = '?',
|
PSYC_OPERATOR_QUERY = '?',
|
||||||
} PsycOperator;
|
} PsycOperator;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PSYC_STATE_NOOP = 0,
|
||||||
|
PSYC_STATE_RESET = '=',
|
||||||
|
PSYC_STATE_SYNC = '?',
|
||||||
|
} PsycStateOp;
|
||||||
|
|
||||||
/** Structure for a modifier. */
|
/** Structure for a modifier. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -93,6 +100,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
PsycHeader routing; ///< Routing header.
|
PsycHeader routing; ///< Routing header.
|
||||||
PsycHeader entity; ///< Entity header.
|
PsycHeader entity; ///< Entity header.
|
||||||
|
char stateop; ///< State operation. @see PsycStateOp
|
||||||
PsycString method; ///< Contains the method.
|
PsycString method; ///< Contains the method.
|
||||||
PsycString data; ///< Contains the data.
|
PsycString data; ///< Contains the data.
|
||||||
PsycString content; ///< Contains the whole content.
|
PsycString content; ///< Contains the whole content.
|
||||||
|
@ -182,7 +190,7 @@ void psyc_packet_init (PsycPacket *packet,
|
||||||
PsycModifier *entity, size_t entitylen,
|
PsycModifier *entity, size_t entitylen,
|
||||||
char *method, size_t methodlen,
|
char *method, size_t methodlen,
|
||||||
char *data, size_t datalen,
|
char *data, size_t datalen,
|
||||||
PsycPacketFlag flag);
|
char stateop, PsycPacketFlag flag);
|
||||||
|
|
||||||
/** Initialize packet with raw content. */
|
/** Initialize packet with raw content. */
|
||||||
void psyc_packet_init_raw (PsycPacket *packet,
|
void psyc_packet_init_raw (PsycPacket *packet,
|
||||||
|
|
|
@ -152,42 +152,46 @@ typedef enum {
|
||||||
/// Routing modifier parsing done.
|
/// Routing modifier parsing done.
|
||||||
/// Operator, name & value contains the respective parts.
|
/// Operator, name & value contains the respective parts.
|
||||||
PSYC_PARSE_ROUTING = 2,
|
PSYC_PARSE_ROUTING = 2,
|
||||||
|
/// State sync operation.
|
||||||
|
PSYC_PARSE_STATE_SYNC = 3,
|
||||||
|
/// State reset operation.
|
||||||
|
PSYC_PARSE_STATE_RESET = 4,
|
||||||
/// Start of an incomplete entity modifier.
|
/// Start of an incomplete entity modifier.
|
||||||
/// Operator & name are complete, value is incomplete.
|
/// Operator & name are complete, value is incomplete.
|
||||||
PSYC_PARSE_ENTITY_START = 3,
|
PSYC_PARSE_ENTITY_START = 5,
|
||||||
/// Continuation of an incomplete entity modifier.
|
/// Continuation of an incomplete entity modifier.
|
||||||
PSYC_PARSE_ENTITY_CONT = 4,
|
PSYC_PARSE_ENTITY_CONT = 6,
|
||||||
/// End of an incomplete entity modifier.
|
/// End of an incomplete entity modifier.
|
||||||
PSYC_PARSE_ENTITY_END = 5,
|
PSYC_PARSE_ENTITY_END = 7,
|
||||||
/// Entity modifier parsing done in one go.
|
/// Entity modifier parsing done in one go.
|
||||||
/// Operator, name & value contains the respective parts.
|
/// Operator, name & value contains the respective parts.
|
||||||
PSYC_PARSE_ENTITY = 6,
|
PSYC_PARSE_ENTITY = 8,
|
||||||
/// Start of an incomplete body.
|
/// Start of an incomplete body.
|
||||||
/// Name contains method, value contains part of the body.
|
/// Name contains method, value contains part of the body.
|
||||||
/// Used when packet length is given
|
/// Used when packet length is given
|
||||||
PSYC_PARSE_BODY_START = 7,
|
PSYC_PARSE_BODY_START = 9,
|
||||||
/// Continuation of an incomplete body.
|
/// Continuation of an incomplete body.
|
||||||
/// Used when packet length is given
|
/// Used when packet length is given
|
||||||
PSYC_PARSE_BODY_CONT = 8,
|
PSYC_PARSE_BODY_CONT = 10,
|
||||||
/// End of an incomplete body.
|
/// End of an incomplete body.
|
||||||
/// Used when packet length is given
|
/// Used when packet length is given
|
||||||
PSYC_PARSE_BODY_END = 9,
|
PSYC_PARSE_BODY_END = 11,
|
||||||
/// Body parsing done in one go, name contains method, value contains body.
|
/// Body parsing done in one go, name contains method, value contains body.
|
||||||
PSYC_PARSE_BODY = 10,
|
PSYC_PARSE_BODY = 12,
|
||||||
/// Start of an incomplete content, value contains part of content.
|
/// Start of an incomplete content, value contains part of content.
|
||||||
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
||||||
PSYC_PARSE_CONTENT_START = 7,
|
PSYC_PARSE_CONTENT_START = 9,
|
||||||
/// Continuation of an incomplete content.
|
/// Continuation of an incomplete content.
|
||||||
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
||||||
PSYC_PARSE_CONTENT_CONT = 8,
|
PSYC_PARSE_CONTENT_CONT = 10,
|
||||||
/// End of an incomplete content.
|
/// End of an incomplete content.
|
||||||
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
||||||
PSYC_PARSE_CONTENT_END = 9,
|
PSYC_PARSE_CONTENT_END = 11,
|
||||||
/// Content parsing done in one go, value contains the whole content.
|
/// Content parsing done in one go, value contains the whole content.
|
||||||
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
|
||||||
PSYC_PARSE_CONTENT = 10,
|
PSYC_PARSE_CONTENT = 12,
|
||||||
/// Finished parsing packet.
|
/// Finished parsing packet.
|
||||||
PSYC_PARSE_COMPLETE = 11,
|
PSYC_PARSE_COMPLETE = 13,
|
||||||
} PsycParseRC;
|
} PsycParseRC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,32 +14,8 @@
|
||||||
# define PSYC_MODIFIER_SIZE_THRESHOLD 404
|
# define PSYC_MODIFIER_SIZE_THRESHOLD 404
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define C_GLYPH_PACKET_DELIMITER '|'
|
#define PSYC_PACKET_DELIMITER_CHAR '|'
|
||||||
#define S_GLYPH_PACKET_DELIMITER "|"
|
|
||||||
#define PSYC_PACKET_DELIMITER "\n|\n"
|
#define PSYC_PACKET_DELIMITER "\n|\n"
|
||||||
|
|
||||||
#define C_GLYPH_SEPARATOR_KEYWORD '_'
|
|
||||||
#define S_GLYPH_SEPARATOR_KEYWORD "_"
|
|
||||||
|
|
||||||
#define C_GLYPH_OPERATOR_SET ':'
|
|
||||||
#define S_GLYPH_OPERATOR_SET ":"
|
|
||||||
|
|
||||||
#define C_GLYPH_OPERATOR_ASSIGN '='
|
|
||||||
#define S_GLYPH_OPERATOR_ASSIGN "="
|
|
||||||
|
|
||||||
#define C_GLYPH_OPERATOR_AUGMENT '+'
|
|
||||||
#define S_GLYPH_OPERATOR_AUGMENT "+"
|
|
||||||
|
|
||||||
#define C_GLYPH_OPERATOR_DIMINISH '-'
|
|
||||||
#define S_GLYPH_OPERATOR_DIMINISH "-"
|
|
||||||
|
|
||||||
#define C_GLYPH_OPERATOR_QUERY '?'
|
|
||||||
#define S_GLYPH_OPERATOR_QUERY "?"
|
|
||||||
|
|
||||||
/* might move into routing.h or something */
|
|
||||||
#define PSYC_ROUTING 1
|
|
||||||
#define PSYC_ROUTING_MERGE 2
|
|
||||||
#define PSYC_ROUTING_RENDER 4
|
|
||||||
|
|
||||||
#define PSYC_SYNTAX_H
|
#define PSYC_SYNTAX_H
|
||||||
#endif
|
#endif
|
||||||
|
|
12
src/packet.c
12
src/packet.c
|
@ -76,7 +76,7 @@ size_t psyc_modifier_length (PsycModifier *m)
|
||||||
inline
|
inline
|
||||||
PsycPacketFlag psyc_packet_length_check (PsycPacket *p)
|
PsycPacketFlag psyc_packet_length_check (PsycPacket *p)
|
||||||
{
|
{
|
||||||
if (p->data.length == 1 && p->data.data[0] == C_GLYPH_PACKET_DELIMITER)
|
if (p->data.length == 1 && p->data.data[0] == PSYC_PACKET_DELIMITER_CHAR)
|
||||||
return PSYC_PACKET_NEED_LENGTH;
|
return PSYC_PACKET_NEED_LENGTH;
|
||||||
|
|
||||||
if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD)
|
if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD)
|
||||||
|
@ -110,6 +110,10 @@ size_t psyc_packet_length_set (PsycPacket *p)
|
||||||
p->contentLength = p->content.length;
|
p->contentLength = p->content.length;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// add state operation
|
||||||
|
if (p->stateop != PSYC_STATE_NOOP)
|
||||||
|
p->contentLength += 2; // op\n
|
||||||
|
|
||||||
// add entity header length
|
// add entity header length
|
||||||
for (i = 0; i < p->entity.lines; i++)
|
for (i = 0; i < p->entity.lines; i++)
|
||||||
p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i]));
|
p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i]));
|
||||||
|
@ -139,9 +143,9 @@ void psyc_packet_init (PsycPacket *p,
|
||||||
PsycModifier *entity, size_t entitylen,
|
PsycModifier *entity, size_t entitylen,
|
||||||
char *method, size_t methodlen,
|
char *method, size_t methodlen,
|
||||||
char *data, size_t datalen,
|
char *data, size_t datalen,
|
||||||
PsycPacketFlag flag)
|
char stateop, PsycPacketFlag flag)
|
||||||
{
|
{
|
||||||
*p = (PsycPacket) {{routinglen, routing}, {entitylen, entity},
|
*p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, stateop,
|
||||||
{methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag};
|
{methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag};
|
||||||
|
|
||||||
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length
|
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length
|
||||||
|
@ -156,7 +160,7 @@ void psyc_packet_init_raw (PsycPacket *p,
|
||||||
char *content, size_t contentlen,
|
char *content, size_t contentlen,
|
||||||
PsycPacketFlag flag)
|
PsycPacketFlag flag)
|
||||||
{
|
{
|
||||||
*p = (PsycPacket) {{routinglen, routing}, {0,0}, {0,0}, {0,0},
|
*p = (PsycPacket) {{routinglen, routing}, {0,0}, 0, {0,0}, {0,0},
|
||||||
{contentlen, content}, 0, 0, flag};
|
{contentlen, content}, 0, 0, flag};
|
||||||
|
|
||||||
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length
|
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length
|
||||||
|
|
22
src/parse.c
22
src/parse.c
|
@ -88,10 +88,6 @@ ParseRC psyc_parse_modifier (PsycParseState *state, char *oper,
|
||||||
*oper = *(state->buffer.data + state->cursor);
|
*oper = *(state->buffer.data + state->cursor);
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
|
|
||||||
if (state->part == PSYC_PART_CONTENT && state->buffer.data[state->cursor] == '\n' &&
|
|
||||||
(*oper == PSYC_OPERATOR_ASSIGN || *oper == PSYC_OPERATOR_QUERY))
|
|
||||||
return PARSE_SUCCESS; // only oper is present, used for state sync/reset
|
|
||||||
|
|
||||||
ParseRC ret = psyc_parse_keyword(state, name);
|
ParseRC ret = psyc_parse_keyword(state, name);
|
||||||
if (ret == PARSE_ERROR)
|
if (ret == PARSE_ERROR)
|
||||||
return PSYC_PARSE_ERROR_MOD_NAME;
|
return PSYC_PARSE_ERROR_MOD_NAME;
|
||||||
|
@ -287,6 +283,24 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper,
|
||||||
// method does not start with a glyph.
|
// method does not start with a glyph.
|
||||||
if (psyc_is_glyph(state->buffer.data[state->cursor]))
|
if (psyc_is_glyph(state->buffer.data[state->cursor]))
|
||||||
{
|
{
|
||||||
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
|
if (state->contentParsed == 0 && state->buffer.data[state->cursor] == '\n')
|
||||||
|
{
|
||||||
|
*oper = *(state->buffer.data + state->cursor - 1);
|
||||||
|
switch (*oper)
|
||||||
|
{
|
||||||
|
case PSYC_STATE_SYNC:
|
||||||
|
state->contentParsed += 2;
|
||||||
|
return PSYC_PARSE_STATE_SYNC;
|
||||||
|
case PSYC_STATE_RESET:
|
||||||
|
state->contentParsed += 2;
|
||||||
|
return PSYC_PARSE_STATE_RESET;
|
||||||
|
default:
|
||||||
|
return PSYC_PARSE_ERROR_MOD_NAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state->cursor--;
|
||||||
|
|
||||||
ret = psyc_parse_modifier(state, oper, name, value);
|
ret = psyc_parse_modifier(state, oper, name, value);
|
||||||
state->contentParsed += state->cursor - pos;
|
state->contentParsed += state->cursor - pos;
|
||||||
|
|
||||||
|
|
20
src/render.c
20
src/render.c
|
@ -1,4 +1,5 @@
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
#include <psyc/packet.h>
|
||||||
#include <psyc/render.h>
|
#include <psyc/render.h>
|
||||||
#include <psyc/syntax.h>
|
#include <psyc/syntax.h>
|
||||||
|
|
||||||
|
@ -46,12 +47,12 @@ static inline
|
||||||
size_t psyc_render_modifier (PsycModifier *mod, char *buffer)
|
size_t psyc_render_modifier (PsycModifier *mod, char *buffer)
|
||||||
{
|
{
|
||||||
size_t cur = 0;
|
size_t cur = 0;
|
||||||
buffer[cur++] = mod->oper;
|
|
||||||
|
|
||||||
if (mod->name.length > 0)
|
buffer[cur++] = mod->oper;
|
||||||
{
|
|
||||||
memcpy(buffer + cur, mod->name.data, mod->name.length);
|
memcpy(buffer + cur, mod->name.data, mod->name.length);
|
||||||
cur += mod->name.length;
|
cur += mod->name.length;
|
||||||
|
if (cur == 1)
|
||||||
|
return cur; // error, name can't be empty
|
||||||
|
|
||||||
if (mod->flag == PSYC_MODIFIER_NEED_LENGTH)
|
if (mod->flag == PSYC_MODIFIER_NEED_LENGTH)
|
||||||
{
|
{
|
||||||
|
@ -62,9 +63,8 @@ size_t psyc_render_modifier (PsycModifier *mod, char *buffer)
|
||||||
buffer[cur++] = '\t';
|
buffer[cur++] = '\t';
|
||||||
memcpy(buffer + cur, mod->value.data, mod->value.length);
|
memcpy(buffer + cur, mod->value.data, mod->value.length);
|
||||||
cur += mod->value.length;
|
cur += mod->value.length;
|
||||||
}
|
|
||||||
|
|
||||||
buffer[cur++] = '\n';
|
buffer[cur++] = '\n';
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,8 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen)
|
||||||
cur += itoa(packet->contentLength, buffer + cur, 10);
|
cur += itoa(packet->contentLength, buffer + cur, 10);
|
||||||
|
|
||||||
if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length ||
|
if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length ||
|
||||||
packet->entity.lines || packet->method.length || packet->data.length)
|
packet->stateop || packet->entity.lines ||
|
||||||
|
packet->method.length || packet->data.length)
|
||||||
buffer[cur++] = '\n'; // start of content part if there's content or length
|
buffer[cur++] = '\n'; // start of content part if there's content or length
|
||||||
|
|
||||||
if (packet->content.length) // render raw content if present
|
if (packet->content.length) // render raw content if present
|
||||||
|
@ -102,6 +103,11 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (packet->stateop) {
|
||||||
|
buffer[cur++] = packet->stateop;
|
||||||
|
buffer[cur++] = '\n';
|
||||||
|
}
|
||||||
|
|
||||||
// render entity modifiers
|
// render entity modifiers
|
||||||
for (i = 0; i < packet->entity.lines; i++)
|
for (i = 0; i < packet->entity.lines; i++)
|
||||||
cur += psyc_render_modifier(&packet->entity.modifiers[i], buffer + cur);
|
cur += psyc_render_modifier(&packet->entity.modifiers[i], buffer + cur);
|
||||||
|
@ -124,7 +130,7 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add packet delimiter
|
// add packet delimiter
|
||||||
buffer[cur++] = C_GLYPH_PACKET_DELIMITER;
|
buffer[cur++] = PSYC_PACKET_DELIMITER_CHAR;
|
||||||
buffer[cur++] = '\n';
|
buffer[cur++] = '\n';
|
||||||
|
|
||||||
// actual length should be equal to pre-calculated length at this point
|
// actual length should be equal to pre-calculated length at this point
|
||||||
|
|
|
@ -98,6 +98,11 @@ int test_input (int i, char *recvbuf, size_t nbytes) {
|
||||||
packet->routing.lines++;
|
packet->routing.lines++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PSYC_PARSE_STATE_SYNC:
|
||||||
|
case PSYC_PARSE_STATE_RESET:
|
||||||
|
packet->stateop = oper;
|
||||||
|
break;
|
||||||
|
|
||||||
case PSYC_PARSE_ENTITY_START:
|
case PSYC_PARSE_ENTITY_START:
|
||||||
case PSYC_PARSE_ENTITY_CONT:
|
case PSYC_PARSE_ENTITY_CONT:
|
||||||
case PSYC_PARSE_ENTITY_END:
|
case PSYC_PARSE_ENTITY_END:
|
||||||
|
|
|
@ -30,6 +30,7 @@ int testPresence (const char *avail, int availlen,
|
||||||
entity, PSYC_NUM_ELEM(entity),
|
entity, PSYC_NUM_ELEM(entity),
|
||||||
PSYC_C2ARG("_notice_presence"),
|
PSYC_C2ARG("_notice_presence"),
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
|
PSYC_STATE_NOOP,
|
||||||
PSYC_PACKET_CHECK_LENGTH);
|
PSYC_PACKET_CHECK_LENGTH);
|
||||||
|
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
@ -82,6 +83,7 @@ int testList (const char *rendered, uint8_t verbose)
|
||||||
entity, PSYC_NUM_ELEM(entity),
|
entity, PSYC_NUM_ELEM(entity),
|
||||||
PSYC_C2ARG("_test_list"),
|
PSYC_C2ARG("_test_list"),
|
||||||
PSYC_C2ARG("list test"),
|
PSYC_C2ARG("list test"),
|
||||||
|
PSYC_STATE_NOOP,
|
||||||
PSYC_PACKET_CHECK_LENGTH);
|
PSYC_PACKET_CHECK_LENGTH);
|
||||||
|
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
|
Loading…
Reference in a new issue