]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | #include <netdb.h> | |
21 | #include <stdlib.h> | |
22 | #include <stdio.h> | |
23 | #include <string.h> | |
24 | #include <unistd.h> | |
25 | ||
26 | #include <thrift/c_glib/thrift.h> | |
27 | #include <thrift/c_glib/transport/thrift_transport.h> | |
28 | #include <thrift/c_glib/transport/thrift_memory_buffer.h> | |
29 | ||
30 | /* object properties */ | |
31 | enum _ThriftMemoryBufferProperties | |
32 | { | |
33 | PROP_0, | |
34 | PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE, | |
35 | PROP_THRIFT_MEMORY_BUFFER_BUFFER, | |
36 | PROP_THRIFT_MEMORY_BUFFER_OWNER | |
37 | }; | |
38 | ||
39 | G_DEFINE_TYPE(ThriftMemoryBuffer, thrift_memory_buffer, THRIFT_TYPE_TRANSPORT) | |
40 | ||
41 | /* implements thrift_transport_is_open */ | |
42 | gboolean | |
43 | thrift_memory_buffer_is_open (ThriftTransport *transport) | |
44 | { | |
45 | THRIFT_UNUSED_VAR (transport); | |
46 | return TRUE; | |
47 | } | |
48 | ||
49 | /* implements thrift_transport_open */ | |
50 | gboolean | |
51 | thrift_memory_buffer_open (ThriftTransport *transport, GError **error) | |
52 | { | |
53 | THRIFT_UNUSED_VAR (transport); | |
54 | THRIFT_UNUSED_VAR (error); | |
55 | return TRUE; | |
56 | } | |
57 | ||
58 | /* implements thrift_transport_close */ | |
59 | gboolean | |
60 | thrift_memory_buffer_close (ThriftTransport *transport, GError **error) | |
61 | { | |
62 | THRIFT_UNUSED_VAR (transport); | |
63 | THRIFT_UNUSED_VAR (error); | |
64 | return TRUE; | |
65 | } | |
66 | ||
67 | /* implements thrift_transport_read */ | |
68 | gint32 | |
69 | thrift_memory_buffer_read (ThriftTransport *transport, gpointer buf, | |
70 | guint32 len, GError **error) | |
71 | { | |
72 | ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport); | |
73 | guint32 give = len; | |
74 | ||
75 | THRIFT_UNUSED_VAR (error); | |
76 | ||
77 | /* if the requested bytes are more than what we have available, | |
78 | * just give all that we have the buffer */ | |
79 | if (t->buf->len < len) | |
80 | { | |
81 | give = t->buf->len; | |
82 | } | |
83 | ||
84 | memcpy (buf, t->buf->data, give); | |
85 | g_byte_array_remove_range (t->buf, 0, give); | |
86 | ||
87 | return give; | |
88 | } | |
89 | ||
90 | /* implements thrift_transport_read_end | |
91 | * called when read is complete. nothing to do on our end. */ | |
92 | gboolean | |
93 | thrift_memory_buffer_read_end (ThriftTransport *transport, GError **error) | |
94 | { | |
95 | /* satisfy -Wall */ | |
96 | THRIFT_UNUSED_VAR (transport); | |
97 | THRIFT_UNUSED_VAR (error); | |
98 | return TRUE; | |
99 | } | |
100 | ||
101 | /* implements thrift_transport_write */ | |
102 | gboolean | |
103 | thrift_memory_buffer_write (ThriftTransport *transport, | |
104 | const gpointer buf, | |
105 | const guint32 len, GError **error) | |
106 | { | |
107 | ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport); | |
108 | ||
109 | THRIFT_UNUSED_VAR (error); | |
110 | ||
111 | /* return an exception if the buffer doesn't have enough space. */ | |
112 | if (len > t->buf_size - t->buf->len) | |
113 | { | |
114 | g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, | |
115 | "unable to write %d bytes to buffer of length %d", | |
116 | len, t->buf_size); | |
117 | return FALSE; | |
118 | } else { | |
119 | t->buf = g_byte_array_append (t->buf, buf, len); | |
120 | return TRUE; | |
121 | } | |
122 | } | |
123 | ||
124 | /* implements thrift_transport_write_end | |
125 | * called when write is complete. nothing to do on our end. */ | |
126 | gboolean | |
127 | thrift_memory_buffer_write_end (ThriftTransport *transport, GError **error) | |
128 | { | |
129 | /* satisfy -Wall */ | |
130 | THRIFT_UNUSED_VAR (transport); | |
131 | THRIFT_UNUSED_VAR (error); | |
132 | return TRUE; | |
133 | } | |
134 | ||
135 | /* implements thrift_transport_flush */ | |
136 | gboolean | |
137 | thrift_memory_buffer_flush (ThriftTransport *transport, GError **error) | |
138 | { | |
139 | THRIFT_UNUSED_VAR (transport); | |
140 | THRIFT_UNUSED_VAR (error); | |
141 | ||
142 | return TRUE; | |
143 | } | |
144 | ||
145 | /* initializes class before constructor properties are set */ | |
146 | static void | |
147 | thrift_memory_buffer_init (ThriftMemoryBuffer *t) | |
148 | { | |
149 | THRIFT_UNUSED_VAR (t); | |
150 | } | |
151 | ||
152 | /* destructor */ | |
153 | static void | |
154 | thrift_memory_buffer_finalize (GObject *object) | |
155 | { | |
156 | ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); | |
157 | ||
158 | if (t->owner && t->buf != NULL) | |
159 | { | |
160 | g_byte_array_unref (t->buf); | |
161 | } | |
162 | t->buf = NULL; | |
163 | } | |
164 | ||
165 | /* property accessor */ | |
166 | void | |
167 | thrift_memory_buffer_get_property (GObject *object, guint property_id, | |
168 | GValue *value, GParamSpec *pspec) | |
169 | { | |
170 | ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); | |
171 | ||
172 | THRIFT_UNUSED_VAR (pspec); | |
173 | ||
174 | switch (property_id) | |
175 | { | |
176 | case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE: | |
177 | g_value_set_uint (value, t->buf_size); | |
178 | break; | |
179 | case PROP_THRIFT_MEMORY_BUFFER_BUFFER: | |
180 | g_value_set_pointer (value, (gpointer) (t->buf)); | |
181 | break; | |
182 | case PROP_THRIFT_MEMORY_BUFFER_OWNER: | |
183 | g_value_set_boolean (value, t->owner); | |
184 | break; | |
185 | default: | |
186 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
187 | break; | |
188 | } | |
189 | } | |
190 | ||
191 | /* property mutator */ | |
192 | void | |
193 | thrift_memory_buffer_set_property (GObject *object, guint property_id, | |
194 | const GValue *value, GParamSpec *pspec) | |
195 | { | |
196 | ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); | |
197 | ||
198 | THRIFT_UNUSED_VAR (pspec); | |
199 | ||
200 | switch (property_id) | |
201 | { | |
202 | case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE: | |
203 | t->buf_size = g_value_get_uint (value); | |
204 | break; | |
205 | case PROP_THRIFT_MEMORY_BUFFER_BUFFER: | |
206 | t->buf = (GByteArray*) g_value_get_pointer (value); | |
207 | break; | |
208 | case PROP_THRIFT_MEMORY_BUFFER_OWNER: | |
209 | t->owner = g_value_get_boolean (value); | |
210 | break; | |
211 | default: | |
212 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
213 | break; | |
214 | } | |
215 | } | |
216 | ||
217 | /* initializes class after constructor properties are set */ | |
218 | static void | |
219 | thrift_memory_buffer_constructed (GObject *object) | |
220 | { | |
221 | ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); | |
222 | ||
223 | if (t->buf == NULL) { | |
224 | t->buf = g_byte_array_new (); | |
225 | } | |
226 | ||
227 | G_OBJECT_CLASS (thrift_memory_buffer_parent_class)->constructed (object); | |
228 | } | |
229 | ||
230 | /* initializes the class */ | |
231 | static void | |
232 | thrift_memory_buffer_class_init (ThriftMemoryBufferClass *cls) | |
233 | { | |
234 | ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls); | |
235 | GObjectClass *gobject_class = G_OBJECT_CLASS (cls); | |
236 | GParamSpec *param_spec = NULL; | |
237 | ||
238 | /* setup accessors and mutators */ | |
239 | gobject_class->get_property = thrift_memory_buffer_get_property; | |
240 | gobject_class->set_property = thrift_memory_buffer_set_property; | |
241 | ||
242 | param_spec = g_param_spec_uint ("buf_size", | |
243 | "buffer size (construct)", | |
244 | "Set the read/write buffer size limit", | |
245 | 0, /* min */ | |
246 | G_MAXUINT32, /* max */ | |
247 | G_MAXUINT32, /* default */ | |
248 | G_PARAM_CONSTRUCT_ONLY | | |
249 | G_PARAM_READWRITE); | |
250 | g_object_class_install_property (gobject_class, | |
251 | PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE, | |
252 | param_spec); | |
253 | ||
254 | param_spec = g_param_spec_pointer ("buf", | |
255 | "internal buffer (GByteArray)", | |
256 | "Set the internal buffer (GByteArray)", | |
257 | G_PARAM_CONSTRUCT_ONLY | | |
258 | G_PARAM_READWRITE); | |
259 | g_object_class_install_property (gobject_class, | |
260 | PROP_THRIFT_MEMORY_BUFFER_BUFFER, | |
261 | param_spec); | |
262 | ||
263 | param_spec = g_param_spec_boolean ("owner", | |
264 | "internal buffer memory management policy", | |
265 | "Set whether internal buffer should be" | |
266 | " unreferenced when thrift_memory_buffer" | |
267 | " is finalized", | |
268 | TRUE, | |
269 | G_PARAM_CONSTRUCT_ONLY | | |
270 | G_PARAM_READWRITE); | |
271 | g_object_class_install_property (gobject_class, | |
272 | PROP_THRIFT_MEMORY_BUFFER_OWNER, | |
273 | param_spec); | |
274 | ||
275 | gobject_class->constructed = thrift_memory_buffer_constructed; | |
276 | gobject_class->finalize = thrift_memory_buffer_finalize; | |
277 | ttc->is_open = thrift_memory_buffer_is_open; | |
278 | ttc->open = thrift_memory_buffer_open; | |
279 | ttc->close = thrift_memory_buffer_close; | |
280 | ttc->read = thrift_memory_buffer_read; | |
281 | ttc->read_end = thrift_memory_buffer_read_end; | |
282 | ttc->write = thrift_memory_buffer_write; | |
283 | ttc->write_end = thrift_memory_buffer_write_end; | |
284 | ttc->flush = thrift_memory_buffer_flush; | |
285 | } |