blob: 91818e91aa6438be6fc61a09706f73f178fd64db [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_memory_buffer.h>
/* object properties */
enum _ThriftMemoryBufferProperties
{
PROP_0,
PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE,
PROP_THRIFT_MEMORY_BUFFER_BUFFER,
PROP_THRIFT_MEMORY_BUFFER_OWNER
};
G_DEFINE_TYPE(ThriftMemoryBuffer, thrift_memory_buffer, THRIFT_TYPE_TRANSPORT)
/* implements thrift_transport_is_open */
gboolean
thrift_memory_buffer_is_open (ThriftTransport *transport)
{
THRIFT_UNUSED_VAR (transport);
return TRUE;
}
/* implements thrift_transport_open */
gboolean
thrift_memory_buffer_open (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_close */
gboolean
thrift_memory_buffer_close (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_read */
gint32
thrift_memory_buffer_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport);
guint32 give = len;
THRIFT_UNUSED_VAR (error);
/* if the requested bytes are more than what we have available,
* just give all that we have the buffer */
if (t->buf->len < len)
{
give = t->buf->len;
}
memcpy (buf, t->buf->data, give);
g_byte_array_remove_range (t->buf, 0, give);
return give;
}
/* implements thrift_transport_read_end
* called when read is complete. nothing to do on our end. */
gboolean
thrift_memory_buffer_read_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_write */
gboolean
thrift_memory_buffer_write (ThriftTransport *transport,
const gpointer buf,
const guint32 len, GError **error)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport);
THRIFT_UNUSED_VAR (error);
/* return an exception if the buffer doesn't have enough space. */
if (len > t->buf_size - t->buf->len)
{
g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND,
"unable to write %d bytes to buffer of length %d",
len, t->buf_size);
return FALSE;
} else {
t->buf = g_byte_array_append (t->buf, buf, len);
return TRUE;
}
}
/* implements thrift_transport_write_end
* called when write is complete. nothing to do on our end. */
gboolean
thrift_memory_buffer_write_end (ThriftTransport *transport, GError **error)
{
/* satisfy -Wall */
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* implements thrift_transport_flush */
gboolean
thrift_memory_buffer_flush (ThriftTransport *transport, GError **error)
{
THRIFT_UNUSED_VAR (transport);
THRIFT_UNUSED_VAR (error);
return TRUE;
}
/* initializes class before constructor properties are set */
static void
thrift_memory_buffer_init (ThriftMemoryBuffer *t)
{
THRIFT_UNUSED_VAR (t);
}
/* destructor */
static void
thrift_memory_buffer_finalize (GObject *object)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
if (t->owner && t->buf != NULL)
{
g_byte_array_unref (t->buf);
}
t->buf = NULL;
}
/* property accessor */
void
thrift_memory_buffer_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE:
g_value_set_uint (value, t->buf_size);
break;
case PROP_THRIFT_MEMORY_BUFFER_BUFFER:
g_value_set_pointer (value, (gpointer) (t->buf));
break;
case PROP_THRIFT_MEMORY_BUFFER_OWNER:
g_value_set_boolean (value, t->owner);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* property mutator */
void
thrift_memory_buffer_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE:
t->buf_size = g_value_get_uint (value);
break;
case PROP_THRIFT_MEMORY_BUFFER_BUFFER:
t->buf = (GByteArray*) g_value_get_pointer (value);
break;
case PROP_THRIFT_MEMORY_BUFFER_OWNER:
t->owner = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* initializes class after constructor properties are set */
static void
thrift_memory_buffer_constructed (GObject *object)
{
ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object);
if (t->buf == NULL) {
t->buf = g_byte_array_new ();
}
G_OBJECT_CLASS (thrift_memory_buffer_parent_class)->constructed (object);
}
/* initializes the class */
static void
thrift_memory_buffer_class_init (ThriftMemoryBufferClass *cls)
{
ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls);
GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
GParamSpec *param_spec = NULL;
/* setup accessors and mutators */
gobject_class->get_property = thrift_memory_buffer_get_property;
gobject_class->set_property = thrift_memory_buffer_set_property;
param_spec = g_param_spec_uint ("buf_size",
"buffer size (construct)",
"Set the read/write buffer size limit",
0, /* min */
G_MAXUINT32, /* max */
G_MAXUINT32, /* default */
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE,
param_spec);
param_spec = g_param_spec_pointer ("buf",
"internal buffer (GByteArray)",
"Set the internal buffer (GByteArray)",
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_MEMORY_BUFFER_BUFFER,
param_spec);
param_spec = g_param_spec_boolean ("owner",
"internal buffer memory management policy",
"Set whether internal buffer should be"
" unreferenced when thrift_memory_buffer"
" is finalized",
TRUE,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_THRIFT_MEMORY_BUFFER_OWNER,
param_spec);
gobject_class->constructed = thrift_memory_buffer_constructed;
gobject_class->finalize = thrift_memory_buffer_finalize;
ttc->is_open = thrift_memory_buffer_is_open;
ttc->open = thrift_memory_buffer_open;
ttc->close = thrift_memory_buffer_close;
ttc->read = thrift_memory_buffer_read;
ttc->read_end = thrift_memory_buffer_read_end;
ttc->write = thrift_memory_buffer_write;
ttc->write_end = thrift_memory_buffer_write_end;
ttc->flush = thrift_memory_buffer_flush;
}