[PATCH] connection: Add some documentation to wl_connection_demarshal()

Philip Withnall philip at tecnocode.co.uk
Fri Feb 8 00:54:15 PST 2013


On Thu, 2013-02-07 at 21:13 -0500, Kristian Høgsberg wrote:
> On Mon, Feb 04, 2013 at 11:21:46AM +0000, Philip Withnall wrote:
> > Signed-off-by: Philip Withnall <philip at tecnocode.co.uk>
> > ---
> >  src/connection.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 62 insertions(+)
> 
> This is good and well-written documentation, but it does clash a bit
> with Jasons custom dispatche series, which change how some of this
> works.  Are you ok with revisiting/rewriting this once we land Jasons
> patches?

I guess I could do that. Might take me a few days to find the time
though.

Philip

> Kristian
> 
> > 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
> > 
> 
> 
> 
> > _______________________________________________
> > wayland-devel mailing list
> > wayland-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 230 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130208/8331b7ec/attachment.pgp>


More information about the wayland-devel mailing list