/* the actual read is "slow" because it calls the underlying transport */ gint32 thrift_framed_transport_read_slow (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); guint32 want = len; guint32 have = t->r_buf->len; // we shouldn't hit this unless the buffer doesn't have enough to read assert (t->r_buf->len < want); // first copy what we have in our buffer, if there is anything left if (have > 0) { memcpy (buf, t->r_buf, t->r_buf->len); want -= t->r_buf->len; t->r_buf = g_byte_array_remove_range (t->r_buf, 0, t->r_buf->len); } // read a frame of input and buffer it thrift_framed_transport_read_frame (transport, error); // hand over what we have up to what the caller wants guint32 give = want < t->r_buf->len ? want : t->r_buf->len; // copy the data into the buffer memcpy (buf + len - want, t->r_buf->data, give); t->r_buf = g_byte_array_remove_range (t->r_buf, 0, give); want -= give; return (len - want); }
/* reads a frame and puts it into the buffer */ gboolean thrift_framed_transport_read_frame (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); guint32 sz; gint32 bytes; gboolean result = FALSE; /* read the size */ if (thrift_transport_read (t->transport, &sz, sizeof (sz), error) == sizeof (sz)) { guchar *tmpdata; sz = ntohl (sz); /* create a buffer to hold the data and read that much data */ tmpdata = g_alloca (sz); bytes = thrift_transport_read (t->transport, tmpdata, sz, error); if (bytes > 0 && (error == NULL || *error == NULL)) { /* add the data to the buffer */ g_byte_array_append (t->r_buf, tmpdata, bytes); result = TRUE; } } return result; }
/* implements thrift_transport_flush */ gboolean thrift_framed_transport_flush (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); gint32 sz_hbo, sz_nbo; guchar *tmpdata; /* get the size of the frame in host and network byte order */ sz_hbo = t->w_buf->len + sizeof(sz_nbo); sz_nbo = (gint32) htonl ((guint32) t->w_buf->len); /* copy the size of the frame and then the frame itself */ tmpdata = g_alloca (sz_hbo); memcpy (tmpdata, (guint8 *) &sz_nbo, sizeof (sz_nbo)); if (t->w_buf->len > 0) { memcpy (tmpdata + sizeof (sz_nbo), t->w_buf->data, t->w_buf->len); t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len); } /* write the buffer and then empty it */ THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, tmpdata, sz_hbo, error); THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush (t->transport, error); return TRUE; }
/* implements thrift_transport_flush */ gboolean thrift_framed_transport_flush(ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); gint32 sz_hbo, sz_nbo; // get the size of the frame in host and network byte order sz_hbo = t->w_buf->len + sizeof(sz_nbo); sz_nbo = (gint32) htonl((guint32) t->w_buf->len); // copy the size of the frame and then the frame itself guchar tmpdata[sz_hbo]; memcpy(tmpdata, (guint8 *) &sz_nbo, sizeof(sz_nbo)); if (t->w_buf->len > 0) { memcpy(tmpdata + sizeof(sz_nbo), t->w_buf->data, t->w_buf->len); t->w_buf = g_byte_array_remove_range(t->w_buf, 0, t->w_buf->len); } // write the buffer and then empty it THRIFT_TRANSPORT_GET_CLASS (t->transport)->write(t->transport, tmpdata, sz_hbo, error); if (error && *error) { printf("GError:%s\n", (*error)->message); return FALSE; } THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush(t->transport, error); if (error && *error) { printf("GError:%s\n", (*error)->message); return FALSE; } return TRUE; }
/* reads a frame and puts it into the buffer */ gboolean thrift_framed_transport_read_frame (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); gint32 sz, bytes; /* read the size */ THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport, (guint32 *) &sz, sizeof (sz), error); sz = ntohl (sz); /* create a buffer to hold the data and read that much data */ guchar tmpdata[sz]; bytes = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport, tmpdata, sz, error); /* add the data to the buffer */ g_byte_array_append (t->r_buf, tmpdata, bytes); return TRUE; }
gboolean thrift_framed_transport_write_slow(ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { THRIFT_UNUSED_VAR(error); ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); // append the data to the buffer and we're done g_byte_array_append(t->w_buf, buf, len); return TRUE; }
/* implements thrift_transport_write */ gboolean thrift_framed_transport_write(ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); /* the length of the current buffer plus the length of the data being read */ if (t->w_buf->len + len <= t->w_buf_size) { t->w_buf = g_byte_array_append(t->w_buf, buf, len); return TRUE; } return thrift_framed_transport_write_slow(transport, buf, len, error); }
/* destructor */ static void thrift_framed_transport_finalize(GObject *object) { ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object); if (transport->r_buf != NULL ) { g_byte_array_free(transport->r_buf, TRUE); } transport->r_buf = NULL; if (transport->w_buf != NULL ) { g_byte_array_free(transport->w_buf, TRUE); } transport->w_buf = NULL; }
/* implements thrift_transport_read */ gint32 thrift_framed_transport_read(ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); /* if we have enough buffer data to fulfill the read, just use * a memcpy from the buffer */ if (len <= t->r_buf->len) { memcpy(buf, t->r_buf->data, len); g_byte_array_remove_range(t->r_buf, 0, len); return len; } return thrift_framed_transport_read_slow(transport, buf, len, error); }
/* property mutator */ void thrift_framed_transport_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { THRIFT_UNUSED_VAR(pspec); ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object); switch (property_id) { case PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT: transport->transport = g_value_get_object(value); break; case PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE: transport->r_buf_size = g_value_get_uint(value); break; case PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE: transport->w_buf_size = g_value_get_uint(value); break; } }
/* implements thrift_transport_close */ gboolean thrift_framed_transport_close (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->close (t->transport, error); }
/* overrides thrift_transport_peek */ gboolean thrift_framed_transport_peek (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); return (t->r_buf->len > 0) || thrift_transport_peek (t->transport, error); }
/* implements thrift_transport_is_open */ gboolean thrift_framed_transport_is_open (ThriftTransport *transport) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->is_open (t->transport); }