From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- lib/erl_interface/doc/src/ei.xml | 728 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 728 insertions(+) create mode 100644 lib/erl_interface/doc/src/ei.xml (limited to 'lib/erl_interface/doc/src/ei.xml') diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml new file mode 100644 index 0000000000..2f65a8c375 --- /dev/null +++ b/lib/erl_interface/doc/src/ei.xml @@ -0,0 +1,728 @@ + + + + +
+ + 20012009 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + ei + Jakob Cederlund + Kent Boortz + 1 + Kenneth Lundin + + 2000-11-27 + PA1 + ei.sgml +
+ ei + routines for handling the erlang binary term format + +

The library contains macros and functions to encode + and decode the erlang binary term format.

+

With , you can convert atoms, lists, numbers and + binaries to and from the binary format. This is useful when + writing port programs and drivers. uses a given + buffer, and no dynamic memory (with the exception of + ), and is often quite fast.

+

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 and + is that 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 library is built on top of + , but of legacy reasons, it doesn't allow for multiple + C-nodes. In general, is the preferred way of doing + C-nodes.

+

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.

+

All functions takes two parameter, is a pointer to + the buffer where the binary data is / will be, 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 when an function is + called.

+

The encode functions all assumes that the and + parameters points to a buffer big enough for the + data. To get the size of an encoded term, without encoding it, + pass instead of a buffer pointer. The + parameter will be incremented, but nothing will be encoded. This + is the way in to "preflight" term encoding.

+

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 , + uses a dynamic buffer.

+

All functions return if successful, and if + not. (For instance, if a term is not of the expected type, or + the data to decode is not a valid erlang term.)

+

Some of the decode-functions needs a preallocated buffer. This + buffer must be allocated big enough, and for non compound types + the + function returns the size required (note that for strings an + extra byte is needed for the 0 string terminator).

+
+ + + voidei_set_compat_rel(release_number) + Set the ei library in compatibility mode + + unsigned release_number; + + + +

By default, the library is only guaranteed + to be compatible with other Erlang/OTP components from the same + release as the library itself. For example, from + the OTP R10 release is not compatible with an Erlang emulator + from the OTP R9 release by default.

+

A call to sets the + library in compatibility mode of release + . Valid range of + is [7, current release]. This makes it possible to + communicate with Erlang/OTP components from earlier releases.

+ +

If this function is called, it may only be called once + and must be called before any other functions in the + library is called.

+
+ +

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.

+
+
+
+ + intei_encode_version(char *buf, int *index) + intei_x_encode_version(ei_x_buff* x) + Encode version + +

Encodes a version magic number for the binary format. Must + be the first token in a binary term.

+
+
+ + intei_encode_long(char *buf, int *index, long p) + intei_x_encode_long(ei_x_buff* x, long p) + Encode integer + +

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().

+
+
+ + intei_encode_ulong(char *buf, int *index, unsigned long p) + intei_x_encode_ulong(ei_x_buff* x, unsigned long p) + Encode unsigned integer + +

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().

+
+
+ + intei_encode_longlong(char *buf, int *index, long long p) + intei_x_encode_longlong(ei_x_buff* x, long long p) + Encode integer + +

Encodes a GCC or Visual C++ (64 bit) + integer in the binary format. Note that this function is missing + in the VxWorks port.

+
+
+ + intei_encode_ulonglong(char *buf, int *index, unsigned long long p) + intei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p) + Encode unsigned integer + +

Encodes a GCC or Visual C++ (64 bit) integer in the binary format. Note that + this function is missing in the VxWorks port.

+
+
+ + intei_encode_bignum(char *buf, int *index, mpz_t obj) + intei_x_encode_bignum(ei_x_buff *x, mpz_t obj) + Encode an arbitrary precision integer + +

Encodes a GMP integer to binary format. + To use this function the ei library needs to be configured and compiled + to use the GMP library.

+
+
+ + intei_encode_double(char *buf, int *index, double p) + intei_x_encode_double(ei_x_buff* x, double p) + Encode a double float + +

Encodes a double-precision (64 bit) floating point number in + the binary format.

+
+
+ + intei_encode_boolean(char *buf, int *index, int p) + intei_x_encode_boolean(ei_x_buff* x, int p) + Encode a boolean + +

Encodes a boolean value, as the atom if p is not + zero or if p is zero.

+
+
+ + intei_encode_char(char *buf, int *index, char p) + intei_x_encode_char(ei_x_buff* x, char p) + Encode an 8-bit integer between 0-255 + +

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 . Your C code should consider the + given argument to be of type even if + the C compilers and system may define to be + signed.

+
+
+ + intei_encode_string(char *buf, int *index, const char *p) + intei_encode_string_len(char *buf, int *index, const char *p, int len) + intei_x_encode_string(ei_x_buff* x, const char *p) + intei_x_encode_string_len(ei_x_buff* x, const char* s, int len) + Encode a string + +

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 function.

+
+
+ + intei_encode_atom(char *buf, int *index, const char *p) + intei_encode_atom_len(char *buf, int *index, const char *p, int len) + intei_x_encode_atom(ei_x_buff* x, const char *p) + intei_x_encode_atom_len(ei_x_buff* x, const char *p, int len) + Encode an atom + +

Encodes an atom in the binary format. The parameter + is the name of the atom. Only upto bytes + are encoded. The name should be zero-terminated, except for + the function.

+
+
+ + intei_encode_binary(char *buf, int *index, const void *p, long len) + intei_x_encode_binary(ei_x_buff* x, const void *p, long len) + Encode a binary + +

Encodes a binary in the binary format. The data is at + , of bytes length.

+
+
+ + intei_encode_pid(char *buf, int *index, const erlang_pid *p) + intei_x_encode_pid(ei_x_buff* x, const erlang_pid *p) + Encode a pid + +

Encodes an erlang process identifier, pid, in the binary + format. The parameter points to an + structure (which should have been obtained + earlier with ).

+
+
+ + intei_encode_fun(char *buf, int *index, const erlang_fun *p) + intei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun) + Encode a fun + +

Encodes a fun in the binary format. The parameter + points to an structure. The + is not freed automatically, the + should be called if the fun is not needed + after encoding.

+
+
+ + intei_encode_port(char *buf, int *index, const erlang_port *p) + intei_x_encode_port(ei_x_buff* x, const erlang_port *p) + Encodes a port + +

Encodes an erlang port in the binary format. The + parameter points to a structure (which + should have been obtained earlier with + .

+
+
+ + intei_encode_ref(char *buf, int *index, const erlang_ref *p) + intei_x_encode_ref(ei_x_buff* x, const erlang_ref *p) + Encodes a ref + +

Encodes an erlang reference in the binary format. The + parameter points to a structure + (which should have been obtained earlier with + .

+
+
+ + intei_encode_term(char *buf, int *index, void *t) + intei_x_encode_term(ei_x_buff* x, void *t) + Encode an term + +

This function encodes an , as obtained from + . The parameter is actually an + pointer. This function doesn't free the + .

+
+
+ + intei_encode_trace(char *buf, int *index, const erlang_trace *p) + intei_x_encode_trace(ei_x_buff* x, const erlang_trace *p) + Encode a trace token + +

This function encodes an erlang trace token in the binary + format. The parameter points to a + structure (which should have been + obtained earlier with .

+
+
+ + intei_encode_tuple_header(char *buf, int *index, int arity) + intei_x_encode_tuple_header(ei_x_buff* x, int arity) + Encode a tuple + +

This function encodes a tuple header, with a specified + arity. The next 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.

+

E.g. to encode the tuple :

+
+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);
+        
+
+
+ + intei_encode_list_header(char *buf, int *index, int arity) + intei_x_encode_list_header(ei_x_buff* x, int arity) + Encode a list + +

This function encodes a list header, with a specified + arity. The next terms are the elements + (actually it's cons cells) and the tail of the + list. Lists and tuples are encoded recursively, so that a + list may contain another list or tuple.

+

E.g. to encode the list :

+
+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);
+        
+ +

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 can be + written as . Using this, a list can + be written as conses.

+
+

To encode a list, without knowing the arity in advance:

+
+while (something()) {
+    ei_x_encode_list_header(&x, 1);
+    ei_x_encode_ulong(&x, i); /* just an example */
+}
+ei_x_encode_empty_list(&x);
+        
+
+
+ + intei_encode_empty_list(char* buf, int* index) + intei_x_encode_empty_list(ei_x_buff* x) + Encode an empty list () + +

This function encodes an empty list. It's often used at the + tail of a list.

+
+
+ + intei_get_type(const char *buf, const int *index, int *type, int *size) + Fetch the type and size of an encoded term + +

This function returns the type in and size in + of the encoded term. + For strings and atoms, size + is the number of characters not including the + terminating 0. For binaries, is the number of + bytes. For lists and tuples, is the arity of the + object. For other types, is 0. In all cases, + is left unchanged.

+
+
+ + intei_decode_version(const char *buf, int *index, int *version) + Encode an empty list () + +

This function decodes the version magic number for the + erlang binary term format. It must be the first token in a + binary term.

+
+
+ + intei_decode_long(const char *buf, int *index, long *p) + Decode integer + +

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().

+
+
+ + intei_decode_ulong(const char *buf, int *index, unsigned long *p) + Decode unsigned integer + +

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().

+
+
+ + intei_decode_longlong(const char *buf, int *index, long long *p) + Decode integer + +

This function decodes a GCC or Visual C++ + (64 bit) integer from the binary format. Note that this + function is missing in the VxWorks port.

+
+
+ + intei_decode_ulonglong(const char *buf, int *index, unsigned long long *p) + Decode unsigned integer + +

This function decodes a GCC or Visual C++ + (64 bit) integer from the binary format. + Note that this function is missing in the VxWorks port.

+
+
+ + intei_decode_bignum(const char *buf, int *index, mpz_t obj) + Decode a GMP arbitrary precision integer + +

This function decodes an integer in the binary format to a GMP integer. + To use this function the ei library needs to be configured and compiled + to use the GMP library.

+
+
+ + intei_decode_double(const char *buf, int *index, double *p) + Decode a double + +

This function decodes an double-precision (64 bit) floating + point number from the binary format.

+
+
+ + intei_decode_boolean(const char *buf, int *index, int *p) + Decode a boolean + +

This function decodes a boolean value from the binary + format. A boolean is actually an atom, decodes 1 + and decodes 0.

+
+
+ + intei_decode_char(const char *buf, int *index, char *p) + Decode an 8-bit integer between 0-255 + +

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 . Your C code should consider the + returned value to be of type even if + the C compilers and system may define to be + signed.

+
+
+ + intei_decode_string(const char *buf, int *index, char *p) + Decode a string + +

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 , + even if it was not intended.

+

The string is copied to , and enough space must be + allocated. The returned string is null terminated so you + need to add an extra byte to the memory requirement.

+
+
+ + intei_decode_atom(const char *buf, int *index, char *p) + Decode an atom + +

This function decodes an atom from the binary format. The + name of the atom is placed at . There can be at most + bytes placed in the buffer.

+
+
+ + intei_decode_binary(const char *buf, int *index, void *p, long *len) + Decode a binary + +

This function decodes a binary from the binary format. The + parameter is set to the actual size of the + binary. Note that assumes that there + are enough room for the binary. The size required can be + fetched by .

+
+
+ + intei_decode_fun(const char *buf, int *index, erlang_fun *p) + voidfree_fun(erlang_fun* f) + Decode a fun + +

This function decodes a fun from the binary format. The + parameter should be NULL or point to an + structure. This is the only decode + function that allocates memory; when the + is no longer needed, it should be freed with + . (This has to do with the arbitrary size of + the environment for a fun.)

+
+
+ + intei_decode_pid(const char *buf, int *index, erlang_pid *p) + Decode a + +

Decodes a pid, process identifier, from the binary format.

+
+
+ + intei_decode_port(const char *buf, int *index, erlang_port *p) + Decode a port + +

This function decodes a port identifier from the binary + format.

+
+
+ + intei_decode_ref(const char *buf, int *index, erlang_ref *p) + Decode a reference + +

This function decodes a reference from the binary format.

+
+
+ + intei_decode_trace(const char *buf, int *index, erlang_trace *p) + Decode a trace token + +

Decodes an erlang trace token from the binary format.

+
+
+ + intei_decode_tuple_header(const char *buf, int *index, int *arity) + Decode a tuple + +

This function decodes a tuple header, the number of elements + is returned in . The tuple elements follows in order in + the buffer.

+
+
+ + intei_decode_list_header(const char *buf, int *index, int *arity) + Decode a list + +

This function decodes a list header from the binary + format. The number of elements is returned in + . The elements follows (the last + one is the tail of the list, normally an empty list.) If + is , it's an empty list.

+

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 + instead.

+
+
+ + intei_decode_ei_term(const char* buf, int* index, ei_term* term) + Decode a term, without prior knowledge of type + +

This function decodes any term, or at least tries to. If the + term pointed at by in fits in the + union, it is decoded, and the appropriate field + in value]]> is set, and is + incremented by the term size.

+

The function returns 0 on successful encoding, -1 on error, + and 1 if the term seems alright, but does not fit in the + structure. If it returns 0, the + will be incremented, and the contains the + decoded term.

+

The 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.

+
+
+ + intei_decode_term(const char *buf, int *index, void *t) + Decode a + +

This function decodes a term from the binary format. The + term is return in as a , so + is actually an (see + . The term should later be + deallocated.

+

Note that this function is located in the erl_interface + library.

+
+
+ + intei_print_term(FILE* fp, const char* buf, int* index) + intei_s_print_term(char** s, const char* buf, int* index) + Print a term in clear text + +

This function prints a term, in clear text, to the file + given by , or the buffer pointed to by . It + tries to resemble the term printing in the erlang shell.

+

In , the parameter should + point to a dynamically (malloc) allocated string of + bytes or a NULL pointer. The string may be + reallocated (and may be updated) by this function + if the result is more than characters. The + string returned is zero-terminated.

+

The return value is the number of characters written to the + file or string, or -1 if doesn't contain a + valid term. Unfortunately, I/O errors on is not + checked.

+

The argument is updated, i.e. this function can + be viewed as en decode function that decodes a term into a + human readable format.

+
+
+ + intei_x_format(ei_x_buff* x, const char* fmt, ...) + intei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ... ) + Format a term from a format string and parameters. + +

Format a term, given as a string, to a buffer. This + functions works like a sprintf for erlang terms. The + contains a format string, with arguments like + , to insert terms from variables. The following + formats are supported (with the C types given):

+

+
+~a - an atom, 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
+        
+

For instance, to encode a tuple with some stuff:

+
+ei_x_format("{~a,~i,~d}", "numbers", 12, 3.14159)
+encodes the tuple {numbers,12,3.14159}
+        
+

The formats into a buffer, without + the initial version byte.

+
+
+ + intei_x_new(ei_x_buff* x) + intei_x_new_with_version(ei_x_buff* x) + Allocate a new buffer + +

This function allocates a new buffer. The + fields of the structure pointed to by parameter is + filled in, and a default buffer is allocated. The + also puts an initial version + byte, that is used in the binary format. (So that + won't be needed.)

+
+
+ + intei_x_free(ei_x_buff* x) + Frees a buffer + +

This function frees an buffer. The memory + used by the buffer is returned to the OS.

+
+
+ + intei_x_append(ei_x_buff* x, const ei_x_buff* x2) + intei_x_append_buf(ei_x_buff* x, const char* buf, int len) + Appends a buffer at the end + +

These functions appends data at the end of the buffer .

+
+
+ + intei_skip_term(const char* buf, int* index) + skip a term + +

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.

+

is the buffer.

+

is updated to point right after the term in the + buffer.

+ +

This can be useful when you want to hold arbitrary + terms: just skip them and copy the binary term data to some + buffer.

+
+

The function returns on success and on + failure.

+
+
+
+ +
+ Debug Information +

Some tips on what to check when the emulator doesn't seem to + receive the terms that you send.

+ + be careful with the version header, use + when appropriate + turn on distribution tracing on the erlang node + check the result codes from ei_decode_-calls + +
+ +
+ See Also +

erl_interface(3)

+
+
+ -- cgit v1.2.3