Signed-off-by: Philip Withnall <phi...@tecnocode.co.uk> --- src/connection.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)
diff --git a/src/connection.c b/src/connection.c index 141875e..531255a 100644 --- a/src/connection.c +++ b/src/connection.c @@ -444,6 +444,8 @@ arg_count_for_signature(const char *signature) return count; } +/* See wl_connection_demarshal() for an explanation of the marshalling + * format. */ struct wl_closure * wl_closure_vmarshal(struct wl_object *sender, uint32_t opcode, va_list ap, @@ -641,6 +643,41 @@ err_null: return NULL; } +/** + * Consume a packet off the wire from the connection, `size` bytes long, and + * demarshal it to a wl_closure. Return NULL on failure. Use the provided + * wl_message to give metadata about the packet, such as its signature. + * + * The returned wl_closure has the following structure: + * + * +--------------------------------------+ + * | preamble (count, message, types, cif | + * +--------------------------------------+ + * | args[20] | + * +--------------------------------------+ + * | start (pointer to buffer) | + * +--------------------------------------+ + * | link, proxy | + * +--------------------------------------+ + * | buffer (first 2 uint32s) | <- start + * | buffer (size bytes long) | <- p + * | ... | + * | extra area (extra_space bytes long) | <-- end, extra + * | ... | + * +--------------------------------------+ + * + * After setting up the closure, demarshalling proceeds through each argument, + * i, in the message's signature, setting closure->args[i] as appropriate. For + * small data types (e.g. inline integers), a value is pulled from `buffer` + * (skipping the first 2 uint32s) and `p` is incremented. + * + * Handling of strings, objects and arrays is more complex. They are + * demarshalled from the buffer in the obvious manner (e.g. strings as + * length + character data + nul terminator), then copied into the extra area + * in the closure, and a pointer to this extra space stored in closure->args[i]. + * This is necessary so that a single pointer refers to all the data for each + * argument. + */ struct wl_closure * wl_connection_demarshal(struct wl_connection *connection, uint32_t size, @@ -703,6 +740,14 @@ wl_connection_demarshal(struct wl_connection *connection, closure->args[i] = p++; break; case 's': + /* Strings are stored as a uint32 length in the buffer, + * followed immediately by the nul-terminated characters + * of the string, then some padding to reach the next + * 4-byte alignment in the buffer. + * + * Zero-length strings are always outputted as NULL, + * and non-zero-length strings must always be + * nul-terminated. */ closure->types[i] = &ffi_type_pointer; length = *p++; @@ -735,6 +780,13 @@ wl_connection_demarshal(struct wl_connection *connection, p = next; break; case 'o': + /* Objects are stored as a uint32 pointer in the + * buffer. Space for a pointer to this pointer (i.e. a + * uint32_t**) is allocated in the extra space, and + * the object pointer stored there. + * + * If the object pointer is 0 when dereferenced, the + * object is NULL. */ closure->types[i] = &ffi_type_pointer; id = (uint32_t **) extra; extra += sizeof *id; @@ -752,6 +804,8 @@ wl_connection_demarshal(struct wl_connection *connection, p++; break; case 'n': + /* New objects are stored as normal objects, as + * above. */ closure->types[i] = &ffi_type_pointer; id = (uint32_t **) extra; extra += sizeof *id; @@ -777,6 +831,14 @@ wl_connection_demarshal(struct wl_connection *connection, p++; break; case 'a': + /* Arrays are stored as a length in the buffer, followed + * by `length` bytes of the array data, then by some + * padding to reach the next 4-byte alignment in the + * buffer. + * + * The array argument is returned as a pointer in the + * extra area, pointing to the array data which + * immediately follows it in the extra area. */ closure->types[i] = &ffi_type_pointer; length = *p++; -- 1.7.11.7
signature.asc
Description: This is a digitally signed message part
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel