[Spice-devel] [PATCH 3/3] Extended protocol documentation

Frediano Ziglio fziglio at redhat.com
Mon Sep 19 08:15:48 UTC 2016


Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 docs/spice_protocol.txt | 360 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 360 insertions(+)

diff --git a/docs/spice_protocol.txt b/docs/spice_protocol.txt
index 3406cb9..29dedc1 100644
--- a/docs/spice_protocol.txt
+++ b/docs/spice_protocol.txt
@@ -23,6 +23,8 @@ It resemble the C format.
 
 (here BNF with some regular expression is used).
 
+It's used to generate automatically code to marshall/demarshall the network data.
+
 Example:
 
     channel ExampleChannel {
@@ -47,4 +49,362 @@ Both C and C++ style comments are supported
     /* this is a comment too
        but can be split in multiple lines */
 
+Base types
+----------
+
+All int from 8 to 64 bit (8, 16, 32 and 64) are supported either signed or unsigned.
+Also you can pass one unix descriptor.
+
+    base_type ::= "int8"|"uint8"|"int16"|"uint16"|"int32"|"uint32"|"int64"|"uint64"|"unix_fd" ;
+
+Example:
+
+    int16 x;
+
+Enumerations and flags
+----------------------
+
+It's possible to specify enumerations and flags. The difference is that flags are defined as 2 power
+values and can combined. Enumerations and flags must have a size (`8`, `16` or `32`) specified.
+
+    enum ::= <enum_type> "{" [ <enumflag_items> ] "}" <attributes> ";" ;
+    flag ::= <flag_type> "{" [ <enumflag_items> ] "}" <attributes> ";" ;
+    enum_type ::= "enum8"|"enum16"|"enum32" ;
+    flag_type ::= "flag8"|"flag16"|"flag32" ;
+    enumflag_items ::= <enumflag_item>|<enumflag_items><enumflag_item>
+    enumflag_item ::= <enum_name> [ "=" <integer> ] [ "," ] ;
+    enum_name ::= [a-z0-9_]* ;
+
+Example:
+
+    enum16 Level {
+        LOW = 0x100,
+        MEDIUM,
+        HIGH = 0x1000
+    };
+
+Variables
+---------
+
+As you should already have noted variables are similar to C syntax but there are
+some differences.
+
+    variable ::= <type> [ "*" ] <identifier> [ "[" <array_size> "]" ] <attributes>;
+
+The `*` specify a pointer. This is quite different from C. For the protocol it
+specifies that in the protocol stream a relative offset is put that points to that
+variable usually after all defined fields. This happens even on arrays, so for instance
+
+    int32 *n;
+
+containing a 0x12345678 `n` value could ended up coded as
+
+    04 00 00 00 // 4 as offset
+    78 56 34 12 // `n`
+
+(little endian). While an array of 2 items defined as
+
+    int32 *n[2];
+
+and containing 0x12345678 and 0x9abcdef could end up with
+
+    04 00 00 00 // 4 as offset
+    78 56 34 12 // `n`[0]
+    ef cd ab 09 // `n`[1]
+
+note that `int32 *n[2]` defined a pointer to an array of 2 items and not
+an array of pointers as C.
+
+*WARNING*: You should avoid using pointers on protocol if not necessary as they are complicated
+to handle not using autogenerated code and also use more space on the network.
+
+Arrays
+------
+
+As seen above the easiest way to define an array size is specifiying a constant value.
+However there are multiple way to specify the size
+
+    array_size ::= <integer>|<identifier>|""|<array_size_image>|<array_size_bytes>|<array_size_cstring> ;
+    array_size_image ::= "image_size" "(" <integer> "," <identifier> ")" ;
+    array_size_bytes ::= "bytes" "(" <identifier> "," <identifier> ")" ;
+    array_size_cstring ::= "cstring()" ;
+
+We already seen integer.
+Specifying an identifier name instead (should be variable) indicate that the length is specified
+in another field, for instance
+
+    uint8 name_len;
+    int8 name[name_len];
+
+allows to put a name of `name_len` len.
+The empty value tell that the array will end when the containing message end so if we have
+
+    int8 name[];
+
+and the message is
+
+    66 6f 6f
+
+possibly the name we want is `foo` (66 6f 6f is the ASCII encoding for `foo`).
+
+TODO: what happen with two [] in the structure ??
+TODO: can a [] array not be the last and what happens ??
+
+`image_size` allow to specify an array holding an image, for instance
+
+    uint16 width;
+    uint16 heigth;
+    uin18 raw_image[image_size(8, width, height)];
+
+could contain row data in raw_image. The constant `8` is the bit size of the image.
+
+TODO `bytes`
+
+`cstring` allows to specify NUL-terminated sequence so having
+
+    int8 name[cstring()];
+
+and the message as
+
+    66 6f 6f 00
+
+we'll have the `foo` name. Note that the field does not need to end the message as in `int8 name[]` example.
+
+Structures
+----------
+
+The simpler coumpound type is the structure. As in C is defined as a list of fields (any variable or swicth).
+But as a protocol definition there are no alignment or padding and every field (beside pointer values) follow each other.
+
+    <struct> ::= "struct" <identifier> "{" [ <fields> ] "}" <attributes> ";" ;
+    <fields> ::= <field>|<fields><field> ;
+    <field> ::= <variable>|<switch>
+
+Example:
+
+    struct Point {
+        int32 x;
+        int32 y;
+    };
+
+Messages
+--------
+
+Messages have the same syntax of structure (beside `message`) with the different that they can
+be used directly inside channels.
+
+    <message> ::= "message" <identifier> "{" [ <fields> ] "}" <attributes> ";" ;
+
+Switches
+--------
+
+TODO
+
+Type definitions
+----------------
+
+Like C type definition allow to short types defining new ones.
+
+    <typedef> ::= "typedef" <identifier> <type>`<attributes> ;
+
+note that unlike C name came before the type.
+
+Example:
+
+    typedef XCoord int32;
+
+Channels
+--------
+
+TODO
+
+Attributes
+----------
+
+As you probably noted attributed can be specified for lot of definitions.
+They allow to change code generated or specific contraints to the protocol.
+
+    attributes ::= ""|<attributes><attribute>|<attribute> ;
+    attribute ::= <attribute_name> [ "(" <attribute_values> ")" ] ;
+    attribute_values ::= <attribute_values> "," <attribute_value> | <attribute_value>
+    attribute_value ::= <integer> | <identifier>
+    attribute_name ::= @[a-z][a-z0-9_]* ;
+
+Mostly of the attributes have no arguments, other currently have only one
+argument.
+
+*NOTE*: Some comments are also written in `spice-common` `python_modules/ptypes.py`
+source file.
+
+ctype
+~~~~~
+
+Specify the structure type name that the generated marshaller/demarshaller code
+will use. By default the name will be converted to CamelCase and prefixed by
+`Spice` so for example a structure like
+
+    struct Point {
+        int32 x;
+        int32 y;
+    } @ctype(MyPoint);
+
+will be marshalled into a C structure like
+
+    struct MyPoint {
+        int32_t x;
+        int32_t y;
+    };
+
+prefix
+~~~~~~
+
+This attribute allow to specify the prefix used for generated enumerations (both
+protocol enumerations and flags generate C enumerations). By default the enumeration
+will use upper case of the enum/flag name prefixed with `SPICE_` and followed by item so
+
+    enum32 level {
+        LOW,
+        HIGH,
+    };
+
+will generate
+
+    typedef enum SpiceLevel {
+        SPICE_LEVEL_LOW,
+        SPICE_LEVEL_HIGH,
+        SPICE_LEVEL_ENUM_END
+    } SpiceLevel;
+
+while
+
+    enum32 level {
+        LOW,
+        HIGH,
+    } @prefix(LVL_);
+
+will generate
+
+    typedef enum SpiceLevel {
+        LVL_LOW,
+        LVL_HIGH,
+        SPICE_LEVEL_ENUM_END
+    } SpiceLevel;
+
+(note that an automatic `END` enumeration is generated and name is not affected).
+
+end
+~~~
+
+This attribute specify that the data will be appended/embedded in the final C structure.
+
+Example:
+
+    struct test {
+        uint16 len;
+        uint16 array[len] @end;
+    };
+
+Output C structure:
+
+    struct test {
+        uint16_t len;
+        uint16_t array[0];
+    };
+
+The generated code will allocate the C structure to allow space for extracted array.
+
+*WARNING*: This option is usually confused with with empty size protocol. The
+empty protocol array size specify array that extend on the network data while
+the `@end` attribute specify to extend the C structure (for instance in the example
+the attribute was attached to a `len`-sized array).
+
+to_ptr
+~~~
+
+TODO
+
+nocopy
+~~~
+
+TODO
+
+as_ptr
+~~~
+
+TODO
+
+nomarshal
+~~~
+
+TODO
+
+zero_terminated
+~~~
+
+TODO
+
+marshall
+~~~
+
+TODO
+
+nonnull
+~~~
+
+TODO
+
+unique_flag
+~~~
+
+TODO
+
+ptr_array
+~~~
+
+TODO
+
+outvar
+~~~
+
+TODO
+
+anon
+~~~
+
+TODO
+
+chunk
+~~~
+
+TODO
+
+ifdef
+~~~
+
+TODO
+
+zero
+~~~
+
+TODO
+
+minor
+~~~
+
+TODO
+
+bytes_count
+~~~
+
+TODO
+
+virtual
+~~~
+
+TODO
+
+fixedsize
+~~~
+
+TODO
 
-- 
2.7.4



More information about the Spice-devel mailing list