+static int esd_proto_sample_cache(struct connection *c, esd_proto_t request, const void *data, size_t length) {
+ struct pa_sample_spec ss;
+ int format, rate;
+ size_t sc_length;
+ uint32_t index;
+ int *ok;
+ char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1];
+ assert(c && data && length == (ESD_NAME_MAX+3*sizeof(int)));
+
+ format = maybe_swap_endian_32(c->swap_byte_order, *(int*)data);
+ rate = maybe_swap_endian_32(c->swap_byte_order, *((int*)data + 1));
+
+ ss.rate = rate;
+ format_esd2native(format, &ss);
+
+ sc_length = (size_t) maybe_swap_endian_32(c->swap_byte_order, (*((int*)data + 2)));
+
+ if (sc_length >= MAX_CACHE_SAMPLE_SIZE)
+ return -1;
+
+ strcpy(name, SCACHE_PREFIX);
+ strncpy(name+sizeof(SCACHE_PREFIX)-1, (char*) data+3*sizeof(int), ESD_NAME_MAX);
+ name[sizeof(name)-1] = 0;
+
+ assert(!c->scache.memchunk.memblock);
+ c->scache.memchunk.memblock = pa_memblock_new(sc_length, c->protocol->core->memblock_stat);
+ c->scache.memchunk.index = 0;
+ c->scache.memchunk.length = sc_length;
+ c->scache.sample_spec = ss;
+ assert(!c->scache.name);
+ c->scache.name = pa_xstrdup(name);
+
+ c->state = ESD_CACHING_SAMPLE;
+
+ pa_scache_add_item(c->protocol->core, c->scache.name, NULL, NULL, &index);
+
+ ok = connection_write(c, sizeof(int));
+ assert(ok);
+
+ *ok = index+1;
+
+ return 0;
+}
+
+static int esd_proto_sample_get_id(struct connection *c, esd_proto_t request, const void *data, size_t length) {
+ int *ok;
+ uint32_t index;
+ char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1];
+ assert(c && data && length == ESD_NAME_MAX);
+
+ ok = connection_write(c, sizeof(int));
+ assert(ok);
+
+ *ok = -1;
+
+ strcpy(name, SCACHE_PREFIX);
+ strncpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX);
+ name[sizeof(name)-1] = 0;
+
+ if ((index = pa_scache_get_id_by_name(c->protocol->core, name)) != PA_IDXSET_INVALID)
+ *ok = (int) index +1;
+
+ return 0;
+}
+
+static int esd_proto_sample_free_or_play(struct connection *c, esd_proto_t request, const void *data, size_t length) {
+ int *ok;
+ const char *name;
+ uint32_t index;
+ assert(c && data && length == sizeof(int));
+
+ index = (uint32_t) maybe_swap_endian_32(c->swap_byte_order, *(int*)data)-1;
+
+ ok = connection_write(c, sizeof(int));
+ assert(ok);
+
+ *ok = 0;
+
+ if ((name = pa_scache_get_name_by_id(c->protocol->core, index))) {
+ if (request == ESD_PROTO_SAMPLE_PLAY) {
+ struct pa_sink *sink;
+
+ if ((sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1)))
+ if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM) >= 0)
+ *ok = (int) index+1;
+ } else {
+ assert(request == ESD_PROTO_SAMPLE_FREE);
+
+ if (pa_scache_remove_item(c->protocol->core, name) >= 0)
+ *ok = (int) index+1;
+ }
+ }
+
+ return 0;
+}
+
+static int esd_proto_standby_or_resume(struct connection *c, esd_proto_t request, const void *data, size_t length) {
+ int *ok;
+ ok = connection_write(c, sizeof(int)*2);
+ assert(ok);
+ ok[0] = 1;
+ ok[1] = 1;
+ return 0;
+}
+