diff --git a/README.md b/README.md index d3a9bc8..70f73f0 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ libsoundio is programmed in a tiny subset of C++11: * No STL. * No `new` or `delete`. * No `class`. All fields in structs are `public`. + * No constructors or destructors. * No exceptions or run-time type information. * No references. * No linking against libstdc++. diff --git a/src/alsa.cpp b/src/alsa.cpp index a9a4f13..4ce0fea 100644 --- a/src/alsa.cpp +++ b/src/alsa.cpp @@ -465,7 +465,7 @@ static int refresh_devices(SoundIoPrivate *si) { SoundIo *soundio = &si->pub; SoundIoAlsa *sia = &si->backend_data.alsa; - SoundIoDevicesInfo *devices_info = create(); + SoundIoDevicesInfo *devices_info = allocate(1); if (!devices_info) return SoundIoErrorNoMem; devices_info->default_output_index = -1; @@ -473,7 +473,7 @@ static int refresh_devices(SoundIoPrivate *si) { void **hints; if (snd_device_name_hint(-1, "pcm", &hints) < 0) { - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } @@ -531,11 +531,11 @@ static int refresh_devices(SoundIoPrivate *si) { } - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { free(name); free(descr); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); snd_device_name_free_hint(hints); return SoundIoErrorNoMem; } @@ -551,7 +551,7 @@ static int refresh_devices(SoundIoPrivate *si) { soundio_device_unref(device); free(name); free(descr); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); snd_device_name_free_hint(hints); return SoundIoErrorNoMem; } @@ -577,7 +577,7 @@ static int refresh_devices(SoundIoPrivate *si) { soundio_device_unref(device); free(name); free(descr); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); snd_device_name_free_hint(hints); return SoundIoErrorNoMem; } @@ -609,14 +609,14 @@ static int refresh_devices(SoundIoPrivate *si) { if (err == -ENOENT) { break; } else { - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorOpeningDevice; } } if ((err = snd_ctl_card_info(handle, card_info)) < 0) { snd_ctl_close(handle); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorSystemResources; } const char *card_name = snd_ctl_card_info_get_name(card_info); @@ -625,7 +625,7 @@ static int refresh_devices(SoundIoPrivate *si) { for (;;) { if (snd_ctl_pcm_next_device(handle, &device_index) < 0) { snd_ctl_close(handle); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorSystemResources; } if (device_index < 0) @@ -643,17 +643,17 @@ static int refresh_devices(SoundIoPrivate *si) { continue; } else { snd_ctl_close(handle); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorSystemResources; } } const char *device_name = snd_pcm_info_get_name(pcm_info); - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { snd_ctl_close(handle); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } SoundIoDevice *device = &dev->pub; @@ -666,7 +666,7 @@ static int refresh_devices(SoundIoPrivate *si) { if (!device->id || !device->name) { soundio_device_unref(device); snd_ctl_close(handle); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } @@ -685,14 +685,14 @@ static int refresh_devices(SoundIoPrivate *si) { if (device_list->append(device)) { soundio_device_unref(device); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } } } snd_ctl_close(handle); if (snd_card_next(&card_index) < 0) { - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorSystemResources; } } @@ -888,11 +888,9 @@ static void outstream_destroy_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate * if (osa->handle) snd_pcm_close(osa->handle); - deallocate(osa->poll_fds, osa->poll_fd_count); - - deallocate(osa->chmap, osa->chmap_size); - - deallocate(osa->sample_buffer, osa->sample_buffer_size); + free(osa->poll_fds); + free(osa->chmap); + free(osa->sample_buffer); } static int os_xrun_recovery(SoundIoOutStreamPrivate *os, int err) { @@ -1394,9 +1392,9 @@ static void instream_destroy_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is if (isa->handle) snd_pcm_close(isa->handle); - deallocate(isa->poll_fds, isa->poll_fd_count); - deallocate(isa->chmap, isa->chmap_size); - deallocate(isa->sample_buffer, isa->sample_buffer_size); + free(isa->poll_fds); + free(isa->chmap); + free(isa->sample_buffer); } static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { diff --git a/src/coreaudio.cpp b/src/coreaudio.cpp index 6829256..17d052d 100644 --- a/src/coreaudio.cpp +++ b/src/coreaudio.cpp @@ -173,7 +173,7 @@ static int from_cf_string(CFStringRef string_ref, char **out_str, int *out_str_l return SoundIoErrorNoMem; if (!CFStringGetCString(string_ref, buf, max_size, kCFStringEncodingUTF8)) { - deallocate(buf, max_size); + free(buf); return SoundIoErrorEncodingString; } @@ -408,8 +408,8 @@ struct RefreshDevices { static void deinit_refresh_devices(RefreshDevices *rd) { if (!rd->ok) unsubscribe_device_listeners(rd->si); - destroy(rd->devices_info); - deallocate((char*)rd->devices, rd->devices_size); + soundio_destroy_devices_info(rd->devices_info); + free(rd->devices); if (rd->string_ref) CFRelease(rd->string_ref); free(rd->device_name); @@ -433,7 +433,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { RefreshDevices rd = {0}; rd.si = si; - if (!(rd.devices_info = create())) { + if (!(rd.devices_info = allocate(1))) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } @@ -586,7 +586,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { if (channel_count <= 0) continue; - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; @@ -602,9 +602,9 @@ static int refresh_devices(struct SoundIoPrivate *si) { rd.device->id = soundio_str_dupe(rd.device_uid, rd.device_uid_len); rd.device->name = soundio_str_dupe(rd.device_name, rd.device_name_len); rd.device->layout_count = 1; - rd.device->layouts = create(); + rd.device->layouts = allocate(1); rd.device->format_count = 1; - rd.device->formats = create(); + rd.device->formats = allocate(1); if (!rd.device->id || !rd.device->name || !rd.device->layouts || !rd.device->formats) { deinit_refresh_devices(&rd); diff --git a/src/dummy.cpp b/src/dummy.cpp index 344482e..5158236 100644 --- a/src/dummy.cpp +++ b/src/dummy.cpp @@ -386,7 +386,7 @@ int soundio_dummy_init(SoundIoPrivate *si) { } assert(!si->safe_devices_info); - si->safe_devices_info = create(); + si->safe_devices_info = allocate(1); if (!si->safe_devices_info) { destroy_dummy(si); return SoundIoErrorNoMem; @@ -397,7 +397,7 @@ int soundio_dummy_init(SoundIoPrivate *si) { // create output device { - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { destroy_dummy(si); return SoundIoErrorNoMem; @@ -446,7 +446,7 @@ int soundio_dummy_init(SoundIoPrivate *si) { // create input device { - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { destroy_dummy(si); return SoundIoErrorNoMem; diff --git a/src/jack.cpp b/src/jack.cpp index b902c25..c1ffd91 100644 --- a/src/jack.cpp +++ b/src/jack.cpp @@ -74,9 +74,9 @@ static void destruct_device(SoundIoDevicePrivate *dp) { SoundIoDeviceJack *dj = &dp->backend_data.jack; for (int i = 0; i < dj->port_count; i += 1) { SoundIoDeviceJackPort *djp = &dj->ports[i]; - destroy(djp->full_name); + free(djp->full_name); } - deallocate(dj->ports, dj->port_count); + free(dj->ports); } static int refresh_devices_bare(SoundIoPrivate *si) { @@ -87,7 +87,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { return SoundIoErrorBackendDisconnected; - SoundIoDevicesInfo *devices_info = create(); + SoundIoDevicesInfo *devices_info = allocate(1); if (!devices_info) return SoundIoErrorNoMem; @@ -95,7 +95,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { devices_info->default_input_index = -1; const char **port_names = jack_get_ports(sij->client, nullptr, nullptr, 0); if (!port_names) { - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } @@ -109,7 +109,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { // This refresh devices scan is already outdated. Just give up and // let refresh_devices be called again. jack_free(port_names); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorInterrupted; } @@ -138,7 +138,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { client_name, client_name_len); if (!client) { jack_free(port_names); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } if (client->port_count >= SOUNDIO_MAX_CHANNELS) { @@ -164,10 +164,10 @@ static int refresh_devices_bare(SoundIoPrivate *si) { if (client->port_count <= 0) continue; - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { jack_free(port_names); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } SoundIoDevice *device = &dev->pub; @@ -188,9 +188,9 @@ static int refresh_devices_bare(SoundIoPrivate *si) { device->id = soundio_str_dupe(client->name, client->name_len); device->name = allocate(description_len); device->layout_count = 1; - device->layouts = create(); + device->layouts = allocate(1); device->format_count = 1; - device->formats = create(); + device->formats = allocate(1); device->current_format = SoundIoFormatFloat32NE; device->sample_rate_min = sij->sample_rate; device->sample_rate_max = sij->sample_rate; @@ -207,7 +207,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { if (!device->id || !device->name || !device->layouts || !device->formats || !dj->ports) { jack_free(port_names); soundio_device_unref(device); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } @@ -221,7 +221,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { if (!djp->full_name) { jack_free(port_names); soundio_device_unref(device); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } } @@ -271,7 +271,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { if (device_list->append(device)) { soundio_device_unref(device); - destroy(devices_info); + soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } diff --git a/src/list.hpp b/src/list.hpp index 43dae4a..4f3dccd 100644 --- a/src/list.hpp +++ b/src/list.hpp @@ -16,7 +16,7 @@ template struct SoundIoList { void deinit() { - deallocate(items, capacity); + free(items); } int __attribute__((warn_unused_result)) append(T item) { int err = ensure_capacity(length + 1); @@ -74,7 +74,7 @@ struct SoundIoList { while (better_capacity < new_capacity) better_capacity = better_capacity * 2; if (better_capacity != capacity) { - T *new_items = reallocate_nonzero(items, capacity, better_capacity); + T *new_items = reallocate_nonzero(items, better_capacity); if (!new_items) return SoundIoErrorNoMem; items = new_items; diff --git a/src/os.cpp b/src/os.cpp index b780daf..debca48 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -191,7 +191,7 @@ int soundio_os_thread_create( { *out_thread = NULL; - struct SoundIoOsThread *thread = create(); + struct SoundIoOsThread *thread = allocate(1); if (!thread) { soundio_os_thread_destroy(thread); return SoundIoErrorNoMem; @@ -279,13 +279,13 @@ void soundio_os_thread_destroy(struct SoundIoOsThread *thread) { } #endif - destroy(thread); + free(thread); } struct SoundIoOsMutex *soundio_os_mutex_create(void) { int err; - struct SoundIoOsMutex *mutex = create(); + struct SoundIoOsMutex *mutex = allocate(1); if (!mutex) { soundio_os_mutex_destroy(mutex); return NULL; @@ -316,7 +316,7 @@ void soundio_os_mutex_destroy(struct SoundIoOsMutex *mutex) { } #endif - destroy(mutex); + free(mutex); } void soundio_os_mutex_lock(struct SoundIoOsMutex *mutex) { @@ -336,7 +336,7 @@ void soundio_os_mutex_unlock(struct SoundIoOsMutex *mutex) { } struct SoundIoOsCond * soundio_os_cond_create(void) { - struct SoundIoOsCond *cond = create(); + struct SoundIoOsCond *cond = allocate(1); if (!cond) { soundio_os_cond_destroy(cond); @@ -399,7 +399,7 @@ void soundio_os_cond_destroy(struct SoundIoOsCond *cond) { } #endif - destroy(cond); + free(cond); } void soundio_os_cond_signal(struct SoundIoOsCond *cond, diff --git a/src/pulseaudio.cpp b/src/pulseaudio.cpp index 3cb43aa..75f8a27 100644 --- a/src/pulseaudio.cpp +++ b/src/pulseaudio.cpp @@ -272,7 +272,7 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in sipa->have_sink_list = true; finish_device_query(si); } else if (!sipa->device_query_err) { - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { sipa->device_query_err = SoundIoErrorNoMem; pa_threaded_mainloop_signal(sipa->main_loop, 0); @@ -342,7 +342,7 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info sipa->have_source_list = true; finish_device_query(si); } else if (!sipa->device_query_err) { - SoundIoDevicePrivate *dev = create(); + SoundIoDevicePrivate *dev = allocate(1); if (!dev) { sipa->device_query_err = SoundIoErrorNoMem; pa_threaded_mainloop_signal(sipa->main_loop, 0); @@ -433,7 +433,7 @@ static int scan_devices(SoundIoPrivate *si) { sipa->have_source_list = false; soundio_destroy_devices_info(sipa->current_devices_info); - sipa->current_devices_info = create(); + sipa->current_devices_info = allocate(1); if (!sipa->current_devices_info) return SoundIoErrorNoMem; diff --git a/src/ring_buffer.cpp b/src/ring_buffer.cpp index 64c10f8..4d5859a 100644 --- a/src/ring_buffer.cpp +++ b/src/ring_buffer.cpp @@ -12,7 +12,7 @@ #include struct SoundIoRingBuffer *soundio_ring_buffer_create(struct SoundIo *soundio, int requested_capacity) { - SoundIoRingBuffer *rb = create(); + SoundIoRingBuffer *rb = allocate(1); assert(requested_capacity > 0); @@ -35,7 +35,7 @@ void soundio_ring_buffer_destroy(struct SoundIoRingBuffer *rb) { soundio_ring_buffer_deinit(rb); - destroy(rb); + free(rb); } int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *rb) { diff --git a/src/soundio.cpp b/src/soundio.cpp index 1e28eb9..4e7009a 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -149,7 +149,7 @@ void soundio_destroy(struct SoundIo *soundio) { soundio_disconnect(soundio); - destroy(si); + free(si); } static void do_nothing_cb(struct SoundIo *) { } @@ -163,7 +163,7 @@ struct SoundIo *soundio_create(void) { int err; if ((err = soundio_os_init())) return nullptr; - struct SoundIoPrivate *si = create(); + struct SoundIoPrivate *si = allocate(1); if (!si) return nullptr; SoundIo *soundio = &si->pub; @@ -325,10 +325,10 @@ void soundio_device_unref(struct SoundIoDevice *device) { free(device->id); free(device->name); - deallocate(device->formats, device->format_count); - deallocate(device->layouts, device->layout_count); + free(device->formats); + free(device->layouts); - destroy(dev); + free(dev); } } @@ -369,7 +369,7 @@ static void default_outstream_error_callback(struct SoundIoOutStream *os, int er static void default_underflow_callback(struct SoundIoOutStream *outstream) { } struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device) { - SoundIoOutStreamPrivate *os = create(); + SoundIoOutStreamPrivate *os = allocate(1); if (!os) return nullptr; SoundIoOutStream *outstream = &os->pub; @@ -432,7 +432,7 @@ void soundio_outstream_destroy(SoundIoOutStream *outstream) { si->outstream_destroy(si, os); soundio_device_unref(outstream->device); - destroy(os); + free(os); } int soundio_outstream_start(struct SoundIoOutStream *outstream) { @@ -454,7 +454,7 @@ static void default_instream_error_callback(struct SoundIoInStream *is, int err) } struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device) { - SoundIoInStreamPrivate *is = create(); + SoundIoInStreamPrivate *is = allocate(1); if (!is) return nullptr; SoundIoInStream *instream = &is->pub; @@ -522,7 +522,7 @@ void soundio_instream_destroy(struct SoundIoInStream *instream) { si->instream_destroy(si, is); soundio_device_unref(instream->device); - destroy(is); + free(is); } int soundio_instream_pause(struct SoundIoInStream *instream, bool pause) { @@ -560,7 +560,7 @@ void soundio_destroy_devices_info(SoundIoDevicesInfo *devices_info) { devices_info->input_devices.deinit(); devices_info->output_devices.deinit(); - destroy(devices_info); + free(devices_info); } bool soundio_have_backend(SoundIoBackend backend) { diff --git a/src/util.hpp b/src/util.hpp index e801af7..06a8b6e 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -11,73 +11,20 @@ #include #include #include -#include template __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { - T *ptr = reinterpret_cast(malloc(count * sizeof(T))); - if (ptr) { - for (size_t i = 0; i < count; i++) - new (&ptr[i]) T; - } - return ptr; + return reinterpret_cast(malloc(count * sizeof(T))); } template __attribute__((malloc)) static inline T *allocate(size_t count) { - T *ptr = reinterpret_cast(calloc(count, sizeof(T))); - if (ptr) { - for (size_t i = 0; i < count; i++) - new (&ptr[i]) T; - } - return ptr; + return reinterpret_cast(calloc(count, sizeof(T))); } template -static inline T * reallocate_nonzero(T * old, size_t old_count, size_t new_count) { - assert(old_count <= new_count); - T * new_ptr = reinterpret_cast(realloc(old, new_count * sizeof(T))); - if (new_ptr) { - for (size_t i = old_count; i < new_count; i += 1) - new (&new_ptr[i]) T; - } - return new_ptr; -} - -template -static inline void deallocate(T * ptr, size_t count) { - if (ptr) { - for (size_t i = 0; i < count; i += 1) - ptr[i].~T(); - } - // keep this outside the if so that the if statement can be optimized out - // completely if T has no destructor - free(ptr); -} - -template -__attribute__((malloc)) static inline T * create_nonzero(Args... args) { - T * ptr = reinterpret_cast(malloc(sizeof(T))); - if (ptr) - new (ptr) T(args...); - return ptr; -} - -template -__attribute__((malloc)) static inline T * create(Args... args) { - T * ptr = reinterpret_cast(calloc(1, sizeof(T))); - if (ptr) - new (ptr) T(args...); - return ptr; -} - -template -static inline void destroy(T * ptr) { - if (ptr) - ptr[0].~T(); - // keep this outside the if so that the if statement can be optimized out - // completely if T has no destructor - free(ptr); +static inline T *reallocate_nonzero(T * old, size_t new_count) { + return reinterpret_cast(realloc(old, new_count * sizeof(T))); } void soundio_panic(const char *format, ...)