43 } xmms_ipc_msg_data_t;
45 struct xmms_ipc_msg_St {
46 xmms_ipc_msg_data_t *data;
52 static void xmms_ipc_msg_store_uint32 (
xmms_ipc_msg_t *msg, uint32_t offset, uint32_t v);
54 static uint32_t internal_ipc_msg_put_bin (
xmms_ipc_msg_t *msg,
const unsigned char *data,
unsigned int len);
55 static uint32_t internal_ipc_msg_put_error (
xmms_ipc_msg_t *msg,
const char *errmsg);
56 static uint32_t internal_ipc_msg_put_uint32 (
xmms_ipc_msg_t *msg, uint32_t v);
57 static uint32_t internal_ipc_msg_put_int32 (
xmms_ipc_msg_t *msg, int32_t v);
58 static uint32_t internal_ipc_msg_put_string (
xmms_ipc_msg_t *msg,
const char *str);
63 static bool xmms_ipc_msg_get_error_alloc (
xmms_ipc_msg_t *msg,
char **buf,
unsigned int *len);
64 static bool xmms_ipc_msg_get_uint32 (
xmms_ipc_msg_t *msg, uint32_t *v);
65 static bool xmms_ipc_msg_get_int32 (
xmms_ipc_msg_t *msg, int32_t *v);
66 static bool xmms_ipc_msg_get_string_alloc (
xmms_ipc_msg_t *msg,
char **buf,
unsigned int *len);
68 static bool xmms_ipc_msg_get_bin_alloc (
xmms_ipc_msg_t *msg,
unsigned char **buf,
unsigned int *len);
74 xmms_ipc_append_coll_attr (
const char *key,
xmmsv_t *value,
void *userdata)
83 internal_ipc_msg_put_string (msg, key);
84 internal_ipc_msg_put_string (msg, s);
88 xmms_ipc_count_coll_attr (
const char *key,
xmmsv_t *value,
void *userdata)
90 int *n = (
int *)userdata;
135 msg->data->header.length = htonl (len);
143 return ntohl (msg->data->header.length);
151 return ntohl (msg->data->header.object);
159 msg->data->header.object = htonl (
object);
167 return ntohl (msg->data->header.cmd);
175 msg->data->header.cmd = htonl (cmd);
181 msg->data->header.cookie = htonl (cookie);
189 return ntohl (msg->data->header.cookie);
206 unsigned int ret, len;
216 buf = (
char *) (msg->data->rawdata + msg->xfered);
225 *disconnected =
true;
231 *disconnected =
true;
237 return (len == msg->xfered);
251 unsigned int ret, len;
262 if (len > msg->size) {
264 newbuf = realloc (msg->data, len);
267 *disconnected =
true;
275 if (msg->xfered == len) {
282 buf = (
char *) (msg->data->rawdata + msg->xfered);
291 *disconnected =
true;
295 }
else if (ret == 0) {
297 *disconnected =
true;
308 xmms_ipc_msg_put_data (
xmms_ipc_msg_t *msg,
const void *data,
unsigned int len)
316 if (total > msg->size) {
324 msg->data = realloc (msg->data, msg->size + realloc_size);
325 msg->size += realloc_size;
329 memcpy (&msg->data->header.data[total], data, len);
342 const unsigned char *data,
345 internal_ipc_msg_put_uint32 (msg, len);
347 return xmms_ipc_msg_put_data (msg, data, len);
351 internal_ipc_msg_put_error (
xmms_ipc_msg_t *msg,
const char *errmsg)
358 return internal_ipc_msg_put_uint32 (msg, 0);
361 internal_ipc_msg_put_uint32 (msg, strlen (errmsg) + 1);
363 return xmms_ipc_msg_put_data (msg, errmsg, strlen (errmsg) + 1);
371 return xmms_ipc_msg_put_data (msg, &v,
sizeof (v));
376 uint32_t offset, uint32_t v)
380 memcpy (&msg->data->header.data[offset], &v, sizeof (v));
388 return xmms_ipc_msg_put_data (msg, &v,
sizeof (v));
392 internal_ipc_msg_put_string (
xmms_ipc_msg_t *msg,
const char *str)
399 return internal_ipc_msg_put_uint32 (msg, 0);
402 internal_ipc_msg_put_uint32 (msg, strlen (str) + 1);
404 return xmms_ipc_msg_put_data (msg, str, strlen (str) + 1);
413 uint32_t ret, *idlist;
428 internal_ipc_msg_put_uint32 (msg, n);
436 for (n = 0; idlist[n] != 0; n++) { }
438 internal_ipc_msg_put_uint32 (msg, n);
439 for (n = 0; idlist[n] != 0; n++) {
440 internal_ipc_msg_put_uint32 (msg, idlist[n]);
449 ret = internal_ipc_msg_put_uint32 (msg, n);
456 x_api_error (
"Non collection operand", 0);
461 ret = internal_ipc_msg_put_collection (msg, op);
476 const unsigned char *bc;
481 internal_ipc_msg_put_int32 (msg, type);
491 ret = internal_ipc_msg_put_error (msg, s);
497 ret = internal_ipc_msg_put_int32 (msg, i);
503 ret = internal_ipc_msg_put_string (msg, s);
509 ret = internal_ipc_msg_put_collection (msg, c);
515 ret = internal_ipc_msg_put_bin (msg, bc, bl);
518 ret = internal_ipc_msg_put_value_list (msg, v);
521 ret = internal_ipc_msg_put_value_dict (msg, v);
532 x_internal_error (
"Tried to serialize value of unsupported type");
544 uint32_t ret, offset, count;
551 offset = internal_ipc_msg_put_uint32 (msg, 0);
562 xmms_ipc_msg_store_uint32 (msg, offset, count);
573 uint32_t ret, offset, count;
580 offset = internal_ipc_msg_put_uint32 (msg, 0);
585 ret = internal_ipc_msg_put_string (msg, key);
592 xmms_ipc_msg_store_uint32 (msg, offset, count);
599 xmms_ipc_msg_get_data (
xmms_ipc_msg_t *msg,
void *buf,
unsigned int len)
608 memcpy (buf, &msg->data->header.data[msg->get_pos], len);
621 return xmms_ipc_msg_get_string_alloc (msg, buf, len);
629 ret = xmms_ipc_msg_get_data (msg, v,
sizeof (*v));
643 ret = xmms_ipc_msg_get_data (msg, v,
sizeof (*v));
659 if (!xmms_ipc_msg_get_uint32 (msg, &l)) {
671 if (!xmms_ipc_msg_get_data (msg, str, l)) {
692 if (!xmms_ipc_msg_get_uint32 (msg, &l)) {
704 if (!xmms_ipc_msg_get_data (msg, b, l)) {
720 unsigned int n_items;
722 uint32_t *idlist = NULL;
726 if (!xmms_ipc_msg_get_uint32 (msg, &type)) {
733 if (!xmms_ipc_msg_get_uint32 (msg, &n_items)) {
737 for (i = 0; i < n_items; i++) {
739 if (!xmms_ipc_msg_get_string_alloc (msg, &key, &len)) {
742 if (!xmms_ipc_msg_get_string_alloc (msg, &val, &len)) {
753 if (!xmms_ipc_msg_get_uint32 (msg, &n_items)) {
757 if (!(idlist =
x_new (uint32_t, n_items + 1))) {
761 for (i = 0; i < n_items; i++) {
762 if (!xmms_ipc_msg_get_uint32 (msg, &
id)) {
775 if (!xmms_ipc_msg_get_uint32 (msg, &n_items)) {
779 for (i = 0; i < n_items; i++) {
783 if (!xmms_ipc_msg_get_uint32 (msg, &type) ||
785 !xmms_ipc_msg_get_collection_alloc (msg, &operand)) {
796 if (idlist != NULL) {
810 unsigned int len, ignore;
815 if (!xmms_ipc_msg_get_uint32 (msg, &len)) {
822 if (!xmms_ipc_msg_get_string_alloc (msg, &key, &ignore)) {
826 if (!xmms_ipc_msg_get_value_alloc (msg, &v)) {
841 x_internal_error (
"Message from server did not parse correctly!");
854 if (!xmms_ipc_msg_get_uint32 (msg, &len)) {
860 if (xmms_ipc_msg_get_value_alloc (msg, &v)) {
873 x_internal_error (
"Message from server did not parse correctly!");
883 if (!xmms_ipc_msg_get_int32 (msg, &type)) {
887 return xmms_ipc_msg_get_value_of_type_alloc (msg, type, val);
902 if (!xmms_ipc_msg_get_error_alloc (msg, &s, &len)) {
909 if (!xmms_ipc_msg_get_int32 (msg, &i)) {
915 if (!xmms_ipc_msg_get_string_alloc (msg, &s, &len)) {
922 if (!xmmsc_deserialize_dict (msg, val)) {
928 if (!xmmsc_deserialize_list (msg, val)) {
934 if (!xmms_ipc_msg_get_collection_alloc (msg, &c)) {
942 if (!xmms_ipc_msg_get_bin_alloc (msg, &d, &len)) {
953 x_internal_error (
"Got message of unknown type!");
963 return xmms_ipc_msg_get_value_alloc (msg, val);
xmmsv_t * xmmsv_new_dict(void)
Allocates a new dict xmmsv_t.
int xmms_ipc_transport_read(xmms_ipc_transport_t *ipct, char *buffer, int len)
#define XMMS_IPC_MSG_HEAD_LEN
#define x_return_val_if_fail(expr, val)
void xmms_ipc_msg_set_cookie(xmms_ipc_msg_t *msg, uint32_t cookie)
void xmmsv_unref(xmmsv_t *val)
Decreases the references for the xmmsv_t When the number of references reaches 0 it will be freed...
int xmmsv_dict_set(xmmsv_t *dictv, const char *key, xmmsv_t *val)
Insert an element under the given key in the dict xmmsv_t.
bool xmms_socket_error_recoverable(void)
xmms_ipc_msg_t * xmms_ipc_msg_alloc(void)
int xmmsv_dict_iter_valid(xmmsv_dict_iter_t *it)
Check whether the iterator is valid and points to a valid pair.
int xmmsv_get_list_iter(const xmmsv_t *val, xmmsv_list_iter_t **it)
Retrieves a list iterator from a list xmmsv_t.
xmmsv_t * xmmsv_new_error(const char *errstr)
Allocates a new error xmmsv_t.
bool xmms_ipc_msg_get_value(xmms_ipc_msg_t *msg, xmmsv_t **val)
xmmsv_t * xmmsv_new_none(void)
Allocates a new empty xmmsv_t.
int xmmsv_list_iter_entry(xmmsv_list_iter_t *it, xmmsv_t **val)
Get the element currently pointed at by the iterator.
uint32_t xmms_ipc_msg_get_cmd(const xmms_ipc_msg_t *msg)
void xmmsv_coll_attribute_set(xmmsv_coll_t *coll, const char *key, const char *value)
Set an attribute in the given collection.
xmmsv_t * xmmsv_new_string(const char *s)
Allocates a new string xmmsv_t.
int xmmsv_get_int(const xmmsv_t *val, int32_t *r)
Retrieves a signed integer from the value.
int xmmsv_list_append(xmmsv_t *listv, xmmsv_t *val)
Append an element to the end of the list xmmsv_t.
#define XMMS_IPC_MSG_DEFAULT_SIZE
struct xmmsv_St * xmmsv_coll_operands_get(xmmsv_coll_t *coll)
void xmms_ipc_msg_set_cmd(xmms_ipc_msg_t *msg, uint32_t cmd)
void xmms_ipc_msg_destroy(xmms_ipc_msg_t *msg)
int xmmsv_dict_foreach(xmmsv_t *dictv, xmmsv_dict_foreach_func func, void *user_data)
Apply a function to each key-element pair in the list.
struct xmms_ipc_msg_St xmms_ipc_msg_t
xmms_ipc_msg_t * xmms_ipc_msg_new(uint32_t object, uint32_t cmd)
int xmmsv_get_coll(const xmmsv_t *val, xmmsv_coll_t **coll)
Retrieves a collection from the value.
int xmmsv_dict_iter_pair(xmmsv_dict_iter_t *it, const char **key, xmmsv_t **val)
Get the key-element pair currently pointed at by the iterator.
xmmsv_t * xmmsv_new_coll(xmmsv_coll_t *coll)
Allocates a new collection xmmsv_t.
void xmms_ipc_msg_set_object(xmms_ipc_msg_t *msg, uint32_t object)
bool xmms_ipc_msg_write_transport(xmms_ipc_msg_t *msg, xmms_ipc_transport_t *transport, bool *disconnected)
Try to write message to transport.
uint32_t xmms_ipc_msg_get_length(const xmms_ipc_msg_t *msg)
struct xmmsv_coll_St xmmsv_coll_t
int xmmsv_list_get_size(xmmsv_t *listv)
Return the size of the list.
void xmmsv_list_iter_next(xmmsv_list_iter_t *it)
Advance the iterator to the next element in the list.
xmmsv_coll_t * xmmsv_coll_new(xmmsv_coll_type_t type)
Allocate a new collection of the given type.
xmmsv_type_t xmmsv_get_type(const xmmsv_t *val)
Get the type of the value.
xmmsv_t * xmmsv_new_int(int32_t i)
Allocates a new integer xmmsv_t.
int xmms_ipc_transport_write(xmms_ipc_transport_t *ipct, char *buffer, int len)
struct xmmsv_St * xmmsv_coll_attributes_get(xmmsv_coll_t *coll)
void xmmsv_coll_add_operand(xmmsv_coll_t *coll, xmmsv_coll_t *op)
Add the operand to the given collection.
int xmmsv_get_error(const xmmsv_t *val, const char **r)
Retrieves an error string describing the server error from the value.
void xmmsv_dict_iter_next(xmmsv_dict_iter_t *it)
Advance the iterator to the next pair in the dict.
uint32_t xmms_ipc_msg_put_value(xmms_ipc_msg_t *msg, xmmsv_t *v)
void xmmsv_coll_set_idlist(xmmsv_coll_t *coll, unsigned int ids[])
Set the list of ids in the given collection.
#define x_new0(type, num)
xmmsv_t * xmmsv_new_bin(unsigned char *data, unsigned int len)
Allocates a new binary data xmmsv_t.
int xmmsv_get_dict_iter(const xmmsv_t *val, xmmsv_dict_iter_t **it)
Retrieves a dict iterator from a dict xmmsv_t.
bool xmms_ipc_msg_read_transport(xmms_ipc_msg_t *msg, xmms_ipc_transport_t *transport, bool *disconnected)
Try to read message from transport into msg.
uint32_t xmms_ipc_msg_get_object(const xmms_ipc_msg_t *msg)
int xmmsv_get_bin(const xmmsv_t *val, const unsigned char **r, unsigned int *rlen)
Retrieves binary data from the value.
xmmsv_t * xmmsv_new_list(void)
Allocates a new list xmmsv_t.
#define x_return_if_fail(expr)
int xmmsv_get_string(const xmmsv_t *val, const char **r)
Retrieves a string from the value.
void xmms_ipc_msg_set_length(xmms_ipc_msg_t *msg, uint32_t len)
uint32_t * xmmsv_coll_get_idlist(xmmsv_coll_t *coll)
Return the list of ids stored in the collection.
xmmsv_coll_type_t xmmsv_coll_get_type(xmmsv_coll_t *coll)
Return the type of the collection.
struct xmmsv_list_iter_St xmmsv_list_iter_t
int xmmsv_list_iter_valid(xmmsv_list_iter_t *it)
Check whether the iterator is valid and points to a valid element.
void xmmsv_coll_unref(xmmsv_coll_t *coll)
Decreases the references for the xmmsv_coll_t When the number of references reaches 0 it will be free...
uint32_t xmms_ipc_msg_get_cookie(const xmms_ipc_msg_t *msg)
struct xmmsv_dict_iter_St xmmsv_dict_iter_t