LCOV - code coverage report
Current view: top level - common - marshaller.c (source / functions) Hit Total Coverage
Test: out.info Lines: 158 282 56.0 %
Date: 2022-01-27 10:43:00 Functions: 19 37 51.4 %

          Line data    Source code
       1             : /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
       2             : /*
       3             :    Copyright (C) 2010 Red Hat, Inc.
       4             : 
       5             :    This library is free software; you can redistribute it and/or
       6             :    modify it under the terms of the GNU Lesser General Public
       7             :    License as published by the Free Software Foundation; either
       8             :    version 2.1 of the License, or (at your option) any later version.
       9             : 
      10             :    This library is distributed in the hope that it will be useful,
      11             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :    Lesser General Public License for more details.
      14             : 
      15             :    You should have received a copy of the GNU Lesser General Public
      16             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      17             : */
      18             : #include <config.h>
      19             : 
      20             : #include "log.h"
      21             : #include "marshaller.h"
      22             : #include "mem.h"
      23             : #include <string.h>
      24             : #include <stdlib.h>
      25             : #include <assert.h>
      26             : #include <unistd.h>
      27             : #include <stdio.h>
      28             : 
      29             : #include <spice/start-packed.h>
      30             : typedef struct SPICE_ATTR_PACKED {
      31             :     int16_t val;
      32             : } int16_unaligned_t;
      33             : 
      34             : typedef struct SPICE_ATTR_PACKED {
      35             :     uint16_t val;
      36             : } uint16_unaligned_t;
      37             : 
      38             : typedef struct SPICE_ATTR_PACKED {
      39             :     int32_t val;
      40             : } int32_unaligned_t;
      41             : 
      42             : typedef struct SPICE_ATTR_PACKED {
      43             :     uint32_t val;
      44             : } uint32_unaligned_t;
      45             : 
      46             : typedef struct SPICE_ATTR_PACKED {
      47             :     int64_t val;
      48             : } int64_unaligned_t;
      49             : 
      50             : typedef struct SPICE_ATTR_PACKED {
      51             :     uint64_t val;
      52             : } uint64_unaligned_t;
      53             : #include <spice/end-packed.h>
      54             : 
      55             : #define write_int8(ptr,v) (*(int8_t *)(ptr) = v)
      56             : #define write_uint8(ptr,v) (*(uint8_t *)(ptr) = v)
      57             : 
      58             : #ifdef WORDS_BIGENDIAN
      59             : #define write_int16(ptr,v) (((uint16_unaligned_t *)(ptr))->val = SPICE_BYTESWAP16((uint16_t)(v)))
      60             : #define write_uint16(ptr,v) (((uint16_unaligned_t *)(ptr))->val = SPICE_BYTESWAP16((uint16_t)(v)))
      61             : #define write_int32(ptr,v) (((uint32_unaligned_t *)(ptr))->val = SPICE_BYTESWAP32((uint32_t)(v)))
      62             : #define write_uint32(ptr,v) (((uint32_unaligned_t *)(ptr))->val = SPICE_BYTESWAP32((uint32_t)(v)))
      63             : #define write_int64(ptr,v) (((uint64_unaligned_t *)(ptr))->val = SPICE_BYTESWAP64((uint64_t)(v)))
      64             : #define write_uint64(ptr,v) (((uint64_unaligned_t *)(ptr))->val = SPICE_BYTESWAP64((uint64_t)(v)))
      65             : #else
      66             : #define write_int16(ptr,v) (((int16_unaligned_t *)(ptr))->val = v)
      67             : #define write_uint16(ptr,v) (((uint16_unaligned_t *)(ptr))->val = v)
      68             : #define write_int32(ptr,v) (((int32_unaligned_t *)(ptr))->val = v)
      69             : #define write_uint32(ptr,v) (((uint32_unaligned_t *)(ptr))->val = v)
      70             : #define write_int64(ptr,v) (((int64_unaligned_t *)(ptr))->val = v)
      71             : #define write_uint64(ptr,v) (((uint64_unaligned_t *)(ptr))->val = v)
      72             : #endif
      73             : 
      74             : typedef struct {
      75             :     uint8_t *data;
      76             :     size_t len;
      77             :     spice_marshaller_item_free_func free_data;
      78             :     void *opaque;
      79             : } MarshallerItem;
      80             : 
      81             : /* Try to fit in 4k page with 2*pointer-size overhead (next ptr and malloc size) */
      82             : #define MARSHALLER_BUFFER_SIZE (4096 - sizeof(void *) * 2)
      83             : 
      84             : typedef struct MarshallerBuffer MarshallerBuffer;
      85             : struct MarshallerBuffer {
      86             :     MarshallerBuffer *next;
      87             :     uint8_t data[MARSHALLER_BUFFER_SIZE];
      88             : };
      89             : 
      90             : #define N_STATIC_ITEMS 4
      91             : 
      92             : typedef struct SpiceMarshallerData SpiceMarshallerData;
      93             : 
      94             : typedef struct {
      95             :     SpiceMarshaller *marshaller;
      96             :     int item_nr;
      97             :     size_t offset;
      98             : } MarshallerRef;
      99             : 
     100             : struct SpiceMarshaller {
     101             :     size_t total_size;
     102             :     SpiceMarshallerData *data;
     103             :     SpiceMarshaller *next;
     104             : 
     105             :     MarshallerRef pointer_ref;
     106             : 
     107             :     int n_items;
     108             :     int items_size; /* number of items available in items */
     109             :     MarshallerItem *items;
     110             : 
     111             :     MarshallerItem static_items[N_STATIC_ITEMS];
     112             :     bool has_fd;
     113             :     int fd;
     114             : };
     115             : 
     116             : struct SpiceMarshallerData {
     117             :     size_t total_size;
     118             :     size_t base;
     119             :     SpiceMarshaller *last_marshaller;
     120             : 
     121             :     size_t current_buffer_position;
     122             :     MarshallerBuffer *current_buffer;
     123             :     MarshallerItem *current_buffer_item;
     124             : 
     125             :     // first marshaller and buffer are statically allocated here
     126             :     SpiceMarshaller marshallers[1];
     127             :     MarshallerBuffer buffers[1];
     128             : };
     129             : 
     130           2 : static void spice_marshaller_init(SpiceMarshaller *m,
     131             :                                   SpiceMarshallerData *data)
     132             : {
     133           2 :     m->data = data;
     134           2 :     m->next = NULL;
     135           2 :     m->total_size = 0;
     136           2 :     m->pointer_ref.marshaller = NULL;
     137           2 :     m->n_items = 0;
     138           2 :     m->items_size = N_STATIC_ITEMS;
     139           2 :     m->items = m->static_items;
     140           2 :     m->fd = -1;
     141           2 :     m->has_fd = false;
     142           2 : }
     143             : 
     144           1 : SpiceMarshaller *spice_marshaller_new(void)
     145             : {
     146             :     SpiceMarshallerData *d;
     147             :     SpiceMarshaller *m;
     148             : 
     149           1 :     d = spice_new(SpiceMarshallerData, 1);
     150             : 
     151           1 :     d->last_marshaller = d->marshallers;
     152           1 :     d->total_size = 0;
     153           1 :     d->base = 0;
     154           1 :     d->buffers->next = NULL;
     155           1 :     d->current_buffer = d->buffers;
     156           1 :     d->current_buffer_position = 0;
     157           1 :     d->current_buffer_item = NULL;
     158             : 
     159           1 :     m = d->marshallers;
     160           1 :     spice_marshaller_init(m, d);
     161             : 
     162           1 :     return m;
     163             : }
     164             : 
     165           3 : static void free_item_data(SpiceMarshaller *m)
     166             : {
     167             :     MarshallerItem *item;
     168             :     int i;
     169             : 
     170             :     /* Free all user data */
     171           6 :     for (i = 0; i < m->n_items; i++) {
     172           3 :         item = &m->items[i];
     173           3 :         if (item->free_data != NULL) {
     174           0 :             item->free_data(item->data, item->opaque);
     175             :         }
     176             :     }
     177           3 : }
     178             : 
     179           2 : static void free_items(SpiceMarshaller *m)
     180             : {
     181           2 :     if (m->items != m->static_items) {
     182           0 :         free(m->items);
     183             :     }
     184           2 : }
     185             : 
     186           2 : void spice_marshaller_reset(SpiceMarshaller *m)
     187             : {
     188             :     SpiceMarshaller *m2, *next;
     189             :     SpiceMarshallerData *d;
     190             : 
     191             :     /* Only supported for root marshaller */
     192           2 :     assert(m->data->marshallers == m);
     193             : 
     194           5 :     for (m2 = m; m2 != NULL; m2 = next) {
     195           3 :         next = m2->next;
     196           3 :         free_item_data(m2);
     197             : 
     198             :         /* Free non-root marshallers */
     199           3 :         if (m2 != m) {
     200           1 :             free_items(m2);
     201           1 :             free(m2);
     202             :         }
     203             :     }
     204             : 
     205           2 :     m->next = NULL;
     206           2 :     m->n_items = 0;
     207           2 :     m->total_size = 0;
     208           2 :     if (m->has_fd) {
     209           0 :         m->has_fd = false;
     210           0 :         if (m->fd != -1) {
     211           0 :             close(m->fd);
     212             :         }
     213             :     }
     214             : 
     215           2 :     d = m->data;
     216           2 :     d->last_marshaller = d->marshallers;
     217           2 :     d->total_size = 0;
     218           2 :     d->base = 0;
     219           2 :     d->current_buffer_item = NULL;
     220           2 :     d->current_buffer = d->buffers;
     221           2 :     d->current_buffer_position = 0;
     222           2 : }
     223             : 
     224           1 : void spice_marshaller_destroy(SpiceMarshaller *m)
     225             : {
     226             :     MarshallerBuffer *buf, *next;
     227             :     SpiceMarshallerData *d;
     228             : 
     229             :     /* Only supported for root marshaller */
     230           1 :     assert(m->data->marshallers == m);
     231             : 
     232           1 :     spice_marshaller_reset(m);
     233             : 
     234           1 :     free_items(m);
     235             : 
     236           1 :     d = m->data;
     237             : 
     238           1 :     buf = d->buffers->next;
     239           1 :     while (buf != NULL) {
     240           0 :         next = buf->next;
     241           0 :         free(buf);
     242           0 :         buf = next;
     243             :     }
     244             : 
     245           1 :     free(d);
     246           1 : }
     247             : 
     248           3 : static MarshallerItem *spice_marshaller_add_item(SpiceMarshaller *m)
     249             : {
     250             :     MarshallerItem *item;
     251             : 
     252           3 :     if (m->n_items == m->items_size) {
     253           0 :         int items_size = m->items_size * 2;
     254             : 
     255           0 :         if (m->items == m->static_items) {
     256           0 :             m->items = spice_new(MarshallerItem, items_size);
     257           0 :             memcpy(m->items, m->static_items, sizeof(MarshallerItem) * m->n_items);
     258             :         } else {
     259           0 :             m->items = spice_renew(MarshallerItem, m->items, items_size);
     260             :         }
     261           0 :         m->items_size = items_size;
     262             :     }
     263           3 :     item = &m->items[m->n_items++];
     264           3 :     item->free_data = NULL;
     265             : 
     266           3 :     return item;
     267             : }
     268             : 
     269          12 : static size_t remaining_buffer_size(SpiceMarshallerData *d)
     270             : {
     271          12 :     return MARSHALLER_BUFFER_SIZE - d->current_buffer_position;
     272             : }
     273             : 
     274           0 : static void reserve_space_free_data(uint8_t *data, SPICE_GNUC_UNUSED void *opaque)
     275             : {
     276           0 :     free(data);
     277           0 : }
     278             : 
     279          12 : uint8_t *spice_marshaller_reserve_space(SpiceMarshaller *m, size_t size)
     280             : {
     281             :     MarshallerItem *item;
     282             :     SpiceMarshallerData *d;
     283             :     uint8_t *res;
     284             : 
     285          12 :     if (size == 0) {
     286           0 :         return NULL;
     287             :     }
     288             : 
     289          12 :     d = m->data;
     290             : 
     291             :     /* Check current item */
     292          12 :     item = &m->items[m->n_items - 1];
     293          21 :     if (item == d->current_buffer_item &&
     294           9 :         remaining_buffer_size(d) >= size) {
     295           9 :         assert(m->n_items >= 1);
     296             :         /* We can piggy back on existing item+buffer */
     297           9 :         res = item->data + item->len;
     298           9 :         item->len += size;
     299           9 :         d->current_buffer_position += size;
     300           9 :         d->total_size += size;
     301           9 :         m->total_size += size;
     302           9 :         return res;
     303             :     }
     304             : 
     305           3 :     item = spice_marshaller_add_item(m);
     306             : 
     307           3 :     if (remaining_buffer_size(d) >= size) {
     308             :         /* Fits in current buffer */
     309           3 :         item->data = d->current_buffer->data + d->current_buffer_position;
     310           3 :         item->len = size;
     311           3 :         d->current_buffer_position += size;
     312           3 :         d->current_buffer_item = item;
     313           0 :     } else if (size > MARSHALLER_BUFFER_SIZE / 2) {
     314             :         /* Large item, allocate by itself */
     315           0 :         item->data = (uint8_t *)spice_malloc(size);
     316           0 :         item->len = size;
     317           0 :         item->free_data = reserve_space_free_data;
     318           0 :         item->opaque = NULL;
     319             :     } else {
     320             :         /* Use next buffer */
     321           0 :         if (d->current_buffer->next == NULL) {
     322           0 :             d->current_buffer->next = spice_new(MarshallerBuffer, 1);
     323           0 :             d->current_buffer->next->next = NULL;
     324             :         }
     325           0 :         d->current_buffer = d->current_buffer->next;
     326           0 :         d->current_buffer_position = size;
     327           0 :         d->current_buffer_item = item;
     328           0 :         item->data = d->current_buffer->data;
     329           0 :         item->len = size;
     330             :     }
     331             : 
     332           3 :     d->total_size += size;
     333           3 :     m->total_size += size;
     334           3 :     return item->data;
     335             : }
     336             : 
     337           0 : void spice_marshaller_unreserve_space(SpiceMarshaller *m, size_t size)
     338             : {
     339             :     MarshallerItem *item;
     340             : 
     341           0 :     if (size == 0) {
     342           0 :         return;
     343             :     }
     344             : 
     345           0 :     item = &m->items[m->n_items - 1];
     346             : 
     347           0 :     assert(item->len >= size);
     348           0 :     item->len -= size;
     349             : }
     350             : 
     351           0 : uint8_t *spice_marshaller_add_by_ref_full(SpiceMarshaller *m, uint8_t *data, size_t size,
     352             :                                           spice_marshaller_item_free_func free_data, void *opaque)
     353             : {
     354             :     MarshallerItem *item;
     355             :     SpiceMarshallerData *d;
     356             : 
     357           0 :     if (data == NULL || size == 0) {
     358           0 :         return NULL;
     359             :     }
     360             : 
     361           0 :     item = spice_marshaller_add_item(m);
     362           0 :     item->data = data;
     363           0 :     item->len = size;
     364           0 :     item->free_data = free_data;
     365           0 :     item->opaque = opaque;
     366             : 
     367           0 :     d = m->data;
     368           0 :     m->total_size += size;
     369           0 :     d->total_size += size;
     370             : 
     371           0 :     return data;
     372             : }
     373             : 
     374           0 : uint8_t *spice_marshaller_add(SpiceMarshaller *m, const uint8_t *data, size_t size)
     375             : {
     376             :     uint8_t *ptr;
     377             : 
     378           0 :     ptr = spice_marshaller_reserve_space(m, size);
     379           0 :     memcpy(ptr, data, size);
     380           0 :     return ptr;
     381             : }
     382             : 
     383           0 : uint8_t *spice_marshaller_add_by_ref(SpiceMarshaller *m, const uint8_t *data, size_t size)
     384             : {
     385             :     /* the cast to no-const here is safe as data is used for writing only if
     386             :      * free_data pointer is not NULL
     387             :      */
     388           0 :     return spice_marshaller_add_by_ref_full(m, (uint8_t *) data, size, NULL, NULL);
     389             : }
     390             : 
     391           0 : void spice_marshaller_add_chunks_by_ref(SpiceMarshaller *m, SpiceChunks *chunks)
     392             : {
     393             :     unsigned int i;
     394             : 
     395           0 :     for (i = 0; i < chunks->num_chunks; i++) {
     396           0 :         spice_marshaller_add_by_ref(m, chunks->chunk[i].data,
     397           0 :                                     chunks->chunk[i].len);
     398             :     }
     399           0 : }
     400             : 
     401           1 : SpiceMarshaller *spice_marshaller_get_submarshaller(SpiceMarshaller *m)
     402             : {
     403             :     SpiceMarshallerData *d;
     404             :     SpiceMarshaller *m2;
     405             : 
     406           1 :     d = m->data;
     407             : 
     408           1 :     m2 = spice_new(SpiceMarshaller, 1);
     409           1 :     spice_marshaller_init(m2, d);
     410             : 
     411           1 :     d->last_marshaller->next = m2;
     412           1 :     d->last_marshaller = m2;
     413             : 
     414           1 :     return m2;
     415             : }
     416             : 
     417           1 : SpiceMarshaller *spice_marshaller_get_ptr_submarshaller(SpiceMarshaller *m)
     418             : {
     419             :     SpiceMarshaller *m2;
     420             :     uint8_t *p;
     421             :     int size;
     422             : 
     423           1 :     size = 4;
     424             : 
     425           1 :     p = spice_marshaller_reserve_space(m, size);
     426           1 :     memset(p, 0, size);
     427           1 :     m2 = spice_marshaller_get_submarshaller(m);
     428           1 :     m2->pointer_ref.marshaller = m;
     429           1 :     m2->pointer_ref.item_nr = m->n_items - 1;
     430           1 :     m2->pointer_ref.offset = m->items[m->n_items - 1].len - size;
     431             : 
     432           1 :     return m2;
     433             : }
     434             : 
     435           1 : static uint8_t *lookup_ref(MarshallerRef *ref)
     436             : {
     437             :     MarshallerItem *item;
     438             : 
     439           1 :     item = &ref->marshaller->items[ref->item_nr];
     440           1 :     return item->data + ref->offset;
     441             : }
     442             : 
     443             : 
     444           0 : void spice_marshaller_set_base(SpiceMarshaller *m, size_t base)
     445             : {
     446             :     /* Only supported for root marshaller */
     447           0 :     assert(m->data->marshallers == m);
     448             : 
     449           0 :     m->data->base = base;
     450           0 : }
     451             : 
     452           3 : uint8_t *spice_marshaller_linearize(SpiceMarshaller *m, size_t skip_bytes,
     453             :                                     size_t *len, int *free_res)
     454             : {
     455             :     MarshallerItem *item;
     456             :     uint8_t *res, *p;
     457             :     int i;
     458             : 
     459             :     /* Only supported for root marshaller */
     460           3 :     assert(m->data->marshallers == m);
     461             : 
     462           3 :     if (m->n_items == 1 && m->next == NULL) {
     463           2 :         *free_res = FALSE;
     464           2 :         if (m->items[0].len <= skip_bytes) {
     465           0 :             *len = 0;
     466           0 :             return NULL;
     467             :         }
     468           2 :         *len = m->items[0].len - skip_bytes;
     469           2 :         return m->items[0].data + skip_bytes;
     470             :     }
     471             : 
     472           1 :     *free_res = TRUE;
     473           1 :     res = (uint8_t *)spice_malloc(m->data->total_size - skip_bytes);
     474           1 :     *len = m->data->total_size - skip_bytes;
     475           1 :     p = res;
     476             : 
     477             :     do {
     478           4 :         for (i = 0; i < m->n_items; i++) {
     479           2 :             item = &m->items[i];
     480             : 
     481           2 :             if (item->len <= skip_bytes) {
     482           0 :                 skip_bytes -= item->len;
     483           0 :                 continue;
     484             :             }
     485           2 :             memcpy(p, item->data + skip_bytes, item->len - skip_bytes);
     486           2 :             p += item->len - skip_bytes;
     487           2 :             skip_bytes = 0;
     488             :         }
     489           2 :         m = m->next;
     490           2 :     } while (m != NULL);
     491             : 
     492           1 :     return res;
     493             : }
     494             : 
     495           0 : uint8_t *spice_marshaller_get_ptr(SpiceMarshaller *m)
     496             : {
     497           0 :     return m->items[0].data;
     498             : }
     499             : 
     500           1 : size_t spice_marshaller_get_offset(SpiceMarshaller *m)
     501             : {
     502             :     SpiceMarshaller *m2;
     503             :     size_t offset;
     504             : 
     505           1 :     offset = 0;
     506           1 :     m2 = m->data->marshallers;
     507           2 :     while (m2 != m) {
     508           1 :         offset += m2->total_size;
     509           1 :         m2 = m2->next;
     510             :     }
     511           1 :     return offset - m->data->base;
     512             : }
     513             : 
     514           0 : size_t spice_marshaller_get_size(SpiceMarshaller *m)
     515             : {
     516           0 :     return m->total_size;
     517             : }
     518             : 
     519           0 : size_t spice_marshaller_get_total_size(SpiceMarshaller *m)
     520             : {
     521           0 :     return m->data->total_size;
     522             : }
     523             : 
     524           2 : void spice_marshaller_flush(SpiceMarshaller *m)
     525             : {
     526             :     SpiceMarshaller *m2;
     527             :     uint8_t *ptr_pos;
     528             : 
     529             :     /* Only supported for root marshaller */
     530           2 :     assert(m->data->marshallers == m);
     531             : 
     532           5 :     for (m2 = m; m2 != NULL; m2 = m2->next) {
     533           3 :         if (m2->pointer_ref.marshaller != NULL && m2->total_size > 0) {
     534           1 :             ptr_pos = lookup_ref(&m2->pointer_ref);
     535           1 :             write_uint32(ptr_pos, spice_marshaller_get_offset(m2));
     536             :         }
     537             :     }
     538           2 : }
     539             : 
     540             : #ifdef WIN32
     541             : // this definition is ABI compatible with WSABUF
     542             : struct iovec {
     543             :     unsigned long iov_len;
     544             :     void *iov_base;
     545             : };
     546             : #endif
     547             : 
     548           0 : int spice_marshaller_fill_iovec(SpiceMarshaller *m, struct iovec *vec,
     549             :                                 int n_vec, size_t skip_bytes)
     550             : {
     551             :     MarshallerItem *item;
     552             :     int v, i;
     553             : 
     554             :     /* Only supported for root marshaller */
     555           0 :     assert(m->data->marshallers == m);
     556             : 
     557           0 :     v = 0;
     558             :     do {
     559           0 :         for (i = 0; i < m->n_items; i++) {
     560           0 :             item = &m->items[i];
     561             : 
     562           0 :             if (item->len <= skip_bytes) {
     563           0 :                 skip_bytes -= item->len;
     564           0 :                 continue;
     565             :             }
     566           0 :             if (v == n_vec) {
     567           0 :                 return v; /* Not enough space in vec */
     568             :             }
     569           0 :             vec[v].iov_base = (uint8_t *)item->data + skip_bytes;
     570           0 :             vec[v].iov_len = item->len - skip_bytes;
     571           0 :             skip_bytes = 0;
     572           0 :             v++;
     573             :         }
     574           0 :         m = m->next;
     575           0 :     } while (m != NULL);
     576             : 
     577           0 :     return v;
     578             : }
     579             : 
     580           2 : void *spice_marshaller_add_uint64(SpiceMarshaller *m, uint64_t v)
     581             : {
     582             :     uint8_t *ptr;
     583             : 
     584           2 :     ptr = spice_marshaller_reserve_space(m, sizeof(uint64_t));
     585           2 :     write_uint64(ptr, v);
     586           2 :     return (void *)ptr;
     587             : }
     588             : 
     589           0 : void *spice_marshaller_add_int64(SpiceMarshaller *m, int64_t v)
     590             : {
     591             :     uint8_t *ptr;
     592             : 
     593           0 :     ptr = spice_marshaller_reserve_space(m, sizeof(int64_t));
     594           0 :     write_int64(ptr, v);
     595           0 :     return (void *)ptr;
     596             : }
     597             : 
     598           3 : void *spice_marshaller_add_uint32(SpiceMarshaller *m, uint32_t v)
     599             : {
     600             :     uint8_t *ptr;
     601             : 
     602           3 :     ptr = spice_marshaller_reserve_space(m, sizeof(uint32_t));
     603           3 :     write_uint32(ptr, v);
     604           3 :     return (void *)ptr;
     605             : }
     606             : 
     607           0 : void spice_marshaller_set_uint32(SPICE_GNUC_UNUSED SpiceMarshaller *m, void *ref, uint32_t v)
     608             : {
     609           0 :     write_uint32((uint8_t *)ref, v);
     610           0 : }
     611             : 
     612           0 : void *spice_marshaller_add_int32(SpiceMarshaller *m, int32_t v)
     613             : {
     614             :     uint8_t *ptr;
     615             : 
     616           0 :     ptr = spice_marshaller_reserve_space(m, sizeof(int32_t));
     617           0 :     write_int32(ptr, v);
     618           0 :     return (void *)ptr;
     619             : }
     620             : 
     621           4 : void *spice_marshaller_add_uint16(SpiceMarshaller *m, uint16_t v)
     622             : {
     623             :     uint8_t *ptr;
     624             : 
     625           4 :     ptr = spice_marshaller_reserve_space(m, sizeof(uint16_t));
     626           4 :     write_uint16(ptr, v);
     627           4 :     return (void *)ptr;
     628             : }
     629             : 
     630           0 : void *spice_marshaller_add_int16(SpiceMarshaller *m, int16_t v)
     631             : {
     632             :     uint8_t *ptr;
     633             : 
     634           0 :     ptr = spice_marshaller_reserve_space(m, sizeof(int16_t));
     635           0 :     write_int16(ptr, v);
     636           0 :     return (void *)ptr;
     637             : }
     638             : 
     639           2 : void *spice_marshaller_add_uint8(SpiceMarshaller *m, uint8_t v)
     640             : {
     641             :     uint8_t *ptr;
     642             : 
     643           2 :     ptr = spice_marshaller_reserve_space(m, sizeof(uint8_t));
     644           2 :     write_uint8(ptr, v);
     645           2 :     return (void *)ptr;
     646             : }
     647             : 
     648           0 : void *spice_marshaller_add_int8(SpiceMarshaller *m, int8_t v)
     649             : {
     650             :     uint8_t *ptr;
     651             : 
     652           0 :     ptr = spice_marshaller_reserve_space(m, sizeof(int8_t));
     653           0 :     write_int8(ptr, v);
     654           0 :     return (void *)ptr;
     655             : }
     656             : 
     657           0 : void spice_marshaller_add_fd(SpiceMarshaller *m, int fd)
     658             : {
     659           0 :     spice_assert(m->has_fd == false);
     660             : 
     661           0 :     m->has_fd = true;
     662           0 :     if (fd != -1) {
     663           0 :         m->fd = dup(fd);
     664           0 :         if (m->fd == -1) {
     665           0 :             perror("dup");
     666             :         }
     667             :     } else {
     668           0 :         m->fd = -1;
     669             :     }
     670           0 : }
     671             : 
     672           0 : bool spice_marshaller_get_fd(SpiceMarshaller *m, int *fd)
     673             : {
     674           0 :     bool had_fd = m->has_fd;
     675             : 
     676           0 :     *fd = m->fd;
     677           0 :     m->has_fd = false;
     678             : 
     679           0 :     return had_fd;
     680             : }

Generated by: LCOV version 1.14