.TH ei 3erl "erl_interface 3.7.18" "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 With \fIei\fR\&, you can 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, and no dynamic memory (with the exception of \fIei_decode_fun()\fR\&), and is often quite fast\&. .LP It also handles C-nodes, C-programs that talks erlang distribution with erlang nodes (or other C-nodes) using the erlang distribution format\&. The difference between \fIei\fR\& and \fIerl_interface\fR\& is that \fIei\fR\& uses the binary format directly when sending and receiving terms\&. It is also thread safe, and using threads, one process can handle multiple C-nodes\&. The \fIerl_interface\fR\& library is built on top of \fIei\fR\&, but of legacy reasons, it doesn\&'t allow for multiple C-nodes\&. In general, \fIei\fR\& is the preferred way of doing C-nodes\&. .LP The decode and encode functions use a buffer 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 may crash\&. .LP All functions takes two parameter, \fIbuf\fR\& is a pointer to the buffer where the binary data is / will be, \fIindex\fR\& is a pointer to an index into the buffer\&. This parameter will be incremented with the size of the term decoded / encoded\&. The data is thus at \fIbuf[*index]\fR\& when an \fIei\fR\& function is called\&. .LP The encode functions all assumes that the \fIbuf\fR\& and \fIindex\fR\& parameters points to a buffer big enough for the data\&. To get the size of an encoded term, without encoding it, pass \fINULL\fR\& instead of a buffer pointer\&. The \fIindex\fR\& parameter will be incremented, but nothing will be encoded\&. This is the way in \fIei\fR\& to "preflight" term encoding\&. .LP There are also encode-functions that uses 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\&, uses a dynamic buffer\&. .LP All functions return \fI0\fR\& if successful, and \fI-1\fR\& if not\&. (For instance, if a term is not of the expected type, or the data to decode is not a valid erlang term\&.) .LP Some of the decode-functions needs a preallocated buffer\&. This buffer must be allocated big enough, and for non compound types the \fIei_get_type()\fR\& function returns the size required (note that for strings an extra byte is needed for the 0 string terminator)\&. .SH "DATA TYPES" .RS 2 .TP 2 .B erlang_char_encoding: .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\&. Latin1 and UTF8 are different extensions of 7-bit ASCII\&. All 7-bit ASCII characters are valid Latin1 and UTF8 characters\&. ASCII and Latin1 both represent each character by one byte\&. A UTF8 character can consist of one to four bytes\&. Note that these constants are bit-flags and can be combined with bitwise-or\&. .RE .RE .SH EXPORTS .LP .B void ei_set_compat_rel(release_number) .br .RS .LP Types: .RS 3 unsigned release_number; .br .RE .RE .RS .LP By default, the \fIei\fR\& library is only guaranteed to be compatible with other Erlang/OTP components from the same release as the \fIei\fR\& library itself\&. For example, \fIei\fR\& from the OTP R10 release is not compatible with an Erlang emulator from the OTP R9 release by default\&. .LP A call to \fIei_set_compat_rel(release_number)\fR\& sets the \fIei\fR\& library in compatibility mode of release \fIrelease_number\fR\&\&. Valid range of \fIrelease_number\fR\& is [7, current release]\&. This makes it possible to communicate with Erlang/OTP components from earlier releases\&. .LP .RS -4 .B Note: .RE If this function is called, it may only be called once and must be called before any other functions in the \fIei\fR\& library is called\&. .LP .RS -4 .B Warning: .RE You may run into trouble if this feature is used carelessly\&. Always make sure that all communicating components are either from the same Erlang/OTP release, or from release X and release Y where all components from release Y are in compatibility mode of release X\&. .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 Encodes a version magic number for the binary format\&. Must be the first token in a binary term\&. .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 Encodes a long integer in the binary format\&. Note that if the code is 64 bits the function ei_encode_long() is exactly the same as ei_encode_longlong()\&. .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 Encodes an unsigned long integer in the binary format\&. Note that if the code is 64 bits the function ei_encode_ulong() is exactly the same as ei_encode_ulonglong()\&. .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 Encodes a GCC \fIlong long\fR\& or Visual C++ \fI__int64\fR\& (64 bit) integer in the binary format\&. Note that this function is missing in the VxWorks port\&. .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 Encodes a GCC \fIunsigned long long\fR\& or Visual C++ \fIunsigned __int64\fR\& (64 bit) integer in the binary format\&. Note that this function is missing in the VxWorks port\&. .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 Encodes a GMP \fImpz_t\fR\& integer to binary format\&. To use this function the ei library needs to be configured and compiled to use the GMP library\&. .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 Encodes a double-precision (64 bit) floating point number in the binary format\&. .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 Encodes a boolean value, as the atom \fItrue\fR\& if p is not zero or \fIfalse\fR\& if p 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 Encodes a char (8-bit) as an integer between 0-255 in the binary format\&. Note that for historical reasons the integer argument is of type \fIchar\fR\&\&. Your C code should consider the given 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_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 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 should be zero-terminated, except for the \fIei_x_encode_string_len()\fR\& function\&. .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 Encodes an atom in the binary format\&. The \fIp\fR\& parameter is the name of the atom in latin1 encoding\&. Only upto \fIMAXATOMLEN-1\fR\& bytes are encoded\&. The name should be zero-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 Encodes an atom in the binary format with character encoding \fI\fBto_enc\fR\&\fR\& (latin1 or utf8)\&. The \fIp\fR\& parameter is the name of the atom with character encoding \fI\fBfrom_enc\fR\&\fR\& (ascii, latin1 or utf8)\&. The name must either be zero-terminated or a function variant with a \fIlen\fR\& parameter must be used\&. If \fIto_enc\fR\& is set to the bitwise-or\&'d combination \fI(ERLANG_LATIN1|ERLANG_UTF8)\fR\&, utf8 encoding is only used if the atom string can not be represented in latin1 encoding\&. .LP The encoding will fail if \fIp\fR\& is not a valid string in encoding \fIfrom_enc\fR\&, if the string is too long or if it can not be represented with character encoding \fIto_enc\fR\&\&. .LP These functions were introduced in R16 release of Erlang/OTP as part of a first step to support UTF8 atoms\&. Atoms encoded with \fIERLANG_UTF8\fR\& can not be decoded by earlier releases than R16\&. .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 Encodes a binary in the binary format\&. The data is at \fIp\fR\&, of \fIlen\fR\& bytes length\&. .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 Encodes an erlang process identifier, pid, in the binary format\&. The \fIp\fR\& parameter points to an \fIerlang_pid\fR\& structure (which should have been obtained earlier with \fIei_decode_pid()\fR\&)\&. .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 Encodes a fun in the binary format\&. The \fIp\fR\& parameter points to an \fIerlang_fun\fR\& structure\&. The \fIerlang_fun\fR\& is not freed automatically, the \fIfree_fun\fR\& should be called if the fun is not needed after encoding\&. .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 Encodes an erlang port in the binary format\&. The \fIp\fR\& parameter points to a \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 Encodes an erlang reference in the binary format\&. The \fIp\fR\& parameter points to a \fIerlang_ref\fR\& structure (which should have been obtained earlier with \fIei_decode_ref()\fR\&\&. .RE .LP .B int ei_encode_term(char *buf, int *index, void *t) .br .B int ei_x_encode_term(ei_x_buff* x, void *t) .br .RS .LP This function encodes an \fIETERM\fR\&, as obtained from \fIerl_interface\fR\&\&. The \fIt\fR\& parameter is actually an \fIETERM\fR\& pointer\&. This function doesn\&'t free the \fIETERM\fR\&\&. .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 This function encodes an erlang trace token in the binary format\&. The \fIp\fR\& parameter 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 This function 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 may contain another tuple or list\&. .LP E\&.g\&. 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_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 This function 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 may contain another list or tuple\&. .LP E\&.g\&. 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\&. Note 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_empty_list(char* buf, int* index) .br .B int ei_x_encode_empty_list(ei_x_buff* x) .br .RS .LP This function encodes an empty list\&. It\&'s often used at the tail of a list\&. .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 This function 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 E\&.g\&. 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 can not have duplicate keys\&. .RE .LP .B int ei_get_type(const char *buf, const int *index, int *type, int *size) .br .RS .LP This function returns the type in \fItype\fR\& and size in \fIsize\fR\& of the encoded term\&. For strings and atoms, size is the number of characters \fInot\fR\& including the terminating 0\&. For binaries, \fIsize\fR\& is the number of bytes\&. For lists and tuples, \fIsize\fR\& is the arity of the object\&. For other types, \fIsize\fR\& is 0\&. In all cases, \fIindex\fR\& is left unchanged\&. .RE .LP .B int ei_decode_version(const char *buf, int *index, int *version) .br .RS .LP This function 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_decode_long(const char *buf, int *index, long *p) .br .RS .LP This function decodes a long integer from the binary format\&. Note that if the code is 64 bits the function ei_decode_long() is exactly the same as ei_decode_longlong()\&. .RE .LP .B int ei_decode_ulong(const char *buf, int *index, unsigned long *p) .br .RS .LP This function decodes an unsigned long integer from the binary format\&. Note that if the code is 64 bits the function ei_decode_ulong() is exactly the same as ei_decode_ulonglong()\&. .RE .LP .B int ei_decode_longlong(const char *buf, int *index, long long *p) .br .RS .LP This function decodes a GCC \fIlong long\fR\& or Visual C++ \fI__int64\fR\& (64 bit) integer from the binary format\&. Note that this function is missing in the VxWorks port\&. .RE .LP .B int ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p) .br .RS .LP This function decodes a GCC \fIunsigned long long\fR\& or Visual C++ \fIunsigned __int64\fR\& (64 bit) integer from the binary format\&. Note that this function is missing in the VxWorks port\&. .RE .LP .B int ei_decode_bignum(const char *buf, int *index, mpz_t obj) .br .RS .LP This function decodes an integer in the binary format to a GMP \fImpz_t\fR\& integer\&. To use this function the ei library needs to be configured and compiled to use the GMP library\&. .RE .LP .B int ei_decode_double(const char *buf, int *index, double *p) .br .RS .LP This function decodes an double-precision (64 bit) floating point number from the binary format\&. .RE .LP .B int ei_decode_boolean(const char *buf, int *index, int *p) .br .RS .LP This function 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 This function decodes a char (8-bit) integer between 0-255 from the binary format\&. Note that for historical reasons the returned integer is of type \fIchar\fR\&\&. Your C code should consider the returned value 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_decode_string(const char *buf, int *index, char *p) .br .RS .LP This function decodes a string from the binary format\&. A string in erlang is a list of integers between 0 and 255\&. Note that since 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 null terminated so you need to add an extra byte to the memory requirement\&. .RE .LP .B int ei_decode_atom(const char *buf, int *index, char *p) .br .RS .LP This function decodes an atom from the binary format\&. The null terminated name of the atom is placed at \fIp\fR\&\&. There can be at most \fIMAXATOMLEN\fR\& bytes 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 This function decodes an atom from the binary format\&. The null 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 \fI\fB want\fR\&\fR\&\&. The original encoding used in the binary format (latin1 or utf8) can be obtained from \fI*was\fR\&\&. The actual encoding of the resulting string (7-bit ascii, latin1 or utf8) can be obtained from \fI*result\fR\&\&. Both \fIwas\fR\& and \fIresult\fR\& can be \fINULL\fR\&\&. \fI*result\fR\& may differ from \fIwant\fR\& if \fIwant\fR\& is a bitwise-or\&'d combination like \fIERLANG_LATIN1|ERLANG_UTF8\fR\& or if \fI*result\fR\& turn out to be pure 7-bit ascii (compatible with both latin1 and utf8)\&. .LP This function fails if the atom is too long for the buffer or if it can not be represented with encoding \fIwant\fR\&\&. .LP This function was introduced in R16 release of Erlang/OTP as part of a first step to support UTF8 atoms\&. .RE .LP .B int ei_decode_binary(const char *buf, int *index, void *p, long *len) .br .RS .LP This function decodes a binary from the binary format\&. The \fIlen\fR\& parameter is set to the actual size of the binary\&. Note that \fIei_decode_binary()\fR\& assumes that there are enough room for the binary\&. The size required can be fetched by \fIei_get_type()\fR\&\&. .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 This function decodes a fun from the binary format\&. The \fIp\fR\& parameter should be NULL 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 should 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_pid(const char *buf, int *index, erlang_pid *p) .br .RS .LP Decodes a pid, process identifier, from the binary format\&. .RE .LP .B int ei_decode_port(const char *buf, int *index, erlang_port *p) .br .RS .LP This function 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 This function decodes a reference from the binary format\&. .RE .LP .B int ei_decode_trace(const char *buf, int *index, erlang_trace *p) .br .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 This function decodes a tuple header, the number of elements is returned in \fIarity\fR\&\&. The tuple elements follows in order in the buffer\&. .RE .LP .B int ei_decode_list_header(const char *buf, int *index, int *arity) .br .RS .LP This function decodes a list header from the binary format\&. The number of elements is returned in \fIarity\fR\&\&. The \fIarity+1\fR\& elements follows (the last one is the tail of the list, normally an empty list\&.) If \fIarity\fR\& is \fI0\fR\&, it\&'s an empty list\&. .LP Note that lists are encoded as strings, if they consist entirely of integers in the range 0\&.\&.255\&. This function will not decode such strings, use \fIei_decode_string()\fR\& instead\&. .RE .LP .B int ei_decode_map_header(const char *buf, int *index, int *arity) .br .RS .LP This function 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 the following order: \fIK1, V1, K2, V2, \&.\&.\&., Kn, Vn\fR\&\&. This makes a total of \fIarity*2\fR\& terms\&. If \fIarity\fR\& is zero, it\&'s an empty map\&. A correctly encoded map does not have duplicate keys\&. .RE .LP .B int ei_decode_ei_term(const char* buf, int* index, ei_term* term) .br .RS .LP This function 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 1 on successful decoding, -1 on error, and 0 if the term seems alright, but does not fit in the \fIterm\fR\& structure\&. If it returns 1, the \fIindex\fR\& will be incremented, and the \fIterm\fR\& contains the decoded term\&. .LP The \fIterm\fR\& structure will contain the arity for a tuple or list, size for a binary, string or atom\&. It will contains a term if it\&'s any of the following: integer, float, atom, pid, port or ref\&. .RE .LP .B int ei_decode_term(const char *buf, int *index, void *t) .br .RS .LP This function decodes a term from the binary format\&. The term is return in \fIt\fR\& as a \fIETERM*\fR\&, so \fIt\fR\& is actually an \fIETERM**\fR\& (see \fIerl_interface(3erl)\fR\&\&. The term should later be deallocated\&. .LP Note that this function is located in the erl_interface library\&. .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 This function prints a term, in clear text, to the file given 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\&, the parameter \fIs\fR\& should point to a dynamically (malloc) allocated string of \fIBUFSIZ\fR\& bytes or a NULL pointer\&. The string may be reallocated (and \fI*s\fR\& may be updated) by this function if the result is more than \fIBUFSIZ\fR\& characters\&. The string returned is zero-terminated\&. .LP The return value is the number of characters written to the file or string, or -1 if \fIbuf[index]\fR\& doesn\&'t contain a valid term\&. Unfortunately, I/O errors on \fIfp\fR\& is not checked\&. .LP The argument \fIindex\fR\& is updated, i\&.e\&. this function can be viewed as en decode function that decodes a term into a human readable format\&. .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 Format a term, given as a string, to a buffer\&. This functions works like a sprintf for erlang terms\&. The \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 .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 instance, 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 The \fIei_x_format_wo_ver()\fR\& formats into a buffer, without the initial version byte\&. .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 This function allocates a new \fIei_x_buff\fR\& buffer\&. The fields of the structure pointed to by \fIx\fR\& parameter is filled in, and a default buffer is allocated\&. The \fIei_x_new_with_version()\fR\& also puts an initial version byte, that is used in the binary format\&. (So that \fIei_x_encode_version()\fR\& won\&'t be needed\&.) .RE .LP .B int ei_x_free(ei_x_buff* x) .br .RS .LP This function frees an \fIei_x_buff\fR\& buffer\&. The memory used by the buffer is returned to the OS\&. .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 These functions appends data at the end of the buffer \fIx\fR\&\&. .RE .LP .B int ei_skip_term(const char* buf, int* index) .br .RS .LP This function skips a term in the given buffer, it 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: just skip them and copy the binary term data to some buffer\&. .LP The function returns \fI0\fR\& on success and \fI-1\fR\& on failure\&. .RE .SH "DEBUG INFORMATION" .LP Some tips on what to check when the emulator doesn\&'t 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 ei_decode_-calls .LP .RE .SH "SEE ALSO" .LP erl_interface(3erl)