#include "parcer.h" #include "server_structs.h" #include #include #include int ensure(size_t recv_len, size_t offset, size_t need) { return (offset + need <= recv_len); } u_int8_t read_uint8(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok) { if (!ensure(recv_len, *offset, sizeof(uint8_t))) { *ok = 0; return 0; } u_int8_t v; memcpy(&v, buf + *offset, sizeof(v)); *offset += sizeof(v); return v; } u_int16_t read_uint16(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok) { if (!ensure(recv_len, *offset, sizeof(uint16_t))) { *ok = 0; return 0; } u_int16_t v; memcpy(&v, buf + *offset, sizeof(v)); *offset += sizeof(v); return (u_int16_t)ntohs(v); } u_int32_t read_uint32(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok) { if (!ensure(recv_len, *offset, sizeof(uint32_t))) { *ok = 0; return 0; } u_int32_t v; memcpy(&v, buf + *offset, sizeof(v)); *offset += sizeof(v); return (u_int32_t)ntohl(v); } int32_t read_int32(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok) { if (!ensure(recv_len, *offset, sizeof(int32_t))) { *ok = 0; return 0; } int32_t v; memcpy(&v, buf + *offset, sizeof(v)); *offset += sizeof(v); return (int32_t)ntohl((u_int32_t)v); } float read_float(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok) { if (!ensure(recv_len, *offset, sizeof(float))) { *ok = 0; return 0.0f; } u_int32_t v_int; memcpy(&v_int, buf + *offset, sizeof(v_int)); *offset += sizeof(v_int); v_int = ntohl(v_int); float v_float; memcpy(&v_float, &v_int, sizeof(v_float)); return v_float; } void read_bytes(const u_int8_t *buf, size_t recv_len, size_t *offset, u_int8_t *out, size_t len, int *ok) { if (!ensure(recv_len, *offset, len)) { *ok = 0; return; } memcpy(out, buf + *offset, len); *offset += len; } void read_utf32le_string(const uint8_t *buffer, size_t buf_size, size_t *offset, char *dest, size_t max_len, int *ok) { size_t i = *offset; size_t j = 0; while (i + 3 < buf_size && j < max_len) { uint32_t codeunit = buffer[i] | (buffer[i + 1] << 8) | (buffer[i + 2] << 16) | (buffer[i + 3] << 24); if (codeunit == 0) { i += 4; // termina a string break; } if (codeunit < 0x80) { dest[j++] = (char)codeunit; } else { dest[j++] = '?'; // substitui caracteres fora de ASCII } i += 4; } dest[j] = '\0'; *offset = i; *ok = 1; } void read_utf16le_string(const uint8_t *buffer, size_t buf_size, size_t *offset, char *dest, size_t max_len, int *ok) { size_t i = *offset; size_t j = 0; while (i + 1 < buf_size && j < max_len - 1) { uint16_t codeunit = buffer[i] | (buffer[i + 1] << 8); if (codeunit == 0) { i += 2; // termina a string break; } if (codeunit < 0x80) { dest[j++] = (char)codeunit; } else { dest[j++] = '?'; // substitui caracteres fora de ASCII } i += 2; } dest[j] = '\0'; *offset = i; *ok = 1; } void read_string(const u_int8_t *buf, size_t recv_len, size_t *offset, char *out, size_t len, int *ok) { if (!ensure(recv_len, *offset, len)) { *ok = 0; return; } for (size_t i = 0; i <= len; i++) { out[i] = (char)buf[*offset + i]; } out[len] = '\0'; // Ensure null termination *offset += len; *ok = 1; }