예제 #1
0
/* The following is based on an example from the GNU libc documentation */
size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) {
    size_t size = 100;
    struct chunk *c = NULL;

    pa_assert(sb);
    pa_assert(format);

    for(;;) {
        va_list ap;
        int r;

        c = pa_xrealloc(c, PA_ALIGN(sizeof(struct chunk)) + size);

        va_start(ap, format);
        r = vsnprintf(CHUNK_TO_TEXT(c), size, format, ap);
        CHUNK_TO_TEXT(c)[size-1] = 0;
        va_end(ap);

        if (r > -1 && (size_t) r < size) {
            c->length = (size_t) r;
            append(sb, c);
            return (size_t) r;
        }

        if (r > -1)    /* glibc 2.1 */
            size = (size_t) r+1;
        else           /* glibc 2.0 */
            size *= 2;
    }
}
예제 #2
0
파일: core-util.c 프로젝트: thewb/mokoiax
/* Same as the previous function, but use a va_list instead of an
 * ellipsis */
char *pa_vsprintf_malloc(const char *format, va_list ap) {
    int  size = 100;
    char *c = NULL;

    pa_assert(format);

    for(;;) {
        int r;
        va_list aq;

        c = pa_xrealloc(c, size);

        va_copy(aq, ap);
        r = vsnprintf(c, size, format, aq);
        va_end(aq);

        c[size-1] = 0;

        if (r > -1 && r < size)
            return c;

        if (r > -1)    /* glibc 2.1 */
            size = r+1;
        else           /* glibc 2.0 */
            size *= 2;
    }
}
예제 #3
0
static inline void extend(pa_tagstruct*t, size_t l) {
    pa_assert(t);
    pa_assert(t->type != PA_TAGSTRUCT_FIXED);

    if (t->length+l <= t->allocated)
        return;

    t->data = pa_xrealloc(t->data, t->allocated = t->length+l+100);
}
예제 #4
0
void pa_dynarray_append(pa_dynarray *array, void *p) {
    pa_assert(array);
    pa_assert(p);

    if (array->n_entries == array->n_allocated) {
        unsigned n = PA_MAX(array->n_allocated * 2, 25U);

        array->data = pa_xrealloc(array->data, sizeof(void *) * n);
        array->n_allocated = n;
    }

    array->data[array->n_entries++] = p;
}
예제 #5
0
static inline void extend(pa_tagstruct*t, size_t l) {
    pa_assert(t);
    pa_assert(t->type != PA_TAGSTRUCT_FIXED);

    if (t->length+l <= t->allocated)
        return;

    if (t->type == PA_TAGSTRUCT_DYNAMIC)
        t->data = pa_xrealloc(t->data, t->allocated = t->length + l + GROW_TAG_SIZE);
    else if (t->type == PA_TAGSTRUCT_APPENDED) {
        t->type = PA_TAGSTRUCT_DYNAMIC;
        t->data = pa_xmalloc(t->allocated = t->length + l + GROW_TAG_SIZE);
        memcpy(t->data, t->per_type.appended, t->length);
    }
}
예제 #6
0
파일: utf8.c 프로젝트: KimT/pulseaudio_kt
static char* iconv_simple(const char *str, const char *to, const char *from) {
    char *new_str;
    size_t len, inlen;
    iconv_t cd;
    ICONV_CONST char *inbuf;
    char *outbuf;
    size_t res, inbytes, outbytes;

    pa_assert(str);
    pa_assert(to);
    pa_assert(from);

    cd = iconv_open(to, from);
    if (cd == (iconv_t)-1)
        return NULL;

    inlen = len = strlen(str) + 1;
    new_str = pa_xmalloc(len);

    for (;;) {
        inbuf = (ICONV_CONST char*) str; /* Brain dead prototype for iconv() */
        inbytes = inlen;
        outbuf = new_str;
        outbytes = len;

        res = iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes);

        if (res != (size_t)-1)
            break;

        if (errno != E2BIG) {
            pa_xfree(new_str);
            new_str = NULL;
            break;
        }

        pa_assert(inbytes != 0);

        len += inbytes;
        new_str = pa_xrealloc(new_str, len);
    }

    iconv_close(cd);

    return new_str;
}
예제 #7
0
/**
 * Pulseaudio callback when new data is available.
 */
static void
stream_read_callback (pa_stream * s,
		      size_t length,
		      void *userdata)
{
  const void *data;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Got %u/%u bytes of PCM data\n",
	      length,
	      pcm_length);

  GNUNET_assert (NULL != s);
  GNUNET_assert (length > 0);
  if (stdio_event)
    mainloop_api->io_enable (stdio_event, PA_IO_EVENT_OUTPUT);

  if (pa_stream_peek (s, (const void **) &data, &length) < 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("pa_stream_peek() failed: %s\n"),
		pa_strerror (pa_context_errno (context)));
    quit (1);
    return;
  }
  GNUNET_assert (NULL != data);
  GNUNET_assert (length > 0);
  if (NULL != transmit_buffer)
  {
    transmit_buffer = pa_xrealloc (transmit_buffer,
				   transmit_buffer_length + length);
    memcpy (&transmit_buffer[transmit_buffer_length],
	    data,
	    length);
    transmit_buffer_length += length;
  }
  else
  {
    transmit_buffer = pa_xmalloc (length);
    memcpy (transmit_buffer, data, length);
    transmit_buffer_length = length;
    transmit_buffer_index = 0;
  }
  pa_stream_drop (s);
  packetizer ();
}
예제 #8
0
pa_prioq_item* pa_prioq_put(pa_prioq *q, void *p) {
    pa_prioq_item *i;

    pa_assert(q);

    if (q->n_items >= q->n_allocated) {
        q->n_allocated = PA_MAX(q->n_items+1, q->n_allocated)*2;
        q->items = pa_xrealloc(q->items, sizeof(pa_prioq_item*) * q->n_allocated);
    }

    if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items))))
        i = pa_xnew(pa_prioq_item, 1);

    i->value = p;
    i->idx = q->n_items++;

    shuffle_up(q, i);

    return i;
}
예제 #9
0
static void devices_add(struct pa_classify_device **p_devices, const char *type,
                        const char *prop, enum pa_classify_method method, const char *arg,
                        pa_hashmap *ports, uint32_t flags)
{
    struct pa_classify_device *devs;
    struct pa_classify_device_def *d;
    size_t newsize;
    const char *method_name;
    char *ports_string = NULL; /* Just for log output. */
    pa_strbuf *buf; /* For building ports_string. */

    pa_assert(p_devices);
    pa_assert_se((devs = *p_devices));

    newsize = sizeof(*devs) + sizeof(devs->defs[0]) * (devs->ndef + 1);

    devs = *p_devices = pa_xrealloc(devs, newsize);

    d = devs->defs + devs->ndef;

    memset(d+1, 0, sizeof(devs->defs[0]));

    d->type  = pa_xstrdup(type);
    d->prop  = pa_xstrdup(prop);

    buf = pa_strbuf_new();

    if (ports && !pa_hashmap_isempty(ports)) {
        struct pa_classify_port_entry *port;
        void *state;
        pa_bool_t first = TRUE;

        /* Copy the ports hashmap to d->data.ports. */

        d->data.ports = pa_hashmap_new(pa_idxset_string_hash_func,
                                       pa_idxset_string_compare_func);
        PA_HASHMAP_FOREACH(port, ports, state) {
            struct pa_classify_port_entry *port_copy =
                pa_xnew(struct pa_classify_port_entry, 1);

            port_copy->device_name = pa_xstrdup(port->device_name);
            port_copy->port_name = pa_xstrdup(port->port_name);

            pa_hashmap_put(d->data.ports, port_copy->device_name, port_copy);

            if (!first) {
                pa_strbuf_putc(buf, ',');
            }
            first = FALSE;

            pa_strbuf_printf(buf, "%s:%s", port->device_name, port->port_name);
        }
    }

    d->data.flags = flags;

    switch (method) {

    case pa_method_equals:
        method_name = "equals";
        d->method = pa_classify_method_equals;
        d->arg.string = pa_xstrdup(arg);
        break;

    case pa_method_startswith:
        method_name = "startswidth";
        d->method = pa_classify_method_startswith;
        d->arg.string = pa_xstrdup(arg);
        break;

    case pa_method_matches:
        method_name = "matches";
        if (regcomp(&d->arg.rexp, arg, 0) == 0) {
            d->method = pa_classify_method_matches;
            break;
        }
        /* intentional fall trough */

    default:
        pa_log("%s: invalid device definition %s", __FUNCTION__, type);
        memset(d, 0, sizeof(*d));
        pa_strbuf_free(buf);
        return;
    }

    devs->ndef++;

    ports_string = pa_strbuf_tostring_free(buf);

    pa_log_info("device '%s' added (%s|%s|%s|%s|0x%04x)",
                type, d->prop, method_name, arg, ports_string, d->data.flags);

    pa_xfree(ports_string);
}
예제 #10
0
static void cards_add(struct pa_classify_card **p_cards, char *type,
                      enum pa_classify_method method[2], char **arg,
                      char **profiles, uint32_t flags[2])
{
    struct pa_classify_card *cards;
    struct pa_classify_card_def *d;
    struct pa_classify_card_data *data;
    size_t newsize;
    char *method_name[2];
    int i;

    pa_assert(p_cards);
    pa_assert_se((cards = *p_cards));

    newsize = sizeof(*cards) + sizeof(cards->defs[0]) * (cards->ndef + 1);

    cards = *p_cards = pa_xrealloc(cards, newsize);

    d = cards->defs + cards->ndef;

    memset(d+1, 0, sizeof(cards->defs[0]));

    d->type    = pa_xstrdup(type);

    for (i = 0; i < 2 && profiles[i]; i++) {

        data = &d->data[i];

        data->profile = profiles[i] ? pa_xstrdup(profiles[i]) : NULL;
        data->flags   = flags[i];

        switch (method[i]) {

        case pa_method_equals:
            method_name[i] = "equals";
            data->method = pa_classify_method_equals;
            data->arg.string = pa_xstrdup(arg[i]);
            break;

        case pa_method_startswith:
            method_name[i] = "startswidth";
            data->method = pa_classify_method_startswith;
            data->arg.string = pa_xstrdup(arg[i]);
            break;

        case pa_method_matches:
            method_name[i] = "matches";
            if (regcomp(&data->arg.rexp, arg[i], 0) == 0) {
                data->method = pa_classify_method_matches;
                break;
            }
            /* intentional fall trough */

        default:
            pa_log("%s: invalid card definition %s", __FUNCTION__, type);
            memset(d, 0, sizeof(*d));
            return;
        }
    }

    cards->ndef++;

    pa_log_info("card '%s' added (%s|%s|%s|0x%04x)", type, method_name[0], arg[0],
                d->data[0].profile ? d->data[0].profile : "", d->data[0].flags);
    if (d->data[1].profile)
        pa_log_info("  :: added (%s|%s|%s|0x%04x)", method_name[1], arg[1],
                    d->data[1].profile ? d->data[1].profile : "", d->data[1].flags);
}
예제 #11
0
/* This is called whenever new data may is available */
static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {

    pa_assert(s);
    pa_assert(length > 0);

    if (raw) {
        pa_assert(!sndfile);

        if (stdio_event)
            mainloop_api->io_enable(stdio_event, PA_IO_EVENT_OUTPUT);

        while (pa_stream_readable_size(s) > 0) {
            const void *data;

            if (pa_stream_peek(s, &data, &length) < 0) {
                pa_log(_("pa_stream_peek() failed: %s"), pa_strerror(pa_context_errno(context)));
                quit(1);
                return;
            }

            pa_assert(data);
            pa_assert(length > 0);

            if (buffer) {
                buffer = pa_xrealloc(buffer, buffer_length + length);
                memcpy((uint8_t*) buffer + buffer_length, data, length);
                buffer_length += length;
            } else {
                buffer = pa_xmalloc(length);
                memcpy(buffer, data, length);
                buffer_length = length;
                buffer_index = 0;
            }

            pa_stream_drop(s);
        }

    } else {
        pa_assert(sndfile);

        while (pa_stream_readable_size(s) > 0) {
            sf_count_t bytes;
            const void *data;

            if (pa_stream_peek(s, &data, &length) < 0) {
                pa_log(_("pa_stream_peek() failed: %s"), pa_strerror(pa_context_errno(context)));
                quit(1);
                return;
            }

            pa_assert(data);
            pa_assert(length > 0);

            if (writef_function) {
                size_t k = pa_frame_size(&sample_spec);

                if ((bytes = writef_function(sndfile, data, (sf_count_t) (length/k))) > 0)
                    bytes *= (sf_count_t) k;

            } else
                bytes = sf_write_raw(sndfile, data, (sf_count_t) length);

            if (bytes < (sf_count_t) length)
                quit(1);

            pa_stream_drop(s);
        }
    }
}
예제 #12
0
/* This is called whenever new data may is available */
static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {

    pa_assert(s);
    pa_assert(length > 0);

    if (raw) {
        pa_assert(!sndfile);

        if (stdio_event)
            mainloop_api->io_enable(stdio_event, PA_IO_EVENT_OUTPUT);

        while (pa_stream_readable_size(s) > 0) {
            const void *data;

            if (pa_stream_peek(s, &data, &length) < 0) {
                pa_log(_("pa_stream_peek() failed: %s"), pa_strerror(pa_context_errno(context)));
                quit(1);
                return;
            }

            pa_assert(length > 0);

            /* If there is a hole in the stream, we generate silence, except
             * if it's a passthrough stream in which case we skip the hole. */
            if (data || !(flags & PA_STREAM_PASSTHROUGH)) {
                buffer = pa_xrealloc(buffer, buffer_length + length);
                if (data)
                    memcpy((uint8_t *) buffer + buffer_length, data, length);
                else
                    pa_silence_memory((uint8_t *) buffer + buffer_length, length, &sample_spec);

                buffer_length += length;
            }

            pa_stream_drop(s);
        }

    } else {
        pa_assert(sndfile);

        while (pa_stream_readable_size(s) > 0) {
            sf_count_t bytes;
            const void *data;

            if (pa_stream_peek(s, &data, &length) < 0) {
                pa_log(_("pa_stream_peek() failed: %s"), pa_strerror(pa_context_errno(context)));
                quit(1);
                return;
            }

            pa_assert(length > 0);

            if (!data && (flags & PA_STREAM_PASSTHROUGH)) {
                pa_stream_drop(s);
                continue;
            }

            if (!data && length > silence_buffer_length) {
                silence_buffer = pa_xrealloc(silence_buffer, length);
                pa_silence_memory((uint8_t *) silence_buffer + silence_buffer_length, length - silence_buffer_length, &sample_spec);
                silence_buffer_length = length;
            }

            if (writef_function) {
                size_t k = pa_frame_size(&sample_spec);

                if ((bytes = writef_function(sndfile, data ? data : silence_buffer, (sf_count_t) (length/k))) > 0)
                    bytes *= (sf_count_t) k;

            } else
                bytes = sf_write_raw(sndfile, data ? data : silence_buffer, (sf_count_t) length);

            if (bytes < (sf_count_t) length)
                quit(1);

            pa_stream_drop(s);
        }
    }
}