int packet_stream_parser_add_payload(struct packet_stream_parser *sp, void *pload, size_t len) { if (!sp->pload && sp->buff) { // Payload was fully used, we can discard the buffer free(sp->buff); sp->buff = NULL; sp->buff_len = 0; sp->buff_pos = 0; } if (sp->buff) { // There is some leftovers, append the new payload if (sp->buff_len - sp->buff_pos < len) { sp->buff = realloc(sp->buff, sp->buff_pos + len); if (!sp->buff) { pom_oom(sp->buff_pos + len); return POM_ERR; } sp->buff_len = sp->buff_pos + len; } memcpy(sp->buff + sp->buff_pos, pload, len); sp->buff_pos += len; sp->pload = sp->buff; sp->plen = sp->buff_pos; } else { // No need to buffer anything, let's just process it sp->pload = pload; sp->plen = len; } debug_stream_parser("entry %p, added pload %p with len %u", sp, pload, len); return POM_OK; }
int packet_stream_parser_get_remaining(struct packet_stream_parser *sp, void **pload, size_t *len) { debug_stream_parser("entry %p, providing remaining pload %p with len %u", sp, sp->pload, sp->plen); *pload = sp->pload; *len = sp->plen; return POM_OK; }
struct packet_stream_parser *packet_stream_parser_alloc(unsigned int max_line_size) { struct packet_stream_parser *res = malloc(sizeof(struct packet_stream_parser)); if (!res) { pom_oom(sizeof(struct packet_stream_parser)); return NULL; } memset(res, 0, sizeof(struct packet_stream_parser)); res->max_line_size = max_line_size; debug_stream_parser("entry %p, allocated with max_line_size %u", res, max_line_size); return res; }
int packet_stream_parser_get_line(struct packet_stream_parser *sp, char **line, size_t *len) { if (!line || !len) return POM_ERR; // Find the next line return in the current payload char *pload = sp->pload; size_t str_len = sp->plen, tmp_len = 0; char *lf = memchr(pload, '\n', sp->plen); if (!lf) { if (sp->buff) { memmove(sp->buff, sp->pload, sp->plen); sp->buff_pos = sp->plen; } else { sp->buff = malloc(sp->plen); if (!sp->buff) { pom_oom(sp->plen); return POM_ERR; } memcpy(sp->buff, sp->pload, sp->plen); sp->buff_len = sp->plen; sp->buff_pos = sp->plen; } // \n not found *line = NULL; *len = 0; debug_stream_parser("entry %p, no line found", sp); return POM_OK; } tmp_len = lf - pload; str_len = tmp_len + 1; if (lf > pload && *(lf - 1) == '\r') tmp_len--; sp->plen -= str_len; if (!sp->plen) sp->pload = NULL; else sp->pload += str_len; // Trim the string if (sp->flags & PACKET_STREAM_PARSER_FLAG_TRIM) { while (tmp_len && *pload == ' ') { pload++; tmp_len--; } while (tmp_len && pload[tmp_len] == ' ') tmp_len--; } *line = pload; if (sp->flags & PACKET_STREAM_PARSER_FLAG_INCLUDE_CRLF) *len = str_len; else *len = tmp_len; debug_stream_parser("entry %p, got line of %u bytes", sp, tmp_len); return POM_OK; }
int packet_stream_parser_get_line(struct packet_stream_parser *sp, char **line, unsigned int *len) { if (!line || !len) return POM_ERR; // Find the next line return in the current payload char *pload = sp->pload; int str_len = sp->plen, tmp_len = 0; char *lf = memchr(pload, '\n', sp->plen); if (!lf) { if (sp->buff) { memmove(sp->buff, sp->pload, sp->plen); sp->buff_pos = sp->plen; } else { sp->buff = malloc(sp->plen); if (!sp->buff) { pom_oom(sp->plen); return POM_ERR; } memcpy(sp->buff, sp->pload, sp->plen); sp->buff_len = sp->plen; sp->buff_pos = sp->plen; } // \n not found *line = NULL; *len = 0; debug_stream_parser("entry %p, no line found", sp); return POM_OK; } tmp_len = lf - pload; str_len = tmp_len + 1; if (lf > pload && *(lf - 1) == '\r') tmp_len--; sp->plen -= str_len; if (!sp->plen) sp->pload = NULL; else sp->pload += str_len; // Trim the string while (*pload == ' ' && tmp_len) { pload++; tmp_len--; } while (pload[tmp_len] == ' ' && tmp_len) tmp_len--; *line = pload; *len = tmp_len; debug_stream_parser("entry %p, got line of %u bytes", sp, tmp_len); return POM_OK; }