.TH ei 3erl "erl_interface 5.3.2.1" "Ericsson AB" "C Library Functions" .SH NAME ei \- Routines for handling the Erlang binary term format. .SH DESCRIPTION .LP The library \fIei\fR\& contains macros and functions to encode and decode the Erlang binary term format\&. .LP \fIei\fR\& allows you to convert atoms, lists, numbers, and binaries to and from the binary format\&. This is useful when writing port programs and drivers\&. \fIei\fR\& uses a given buffer, no dynamic memory (except \fIei_decode_fun()\fR\&) and is often quite fast\&. .LP \fIei\fR\& also handles C-nodes, C-programs that talks Erlang distribution with Erlang nodes (or other C-nodes) using the Erlang distribution format\&.The \fIei\fR\& library is thread safe, and using threads, one process can handle multiple C-nodes\&. .LP The decode and encode functions use a buffer and an index into the buffer, which points at the point where to encode and decode\&. The index is updated to point right after the term encoded/decoded\&. No checking is done whether the term fits in the buffer or not\&. If encoding goes outside the buffer, the program can crash\&. .LP All functions take two parameters: .RS 2 .TP 2 * \fIbuf\fR\& is a pointer to the buffer where the binary data is or will be\&. .LP .TP 2 * \fIindex\fR\& is a pointer to an index into the buffer\&. This parameter is incremented with the size of the term decoded/encoded\&. .LP .RE .LP The data is thus at \fIbuf[*index]\fR\& when an \fIei\fR\& function is called\&. .LP All encode functions assume that the \fIbuf\fR\& and \fIindex\fR\& parameters point to a buffer large enough for the data\&. To get the size of an encoded term, without encoding it, pass \fINULL\fR\& instead of a buffer pointer\&. Parameter \fIindex\fR\& is incremented, but nothing will be encoded\&. This is the way in \fIei\fR\& to "preflight" term encoding\&. .LP There are also encode functions that use a dynamic buffer\&. It is often more convenient to use these to encode data\&. All encode functions comes in two versions; those starting with \fIei_x_\fR\& use a dynamic buffer of type \fIei_x_buff\fR\&\&. .LP All functions return \fI0\fR\& if successful, otherwise \fI-1\fR\& (for example, if a term is not of the expected type, or the data to decode is an invalid Erlang term)\&. .LP Some of the decode functions need a pre-allocated buffer\&. This buffer must be allocated large enough, and for non-compound types the \fIei_get_type()\fR\& function returns the size required (notice that for strings an extra byte is needed for the \fINULL\fR\&-terminator)\&. .SH "DATA TYPES" .RS 2 .TP 2 .B \fIei_term\fR\&: .LP .nf typedef struct { char ei_type; int arity; int size; union { long i_val; double d_val; char atom_name[MAXATOMLEN_UTF8]; erlang_pid pid; erlang_port port; erlang_ref ref; } value; } ei_term; .fi .RS 2 .LP Structure written by \fIei_decode_ei_term()\fR\&\&. The \fIei_type\fR\& field is the type of the term which equals to what \fIei_get_type()\fR\& sets \fI*type\fR\& to\&. .RE .TP 2 .B \fIei_x_buff\fR\&: A dynamically resized buffer\&. It is a \fIstruct\fR\& with two fields of interest for the user: .RS 2 .TP 2 .B \fIchar *buff\fR\&: Pointer to the dynamically allocated buffer\&. .TP 2 .B \fIint index\fR\&: Offset to the next byte to write which also equals the amount of bytes currently written\&. .RE .RS 2 .LP An \fIei_x_buff\fR\& is initialized by calling either \fIei_x_new()\fR\& or \fIei_x_new_with_version()\fR\&\&. The memory used by an initialized \fIei_x_buff\fR\& is released by calling \fIei_x_free()\fR\&\&. .RE .TP 2 .B \fIerlang_char_encoding\fR\&: .LP .nf typedef enum { ERLANG_ASCII = 1, ERLANG_LATIN1 = 2, ERLANG_UTF8 = 4 } erlang_char_encoding; .fi .RS 2 .LP The character encodings used for atoms\&. \fIERLANG_ASCII\fR\& represents 7-bit ASCII\&. Latin-1 and UTF-8 are different extensions of 7-bit ASCII\&. All 7-bit ASCII characters are valid Latin-1 and UTF-8 characters\&. ASCII and Latin-1 both represent each character by one byte\&. An UTF-8 character can consist of 1-4 bytes\&. Notice that these constants are bit-flags and can be combined with bitwise OR\&. .RE .TP 2 .B \fIerlang_fun\fR\&: Opaque data type representing an Erlang fun\&. .TP 2 .B \fIerlang_pid\fR\&: Opaque data type representing an Erlang process identifier\&. .TP 2 .B \fIerlang_port\fR\&: Opaque data type representing an Erlang port identifier\&. .TP 2 .B \fIerlang_ref\fR\&: Opaque data type representing an Erlang reference\&. .TP 2 .B \fIerlang_trace\fR\&: Opaque data type representing an Erlang sequential trace token\&. .RE .SH EXPORTS .LP .B int ei_cmp_pids(erlang_pid *a, erlang_pid *b) .br .RS .LP Types: .RS 3 \fIerlang_pid\fR\& .br .RE .RE .RS .LP Compare two process identifiers\&. The comparison is done the same way as Erlang does\&. .LP Returns \fI0\fR\& if \fIa\fR\& and \fIb\fR\& are equal\&. Returns a value less than \fI0\fR\& if \fIa\fR\& compares as less than \fIb\fR\&\&. Returns a value larger than \fI0\fR\& if \fIa\fR\& compares as larger than \fIb\fR\&\&. .RE .LP .B int ei_cmp_ports(erlang_port *a, erlang_port *b) .br .RS .LP Types: .RS 3 \fIerlang_port\fR\& .br .RE .RE .RS .LP Compare two port identifiers\&. The comparison is done the same way as Erlang does\&. .LP Returns \fI0\fR\& if \fIa\fR\& and \fIb\fR\& are equal\&. Returns a value less than \fI0\fR\& if \fIa\fR\& compares as less than \fIb\fR\&\&. Returns a value larger than \fI0\fR\& if \fIa\fR\& compares as larger than \fIb\fR\&\&. .RE .LP .B int ei_cmp_refs(erlang_ref *a, erlang_ref *b) .br .RS .LP Types: .RS 3 \fIerlang_ref\fR\& .br .RE .RE .RS .LP Compare two references\&. The comparison is done the same way as Erlang does\&. .LP Returns \fI0\fR\& if \fIa\fR\& and \fIb\fR\& are equal\&. Returns a value less than \fI0\fR\& if \fIa\fR\& compares as less than \fIb\fR\&\&. Returns a value larger than \fI0\fR\& if \fIa\fR\& compares as larger than \fIb\fR\&\&. .RE .LP .B int ei_decode_atom(const char *buf, int *index, char *p) .br .RS .LP Decodes an atom from the binary format\&. The \fINULL\fR\&-terminated name of the atom is placed at \fIp\fR\&\&. At most \fIMAXATOMLEN\fR\& bytes can be placed in the buffer\&. .RE .LP .B int ei_decode_atom_as(const char *buf, int *index, char *p, int plen, erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result) .br .RS .LP Types: .RS 3 \fIerlang_char_encoding\fR\& .br .RE .RE .RS .LP Decodes an atom from the binary format\&. The \fINULL\fR\&-terminated name of the atom is placed in buffer at \fIp\fR\& of length \fIplen\fR\& bytes\&. .LP The wanted string encoding is specified by \fIwant\fR\&\&. The original encoding used in the binary format (Latin-1 or UTF-8) can be obtained from \fI*was\fR\&\&. The encoding of the resulting string (7-bit ASCII, Latin-1, or UTF-8) can be obtained from \fI*result\fR\&\&. Both \fIwas\fR\& and \fIresult\fR\& can be \fINULL\fR\&\&. \fI*result\fR\& can differ from \fIwant\fR\& if \fIwant\fR\& is a bitwise OR\&'d combination like \fIERLANG_LATIN1|ERLANG_UTF8\fR\& or if \fI*result\fR\& turns out to be pure 7-bit ASCII (compatible with both Latin-1 and UTF-8)\&. .LP This function fails if the atom is too long for the buffer or if it cannot be represented with encoding \fIwant\fR\&\&. .LP This function was introduced in Erlang/OTP R16 as part of a first step to support UTF-8 atoms\&. .RE .LP .B int ei_decode_bignum(const char *buf, int *index, mpz_t obj) .br .RS .LP Decodes an integer in the binary format to a GMP \fImpz_t\fR\& integer\&. To use this function, the \fIei\fR\& library must be configured and compiled to use the GMP library\&. .RE .LP .B int ei_decode_binary(const char *buf, int *index, void *p, long *len) .br .RS .LP Decodes a binary from the binary format\&. Parameter \fIlen\fR\& is set to the actual size of the binary\&. Notice that \fIei_decode_binary()\fR\& assumes that there is enough room for the binary\&. The size required can be fetched by \fIei_get_type()\fR\&\&. .RE .LP .B int ei_decode_bitstring(const char *buf, int *index, const char **pp, unsigned int *bitoffsp, size_t *nbitsp) .br .RS .LP Decodes a bit string from the binary format\&. .RS 2 .TP 2 .B \fIpp\fR\&: Either \fINULL\fR\& or \fI*pp\fR\& returns a pointer to the first byte of the bit string\&. The returned bit string is readable as long as the buffer pointed to by \fIbuf\fR\& is readable and not written to\&. .TP 2 .B \fIbitoffsp\fR\&: Either \fINULL\fR\& or \fI*bitoffsp\fR\& returns the number of unused bits in the first byte pointed to by \fI*pp\fR\&\&. The value of \fI*bitoffsp\fR\& is between 0 and 7\&. Unused bits in the first byte are the most significant bits\&. .TP 2 .B \fInbitsp\fR\&: Either \fINULL\fR\& or \fI*nbitsp\fR\& returns the length of the bit string in \fIbits\fR\&\&. .RE .LP Returns \fI0\fR\& if it was a bit string term\&. .LP The number of \fIbytes\fR\& pointed to by \fI*pp\fR\&, which are part of the bit string, is \fI(*bitoffsp + *nbitsp + 7)/8\fR\&\&. If \fI(*bitoffsp + *bitsp)%8 > 0\fR\& then only \fI(*bitoffsp + *bitsp)%8\fR\& bits of the last byte are used\&. Unused bits in the last byte are the least significant bits\&. .LP The values of unused bits in the first and last byte are undefined and cannot be relied on\&. .LP Number of bits may be divisible by 8, which means a binary decodable by \fIei_decode_binary\fR\& is also decodable by \fIei_decode_bitstring\fR\&\&. .RE .LP .B int ei_decode_boolean(const char *buf, int *index, int *p) .br .RS .LP Decodes a boolean value from the binary format\&. A boolean is actually an atom, \fItrue\fR\& decodes 1 and \fIfalse\fR\& decodes 0\&. .RE .LP .B int ei_decode_char(const char *buf, int *index, char *p) .br .RS .LP Decodes a char (8-bit) integer between 0-255 from the binary format\&. For historical reasons the returned integer is of type \fIchar\fR\&\&. Your C code is to consider the returned value to be of type \fIunsigned char\fR\& even if the C compilers and system can define \fIchar\fR\& to be signed\&. .RE .LP .B int ei_decode_double(const char *buf, int *index, double *p) .br .RS .LP Decodes a double-precision (64-bit) floating point number from the binary format\&. .RE .LP .B int ei_decode_ei_term(const char* buf, int* index, ei_term* term) .br .RS .LP Types: .RS 3 \fIei_term\fR\& .br .RE .RE .RS .LP Decodes any term, or at least tries to\&. If the term pointed at by \fI*index\fR\& in \fIbuf\fR\& fits in the \fIterm\fR\& union, it is decoded, and the appropriate field in \fIterm->value\fR\& is set, and \fI*index\fR\& is incremented by the term size\&. .LP The function returns \fI1\fR\& on successful decoding, \fI-1\fR\& on error, and \fI0\fR\& if the term seems alright, but does not fit in the \fIterm\fR\& structure\&. If \fI1\fR\& is returned, the \fIindex\fR\& is incremented, and \fIterm\fR\& contains the decoded term\&. .LP The \fIterm\fR\& structure contains the arity for a tuple or list, size for a binary, string, or atom\&. It contains a term if it is any of the following: integer, float, atom, pid, port, or ref\&. .RE .LP .B int ei_decode_fun(const char *buf, int *index, erlang_fun *p) .br .B void free_fun(erlang_fun* f) .br .RS .LP Types: .RS 3 \fIerlang_fun\fR\& .br .RE .RE .RS .LP Decodes a fun from the binary format\&. Parameter \fIp\fR\& is to be \fINULL\fR\& or point to an \fIerlang_fun\fR\& structure\&. This is the only decode function that allocates memory\&. When the \fIerlang_fun\fR\& is no longer needed, it is to be freed with \fIfree_fun\fR\&\&. (This has to do with the arbitrary size of the environment for a fun\&.) .RE .LP .B int ei_decode_iodata(const char *buf, int *index, int *size, char *outbuf) .br .RS .LP Decodes a term of the type \fIiodata()\fR\&\&. The \fIiodata()\fR\& term will be flattened an written into the buffer pointed to by the \fIoutbuf\fR\& argument\&. The byte size of the \fIiodata\fR\& is written into the integer variable pointed to by the \fIsize\fR\& argument\&. Both \fIsize\fR\& and \fIoutbuf\fR\& can be set to \fINULL\fR\&\&. The integer pointed to by the \fIindex\fR\& argument is updated to refer to the term following after the \fIiodata()\fR\& term regardless of the the state of the \fIsize\fR\& and the \fIoutbuf\fR\& arguments\&. .LP Note that the buffer pointed to by the \fIoutbuf\fR\& argument must be large enough if a non \fINULL\fR\& value is passed as \fIoutbuf\fR\&\&. You typically want to call \fIei_decode_iodata()\fR\& twice\&. First with a non \fINULL\fR\& \fIsize\fR\& argument and a \fINULL\fR\& \fIoutbuf\fR\& argument in order to determine the size of the buffer needed, and then once again in order to do the actual decoding\&. Note that the integer pointed to by \fIindex\fR\& will be updated by the call determining the size as well, so you need to reset it before the second call doing the actual decoding\&. .LP Returns \fI0\fR\& on success and \fI-1\fR\& on failure\&. Failure might be either due to invalid encoding of the term or due to the term not being of the type \fIiodata()\fR\&\&. On failure, the integer pointed to by the \fIindex\fR\& argument will be updated to refer to the sub term where the failure was detected\&. .RE .LP .B int ei_decode_list_header(const char *buf, int *index, int *arity) .br .RS .LP Decodes a list header from the binary format\&. The number of elements is returned in \fIarity\fR\&\&. The \fIarity+1\fR\& elements follow (the last one is the tail of the list, normally an empty list)\&. If \fIarity\fR\& is \fI0\fR\&, it is an empty list\&. .LP Notice that lists are encoded as strings if they consist entirely of integers in the range 0\&.\&.255\&. This function do not decode such strings, use \fIei_decode_string()\fR\& instead\&. .RE .LP .B int ei_decode_long(const char *buf, int *index, long *p) .br .RS .LP Decodes a long integer from the binary format\&. If the code is 64 bits, the function \fIei_decode_long()\fR\& is the same as \fIei_decode_longlong()\fR\&\&. .RE .LP .B int ei_decode_longlong(const char *buf, int *index, long long *p) .br .RS .LP Decodes a GCC \fIlong long\fR\& or Visual C++ \fI__int64\fR\& (64-bit) integer from the binary format\&. .RE .LP .B int ei_decode_map_header(const char *buf, int *index, int *arity) .br .RS .LP Decodes a map header from the binary format\&. The number of key-value pairs is returned in \fI*arity\fR\&\&. Keys and values follow in this order: \fIK1, V1, K2, V2, \&.\&.\&., Kn, Vn\fR\&\&. This makes a total of \fIarity*2\fR\& terms\&. If \fIarity\fR\& is zero, it is an empty map\&. A correctly encoded map does not have duplicate keys\&. .RE .LP .B int ei_decode_pid(const char *buf, int *index, erlang_pid *p) .br .RS .LP Types: .RS 3 \fIerlang_pid\fR\& .br .RE .RE .RS .LP Decodes a process identifier (pid) from the binary format\&. .RE .LP .B int ei_decode_port(const char *buf, int *index, erlang_port *p) .br .RS .LP Types: .RS 3 \fIerlang_port\fR\& .br .RE .RE .RS .LP Decodes a port identifier from the binary format\&. .RE .LP .B int ei_decode_ref(const char *buf, int *index, erlang_ref *p) .br .RS .LP Types: .RS 3 \fIerlang_ref\fR\& .br .RE .RE .RS .LP Decodes a reference from the binary format\&. .RE .LP .B int ei_decode_string(const char *buf, int *index, char *p) .br .RS .LP Decodes a string from the binary format\&. A string in Erlang is a list of integers between 0 and 255\&. Notice that as the string is just a list, sometimes lists are encoded as strings by \fIterm_to_binary/1\fR\&, even if it was not intended\&. .LP The string is copied to \fIp\fR\&, and enough space must be allocated\&. The returned string is \fINULL\fR\&-terminated, so you must add an extra byte to the memory requirement\&. .RE .LP .B int ei_decode_trace(const char *buf, int *index, erlang_trace *p) .br .RS .LP Types: .RS 3 \fIerlang_trace\fR\& .br .RE .RE .RS .LP Decodes an Erlang trace token from the binary format\&. .RE .LP .B int ei_decode_tuple_header(const char *buf, int *index, int *arity) .br .RS .LP Decodes a tuple header, the number of elements is returned in \fIarity\fR\&\&. The tuple elements follow in order in the buffer\&. .RE .LP .B int ei_decode_ulong(const char *buf, int *index, unsigned long *p) .br .RS .LP Decodes an unsigned long integer from the binary format\&. If the code is 64 bits, the function \fIei_decode_ulong()\fR\& is the same as \fIei_decode_ulonglong()\fR\&\&. .RE .LP .B int ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p) .br .RS .LP Decodes a GCC \fIunsigned long long\fR\& or Visual C++ \fIunsigned __int64\fR\& (64-bit) integer from the binary format\&. .RE .LP .B int ei_decode_version(const char *buf, int *index, int *version) .br .RS .LP Decodes the version magic number for the Erlang binary term format\&. It must be the first token in a binary term\&. .RE .LP .B int ei_encode_atom(char *buf, int *index, const char *p) .br .B int ei_encode_atom_len(char *buf, int *index, const char *p, int len) .br .B int ei_x_encode_atom(ei_x_buff* x, const char *p) .br .B int ei_x_encode_atom_len(ei_x_buff* x, const char *p, int len) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes an atom in the binary format\&. Parameter \fIp\fR\& is the name of the atom in Latin-1 encoding\&. Only up to \fIMAXATOMLEN-1\fR\& bytes are encoded\&. The name is to be \fINULL\fR\&-terminated, except for the \fIei_x_encode_atom_len()\fR\& function\&. .RE .LP .B int ei_encode_atom_as(char *buf, int *index, const char *p, erlang_char_encoding from_enc, erlang_char_encoding to_enc) .br .B int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len, erlang_char_encoding from_enc, erlang_char_encoding to_enc) .br .B int ei_x_encode_atom_as(ei_x_buff* x, const char *p, erlang_char_encoding from_enc, erlang_char_encoding to_enc) .br .B int ei_x_encode_atom_len_as(ei_x_buff* x, const char *p, int len, erlang_char_encoding from_enc, erlang_char_encoding to_enc) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br \fIerlang_char_encoding\fR\& .br .RE .RE .RS .LP Encodes an atom in the binary format\&. Parameter \fIp\fR\& is the name of the atom with character encoding \fIfrom_enc\fR\& (ASCII, Latin-1, or UTF-8)\&. The name must either be \fINULL\fR\&-terminated or a function variant with a \fIlen\fR\& parameter must be used\&. .LP The encoding fails if \fIp\fR\& is not a valid string in encoding \fIfrom_enc\fR\&\&. .LP Argument \fIto_enc\fR\& is ignored\&. As from Erlang/OTP 20 the encoding is always done in UTF-8 which is readable by nodes as old as Erlang/OTP R16\&. .RE .LP .B int ei_encode_bignum(char *buf, int *index, mpz_t obj) .br .B int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a GMP \fImpz_t\fR\& integer to binary format\&. To use this function, the \fIei\fR\& library must be configured and compiled to use the GMP library\&. .RE .LP .B int ei_encode_binary(char *buf, int *index, const void *p, long len) .br .B int ei_x_encode_binary(ei_x_buff* x, const void *p, long len) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a binary in the binary format\&. The data is at \fIp\fR\&, of \fIlen\fR\& bytes length\&. .RE .LP .B int ei_encode_bitstring(char *buf, int *index, const char *p, size_t bitoffs, size_t nbits) .br .B int ei_x_encode_bitstring(ei_x_buff* x, const char *p, size_t bitoffs, size_t nbits) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a bit string in the binary format\&. .LP The data is at \fIp\fR\&\&. The length of the bit string is \fInbits\fR\& bits\&. The first \fIbitoffs\fR\& bits of the data at \fIp\fR\& are unused\&. The first byte which is part of the bit string is \fIp[bitoffs/8]\fR\&\&. The \fIbitoffs%8\fR\& most significant bits of the first byte \fIp[bitoffs/8]\fR\& are unused\&. .LP The number of bytes which is part of the bit string is \fI(bitoffs + nbits + 7)/8\fR\&\&. If \fI(bitoffs + nbits)%8 > 0\fR\& then only \fI(bitoffs + nbits)%8\fR\& bits of the last byte are used\&. Unused bits in the last byte are the least significant bits\&. .LP The values of unused bits are disregarded and does not need to be cleared\&. .RE .LP .B int ei_encode_boolean(char *buf, int *index, int p) .br .B int ei_x_encode_boolean(ei_x_buff* x, int p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a boolean value as the atom \fItrue\fR\& if \fIp\fR\& is not zero, or \fIfalse\fR\& if \fIp\fR\& is zero\&. .RE .LP .B int ei_encode_char(char *buf, int *index, char p) .br .B int ei_x_encode_char(ei_x_buff* x, char p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a char (8-bit) as an integer between 0-255 in the binary format\&. For historical reasons the integer argument is of type \fIchar\fR\&\&. Your C code is to consider the specified argument to be of type \fIunsigned char\fR\& even if the C compilers and system may define \fIchar\fR\& to be signed\&. .RE .LP .B int ei_encode_double(char *buf, int *index, double p) .br .B int ei_x_encode_double(ei_x_buff* x, double p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a double-precision (64-bit) floating point number in the binary format\&. .LP Returns \fI-1\fR\& if the floating point number is not finite\&. .RE .LP .B int ei_encode_empty_list(char* buf, int* index) .br .B int ei_x_encode_empty_list(ei_x_buff* x) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes an empty list\&. It is often used at the tail of a list\&. .RE .LP .B int ei_encode_fun(char *buf, int *index, const erlang_fun *p) .br .B int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br \fIerlang_fun\fR\& .br .RE .RE .RS .LP Encodes a fun in the binary format\&. Parameter \fIp\fR\& points to an \fIerlang_fun\fR\& structure\&. The \fIerlang_fun\fR\& is not freed automatically, the \fIfree_fun\fR\& is to be called if the fun is not needed after encoding\&. .RE .LP .B int ei_encode_list_header(char *buf, int *index, int arity) .br .B int ei_x_encode_list_header(ei_x_buff* x, int arity) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a list header, with a specified arity\&. The next \fIarity+1\fR\& terms are the elements (actually its \fIarity\fR\& cons cells) and the tail of the list\&. Lists and tuples are encoded recursively, so that a list can contain another list or tuple\&. .LP For example, to encode the list \fI[c, d, [e | f]]\fR\&: .LP .nf ei_encode_list_header(buf, &i, 3); ei_encode_atom(buf, &i, "c"); ei_encode_atom(buf, &i, "d"); ei_encode_list_header(buf, &i, 1); ei_encode_atom(buf, &i, "e"); ei_encode_atom(buf, &i, "f"); ei_encode_empty_list(buf, &i); .fi .LP .RS -4 .B Note: .RE It may seem that there is no way to create a list without knowing the number of elements in advance\&. But indeed there is a way\&. Notice that the list \fI[a, b, c]\fR\& can be written as \fI[a | [b | [c]]]\fR\&\&. Using this, a list can be written as conses\&. .LP To encode a list, without knowing the arity in advance: .LP .nf while (something()) { ei_x_encode_list_header(&x, 1); ei_x_encode_ulong(&x, i); /* just an example */ } ei_x_encode_empty_list(&x); .fi .RE .LP .B int ei_encode_long(char *buf, int *index, long p) .br .B int ei_x_encode_long(ei_x_buff* x, long p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a long integer in the binary format\&. If the code is 64 bits, the function \fIei_encode_long()\fR\& is the same as \fIei_encode_longlong()\fR\&\&. .RE .LP .B int ei_encode_longlong(char *buf, int *index, long long p) .br .B int ei_x_encode_longlong(ei_x_buff* x, long long p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a GCC \fIlong long\fR\& or Visual C++ \fI__int64\fR\& (64-bit) integer in the binary format\&. .RE .LP .B int ei_encode_map_header(char *buf, int *index, int arity) .br .B int ei_x_encode_map_header(ei_x_buff* x, int arity) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a map header, with a specified arity\&. The next \fIarity*2\fR\& terms encoded will be the keys and values of the map encoded in the following order: \fIK1, V1, K2, V2, \&.\&.\&., Kn, Vn\fR\&\&. .LP For example, to encode the map \fI#{a => "Apple", b => "Banana"}\fR\&: .LP .nf ei_x_encode_map_header(&x, 2); ei_x_encode_atom(&x, "a"); ei_x_encode_string(&x, "Apple"); ei_x_encode_atom(&x, "b"); ei_x_encode_string(&x, "Banana"); .fi .LP A correctly encoded map cannot have duplicate keys\&. .RE .LP .B int ei_encode_pid(char *buf, int *index, const erlang_pid *p) .br .B int ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br \fIerlang_pid\fR\& .br .RE .RE .RS .LP Encodes an Erlang process identifier (pid) in the binary format\&. Parameter \fIp\fR\& points to an \fIerlang_pid\fR\& structure which should either have been obtained earlier with \fIei_decode_pid()\fR\&, \fIei_self()\fR\& or created by \fIei_make_pid()\fR\&\&. .RE .LP .B int ei_encode_port(char *buf, int *index, const erlang_port *p) .br .B int ei_x_encode_port(ei_x_buff* x, const erlang_port *p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br \fIerlang_port\fR\& .br .RE .RE .RS .LP Encodes an Erlang port in the binary format\&. Parameter \fIp\fR\& points to an \fIerlang_port\fR\& structure which should have been obtained earlier with \fIei_decode_port()\fR\&, .RE .LP .B int ei_encode_ref(char *buf, int *index, const erlang_ref *p) .br .B int ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br \fIerlang_ref\fR\& .br .RE .RE .RS .LP Encodes an Erlang reference in the binary format\&. Parameter \fIp\fR\& points to an \fIerlang_ref\fR\& structure which either should have been obtained earlier with \fIei_decode_ref()\fR\&, or created by \fIei_make_ref()\fR\&\&. .RE .LP .B int ei_encode_string(char *buf, int *index, const char *p) .br .B int ei_encode_string_len(char *buf, int *index, const char *p, int len) .br .B int ei_x_encode_string(ei_x_buff* x, const char *p) .br .B int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a string in the binary format\&. (A string in Erlang is a list, but is encoded as a character array in the binary format\&.) The string is to be \fINULL\fR\&-terminated, except for the \fIei_x_encode_string_len()\fR\& function\&. .RE .LP .B int ei_encode_trace(char *buf, int *index, const erlang_trace *p) .br .B int ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br \fIerlang_trace\fR\& .br .RE .RE .RS .LP Encodes an Erlang trace token in the binary format\&. Parameter \fIp\fR\& points to a \fIerlang_trace\fR\& structure which should have been obtained earlier with \fIei_decode_trace()\fR\&\&. .RE .LP .B int ei_encode_tuple_header(char *buf, int *index, int arity) .br .B int ei_x_encode_tuple_header(ei_x_buff* x, int arity) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a tuple header, with a specified arity\&. The next \fIarity\fR\& terms encoded will be the elements of the tuple\&. Tuples and lists are encoded recursively, so that a tuple can contain another tuple or list\&. .LP For example, to encode the tuple \fI{a, {b, {}}}\fR\&: .LP .nf ei_encode_tuple_header(buf, &i, 2); ei_encode_atom(buf, &i, "a"); ei_encode_tuple_header(buf, &i, 2); ei_encode_atom(buf, &i, "b"); ei_encode_tuple_header(buf, &i, 0); .fi .RE .LP .B int ei_encode_ulong(char *buf, int *index, unsigned long p) .br .B int ei_x_encode_ulong(ei_x_buff* x, unsigned long p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes an unsigned long integer in the binary format\&. If the code is 64 bits, the function \fIei_encode_ulong()\fR\& is the same as \fIei_encode_ulonglong()\fR\&\&. .RE .LP .B int ei_encode_ulonglong(char *buf, int *index, unsigned long long p) .br .B int ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a GCC \fIunsigned long long\fR\& or Visual C++ \fIunsigned __int64\fR\& (64-bit) integer in the binary format\&. .RE .LP .B int ei_encode_version(char *buf, int *index) .br .B int ei_x_encode_version(ei_x_buff* x) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Encodes a version magic number for the binary format\&. Must be the first token in a binary term\&. .RE .LP .B int ei_get_type(const char *buf, const int *index, int *type, int *size) .br .RS .LP Returns the type in \fI*type\fR\& and size in \fI*size\fR\& of the encoded term\&. For strings and atoms, size is the number of characters \fInot\fR\& including the terminating \fINULL\fR\&\&. For binaries and bitstrings, \fI*size\fR\& is the number of bytes\&. For lists, tuples and maps, \fI*size\fR\& is the arity of the object\&. For bignum integers, \fI*size\fR\& is the number of bytes for the absolute value of the bignum\&. For other types, \fI*size\fR\& is 0\&. In all cases, \fIindex\fR\& is left unchanged\&. .LP Currently \fI*type\fR\& is one of: .RS 2 .TP 2 .B ERL_ATOM_EXT: Decode using either \fIei_decode_atom()\fR\&, \fIei_decode_atom_as()\fR\&, or \fIei_decode_boolean()\fR\&\&. .TP 2 .B ERL_BINARY_EXT: Decode using either \fIei_decode_binary()\fR\&, \fIei_decode_bitstring()\fR\&, or \fIei_decode_iodata()\fR\&\&. .TP 2 .B ERL_BIT_BINARY_EXT: Decode using \fIei_decode_bitstring()\fR\&\&. .TP 2 .B ERL_FLOAT_EXT: Decode using \fIei_decode_double()\fR\&\&. .TP 2 .B ERL_NEW_FUN_EXT .br ERL_FUN_EXT .br ERL_EXPORT_EXT: Decode using \fIei_decode_fun()\fR\&\&. .TP 2 .B ERL_SMALL_INTEGER_EXT .br ERL_INTEGER_EXT .br ERL_SMALL_BIG_EXT .br ERL_LARGE_BIG_EXT: Decode using either \fIei_decode_char()\fR\&, \fIei_decode_long()\fR\&, \fIei_decode_longlong()\fR\&, \fIei_decode_ulong()\fR\&, \fIei_decode_ulonglong()\fR\&, or \fIei_decode_bignum()\fR\&\&. .TP 2 .B ERL_LIST_EXT .br ERL_NIL_EXT: Decode using either \fIei_decode_list_header()\fR\&, or \fIei_decode_iodata()\fR\&\&. .TP 2 .B ERL_STRING_EXT: Decode using either \fIei_decode_string()\fR\&, or \fIei_decode_iodata()\fR\&\&. .TP 2 .B ERL_MAP_EXT: Decode using \fIei_decode_map_header()\fR\&\&. .TP 2 .B ERL_PID_EXT: Decode using \fIei_decode_pid()\fR\&\&. .TP 2 .B ERL_PORT_EXT: Decode using \fIei_decode_port()\fR\&\&. .TP 2 .B ERL_NEW_REFERENCE_EXT: Decode using \fIei_decode_ref()\fR\&\&. .TP 2 .B ERL_SMALL_TUPLE_EXT .br ERL_LARGE_TUPLE_EXT: Decode using \fIei_decode_tuple_header()\fR\&\&. .RE .LP Instead of decoding a term you can also skipped past it if you are not interested in the data by usage of \fIei_skip_term()\fR\&\&. .RE .LP .B int ei_init(void) .br .RS .LP Initialize the \fIei\fR\& library\&. This function should be called once (and only once) before calling any other functionality in the \fIei\fR\& library\&. .LP On success zero is returned\&. On failure a posix error code is returned\&. .RE .LP .B int ei_print_term(FILE* fp, const char* buf, int* index) .br .B int ei_s_print_term(char** s, const char* buf, int* index) .br .RS .LP Prints a term, in clear text, to the file specified by \fIfp\fR\&, or the buffer pointed to by \fIs\fR\&\&. It tries to resemble the term printing in the Erlang shell\&. .LP In \fIei_s_print_term()\fR\&, parameter \fIs\fR\& is to point to a dynamically (malloc) allocated string of \fIBUFSIZ\fR\& bytes or a \fINULL\fR\& pointer\&. The string can be reallocated (and \fI*s\fR\& can be updated) by this function if the result is more than \fIBUFSIZ\fR\& characters\&. The string returned is \fINULL\fR\&-terminated\&. .LP The return value is the number of characters written to the file or string, or \fI-1\fR\& if \fIbuf[index]\fR\& does not contain a valid term\&. Unfortunately, I/O errors on \fIfp\fR\& is not checked\&. .LP Argument \fIindex\fR\& is updated, that is, this function can be viewed as a decode function that decodes a term into a human-readable format\&. .RE .LP .B void ei_set_compat_rel(unsigned release_number) .br .RS .LP In general, the \fIei\fR\& library is guaranteed to be compatible with other Erlang/OTP components that are 2 major releases older or newer than the \fIei\fR\& library itself\&. .LP Sometimes an exception to the above rule has to be made to make new features (or even bug fixes) possible\&. A call to \fIei_set_compat_rel(release_number)\fR\& sets the \fIei\fR\& library in compatibility mode of OTP release \fIrelease_number\fR\&\&. .LP The only useful value for \fIrelease_number\fR\& is currently \fI21\fR\&\&. This will only be useful and have an effect if \fIbit strings\fR\& or \fIexport funs\fR\& are received from a connected node\&. Before OTP 22, bit strings and export funs were not supported by \fIei\fR\&\&. They were instead encoded using an undocumented fallback tuple format when sent from the emulator to \fIei\fR\&: .RS 2 .TP 2 .B \fIBit string\fR\&: The term \fI<<42, 1:1>>\fR\& was encoded as \fI{<<42, 128>>, 1}\fR\&\&. The first element of the tuple is a binary and the second element denotes how many bits of the last bytes are part of the bit string\&. In this example only the most significant bit of the last byte (128) is part of the bit string\&. .TP 2 .B \fIExport fun\fR\&: The term \fIfun lists:map/2\fR\& was encoded as \fI{lists,map}\fR\&\&. A tuple with the module, function and a missing arity\&. .RE .LP If \fIei_set_compat_rel(21)\fR\& is \fInot\fR\& called then a connected emulator will send bit strings and export funs correctly encoded\&. The functions \fIei_decode_bitstring\fR\& and \fIei_decode_fun\fR\& has to be used to decode such terms\&. Calling \fIei_set_compat_rel(21)\fR\& should only be done as a workaround to keep an old implementation alive, which expects to receive the undocumented tuple formats for bit strings and/or export funs\&. .LP .RS -4 .B Note: .RE If this function is called, it can only be called once and must be called before any other functions in the \fIei\fR\& library are called\&. .RE .LP .B int ei_skip_term(const char* buf, int* index) .br .RS .LP Skips a term in the specified buffer; recursively skips elements of lists and tuples, so that a full term is skipped\&. This is a way to get the size of an Erlang term\&. .LP \fIbuf\fR\& is the buffer\&. .LP \fIindex\fR\& is updated to point right after the term in the buffer\&. .LP .RS -4 .B Note: .RE This can be useful when you want to hold arbitrary terms: skip them and copy the binary term data to some buffer\&. .LP Returns \fI0\fR\& on success, otherwise \fI-1\fR\&\&. .RE .LP .B int ei_x_append(ei_x_buff* x, const ei_x_buff* x2) .br .B int ei_x_append_buf(ei_x_buff* x, const char* buf, int len) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Appends data at the end of buffer \fIx\fR\&\&. .RE .LP .B int ei_x_format(ei_x_buff* x, const char* fmt, ...) .br .B int ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ... ) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br \fIerlang_pid\fR\& .br .RE .RE .RS .LP Formats a term, given as a string, to a buffer\&. Works like a sprintf for Erlang terms\&. \fIfmt\fR\& contains a format string, with arguments like \fI~d\fR\&, to insert terms from variables\&. The following formats are supported (with the C types given): .LP .nf ~a An atom, char* ~c A character, char ~s A string, char* ~i An integer, int ~l A long integer, long int ~u A unsigned long integer, unsigned long int ~f A float, float ~d A double float, double float ~p An Erlang pid, erlang_pid* .fi .LP For example, to encode a tuple with some stuff: .LP .nf ei_x_format("{~a,~i,~d}", "numbers", 12, 3.14159) encodes the tuple {numbers,12,3.14159} .fi .LP \fIei_x_format_wo_ver()\fR\& formats into a buffer, without the initial version byte\&. .RE .LP .B int ei_x_free(ei_x_buff* x) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Deallocates the dynamically allocated content of the buffer referred by \fIx\fR\&\&. After deallocation, the \fIbuff\fR\& field is set to \fINULL\fR\&\&. .RE .LP .B int ei_x_new(ei_x_buff* x) .br .B int ei_x_new_with_version(ei_x_buff* x) .br .RS .LP Types: .RS 3 \fIei_x_buff\fR\& .br .RE .RE .RS .LP Initialize the dynamically realizable buffer referred to by \fIx\fR\&\&. The fields of the structure pointed to by parameter \fIx\fR\& is filled in, and a default buffer is allocated\&. \fIei_x_new_with_version()\fR\& also puts an initial version byte, which is used in the binary format (so that \fIei_x_encode_version()\fR\& will not be needed\&.) .RE .SH "DEBUG INFORMATION" .LP Some tips on what to check when the emulator does not seem to receive the terms that you send: .RS 2 .TP 2 * Be careful with the version header, use \fIei_x_new_with_version()\fR\& when appropriate\&. .LP .TP 2 * Turn on distribution tracing on the Erlang node\&. .LP .TP 2 * Check the result codes from \fIei_decode_-calls\fR\&\&. .LP .RE