eolib 0.5.0
A core C library for writing applications related to Endless Online
Loading...
Searching...
No Matches
Writing Data

EoWriter accumulates EO-encoded bytes into a dynamically-growing buffer. Call eo_writer_free() when finished to release the owned memory.

Basic usage:

eo_writer_add_byte(&writer, 0x06); // Action byte
eo_writer_add_byte(&writer, 0x02); // Family byte
eo_writer_add_short(&writer, 1234); // Player ID
eo_writer_add_string(&writer, "Eoserv");
// writer.data and writer.length hold the final payload.
send(socket, writer.data, writer.length);
eo_writer_free(&writer);
EoResult eo_writer_add_string(EoWriter *writer, const char *value)
Definition data.c:561
EoResult eo_writer_add_byte(EoWriter *writer, uint8_t value)
Definition data.c:423
EoResult eo_writer_add_short(EoWriter *writer, int32_t value)
Definition data.c:469
EoWriter eo_writer_init(void)
Definition data.c:216
void eo_writer_free(EoWriter *writer)
Definition data.c:231
size_t length
Definition data.h:27
uint8_t * data
Definition data.h:26

Encoded (EO-transformed) strings:

Some packet fields use EO's string encoding, which byte-transforms and reverses the string. Use the _encoded_ variants for these fields:

eo_writer_add_encoded_string(&writer, "secret");
EoResult eo_writer_add_encoded_string(EoWriter *writer, const char *value)
Definition data.c:607

String sanitization mode:

When string sanitization is enabled, any 0xFF byte in a string is replaced with 0x79 ('y'). This prevents chat or name strings from accidentally introducing chunk delimiters.

eo_writer_add_string(&writer, user_input); // 0xFF bytes safely replaced.
void eo_writer_set_string_sanitization_mode(EoWriter *writer, bool enabled)
Definition data.c:415

Number types and their byte widths:

Function Bytes written Max value
eo_writer_add_byte() 1 255
eo_writer_add_char() 1 EO_CHAR_MAX
eo_writer_add_short() 2 EO_SHORT_MAX
eo_writer_add_three() 3 EO_THREE_MAX
eo_writer_add_int() 4 EO_INT_MAX

Negative numbers:

Only eo_writer_add_int() supports negative int32_t values. eo_writer_add_char(), eo_writer_add_short(), and eo_writer_add_three() accept only non-negative values in their documented ranges.

Negative 4-byte EO ints are encoded from the value's 32-bit bit pattern. Because EO's 4-byte range stops at EO_INT_MAX (4097152081), not every negative int32_t is representable. The valid negative range is [INT32_MIN, -197815216].

In particular:

  • INT32_MIN encodes to A8 B5 9A 85
  • -197815216 encodes to FD FD FD FD
  • values in [-197815215, -1] are rejected with EO_INVALID_INT

Pre-allocating with eo_get_size():

eo_get_size() dispatches through the vtable to return the exact number of bytes eo_serialize() will write for a given struct. Pass that value to eo_writer_init_with_capacity() to allocate the full buffer upfront and avoid repeated reallocations during serialization.

This is especially valuable when serializing large structures such as pub files or packets with long string arrays.

pkt.username = "Admin";
pkt.password = "hunter2";
// Calculate exact serialized size before writing.
eo_get_size((const EoSerialize *)&pkt));
EoResult result = eo_serialize((const EoSerialize *)&pkt, &writer);
if (result != EO_SUCCESS) {
eo_writer_free(&writer);
return result;
}
send(socket, writer.data, writer.length);
eo_writer_free(&writer);
static EoResult eo_serialize(const EoSerialize *serialize, EoWriter *writer)
Definition data.h:428
static size_t eo_get_size(const EoSerialize *serialize)
Definition data.h:440
EoWriter eo_writer_init_with_capacity(size_t capacity)
Definition data.c:221
LoginRequestClientPacket LoginRequestClientPacket_init(void)
Creates a new LoginRequestClientPacket with the serialization vtable initialized.
Definition protocol.c:7152
EoResult
Definition result.h:12
@ EO_SUCCESS
Definition result.h:14

When serializing a collection of structs (e.g. building a pub file), sum the sizes first:

Eif eif = Eif_init();
// ... populate eif ...
size_t total = eo_get_size((const EoSerialize *)&eif);
eo_serialize((const EoSerialize *)&eif, &writer);
// write writer.data to disk...
eo_writer_free(&writer);
static void eo_free(EoSerialize *serialize)
Definition data.h:452
Eif Eif_init(void)
Creates a new Eif with the serialization vtable initialized.
Definition protocol.c:1330
Note
eo_writer_init_with_capacity() pre-allocates the requested bytes but does not limit the writer — it will still grow if you write more. If capacity is 0 it behaves identically to eo_writer_init().