diff options
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 77 | ||||
-rw-r--r-- | Alc/alstring.h | 32 | ||||
-rw-r--r-- | Alc/helpers.c | 64 | ||||
-rw-r--r-- | Alc/vector.h | 7 |
4 files changed, 130 insertions, 50 deletions
@@ -39,6 +39,8 @@ #include "bs2b.h" #include "alu.h" +#include "alstring.h" + #include "backends/base.h" #include "midi/base.h" @@ -695,11 +697,9 @@ static const ALCchar alcErrOutOfMemory[] = "Out of Memory"; /* Enumerated device names */ static const ALCchar alcDefaultName[] = "OpenAL Soft\0"; -static ALCchar *alcAllDevicesList; -static ALCchar *alcCaptureDeviceList; -/* Sizes only include the first ending null character, not the second */ -static size_t alcAllDevicesListSize; -static size_t alcCaptureDeviceListSize; + +static al_string alcAllDevicesList; +static al_string alcCaptureDeviceList; /* Default is always the first in the list */ static ALCchar *alcDefaultAllDevicesSpecifier; @@ -862,6 +862,9 @@ static void alc_init(void) LogFile = stderr; + AL_STRING_INIT(alcAllDevicesList); + AL_STRING_INIT(alcCaptureDeviceList); + str = getenv("__ALSOFT_HALF_ANGLE_CONES"); if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) ConeScale *= 0.5f; @@ -1154,10 +1157,8 @@ static void alc_cleanup(void) { ALCdevice *dev; - free(alcAllDevicesList); alcAllDevicesList = NULL; - alcAllDevicesListSize = 0; - free(alcCaptureDeviceList); alcCaptureDeviceList = NULL; - alcCaptureDeviceListSize = 0; + AL_STRING_DEINIT(alcAllDevicesList); + AL_STRING_DEINIT(alcCaptureDeviceList); free(alcDefaultAllDevicesSpecifier); alcDefaultAllDevicesSpecifier = NULL; @@ -1223,14 +1224,12 @@ static void alc_deinit(void) /************************************************ * Device enumeration ************************************************/ -static void ProbeList(ALCchar **list, size_t *listsize, enum DevProbe type) +static void ProbeDevices(al_string *list, enum DevProbe type) { DO_INITCONFIG(); LockLists(); - free(*list); - *list = NULL; - *listsize = 0; + al_string_clear(list); if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory)) { @@ -1254,42 +1253,24 @@ static void ProbeList(ALCchar **list, size_t *listsize, enum DevProbe type) } UnlockLists(); } - static void ProbeAllDevicesList(void) -{ ProbeList(&alcAllDevicesList, &alcAllDevicesListSize, ALL_DEVICE_PROBE); } +{ ProbeDevices(&alcAllDevicesList, ALL_DEVICE_PROBE); } static void ProbeCaptureDeviceList(void) -{ ProbeList(&alcCaptureDeviceList, &alcCaptureDeviceListSize, CAPTURE_DEVICE_PROBE); } - +{ ProbeDevices(&alcCaptureDeviceList, CAPTURE_DEVICE_PROBE); } -static void AppendList(const ALCchar *name, ALCchar **List, size_t *ListSize) +static void AppendDevice(const ALCchar *name, al_string *devnames) { size_t len = strlen(name); - void *temp; - - if(len == 0) - return; - - temp = realloc(*List, (*ListSize) + len + 2); - if(!temp) + if(len > 0) { - ERR("Realloc failed to add %s!\n", name); - return; + al_string_append_range(devnames, name, name+len); + al_string_append_char(devnames, '\0'); } - *List = temp; - - memcpy((*List)+(*ListSize), name, len+1); - *ListSize += len+1; - (*List)[*ListSize] = 0; } - -#define DECL_APPEND_LIST_FUNC(type) \ -void Append##type##List(const ALCchar *name) \ -{ AppendList(name, &alc##type##List, &alc##type##ListSize); } - -DECL_APPEND_LIST_FUNC(AllDevices) -DECL_APPEND_LIST_FUNC(CaptureDevice) - -#undef DECL_APPEND_LIST_FUNC +void AppendAllDevicesList(const ALCchar *name) +{ AppendDevice(name, &alcAllDevicesList); } +void AppendCaptureDeviceList(const ALCchar *name) +{ AppendDevice(name, &alcCaptureDeviceList); } /************************************************ @@ -2380,7 +2361,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para else { ProbeAllDevicesList(); - value = alcAllDevicesList; + value = al_string_get_cstr(alcAllDevicesList); } break; @@ -2393,7 +2374,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para else { ProbeCaptureDeviceList(); - value = alcCaptureDeviceList; + value = al_string_get_cstr(alcCaptureDeviceList); } break; @@ -2403,14 +2384,13 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para break; case ALC_DEFAULT_ALL_DEVICES_SPECIFIER: - if(!alcAllDevicesList) + if(al_string_empty(alcAllDevicesList)) ProbeAllDevicesList(); Device = VerifyDevice(Device); free(alcDefaultAllDevicesSpecifier); - alcDefaultAllDevicesSpecifier = strdup(alcAllDevicesList ? - alcAllDevicesList : ""); + alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList)); if(!alcDefaultAllDevicesSpecifier) alcSetError(Device, ALC_OUT_OF_MEMORY); @@ -2419,14 +2399,13 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para break; case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER: - if(!alcCaptureDeviceList) + if(al_string_empty(alcCaptureDeviceList)) ProbeCaptureDeviceList(); Device = VerifyDevice(Device); free(alcCaptureDefaultDeviceSpecifier); - alcCaptureDefaultDeviceSpecifier = strdup(alcCaptureDeviceList ? - alcCaptureDeviceList : ""); + alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcAllDevicesList)); if(!alcCaptureDefaultDeviceSpecifier) alcSetError(Device, ALC_OUT_OF_MEMORY); diff --git a/Alc/alstring.h b/Alc/alstring.h new file mode 100644 index 00000000..b393a8f4 --- /dev/null +++ b/Alc/alstring.h @@ -0,0 +1,32 @@ +#ifndef ALSTRING_H +#define ALSTRING_H + +#include "vector.h" + +typedef char al_string_char_type; +DECL_VECTOR(al_string_char_type) + +typedef vector_al_string_char_type al_string; +typedef const_vector_al_string_char_type const_al_string; + +#define AL_STRING_INIT(_x) do { (_x) = calloc(1, sizeof(*(_x)) + sizeof((_x)->Data[0])); } while(0) +#define AL_STRING_DEINIT(_x) VECTOR_DEINIT(_x) + +inline ALsizei al_string_length(const_al_string str) +{ return VECTOR_SIZE(str); } + +inline ALsizei al_string_empty(const_al_string str) +{ return al_string_length(str) == 0; } + +inline const al_string_char_type *al_string_get_cstr(const_al_string str) +{ return &VECTOR_FRONT(str); } + +void al_string_clear(al_string *str); + +void al_string_copy(al_string *str, const_al_string from); +void al_string_copy_cstr(al_string *str, const al_string_char_type *from); + +void al_string_append_char(al_string *str, const al_string_char_type c); +void al_string_append_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to); + +#endif /* ALSTRING_H */ diff --git a/Alc/helpers.c b/Alc/helpers.c index af17b48c..77bfb353 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -87,6 +87,7 @@ DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, #include "atomic.h" #include "uintmap.h" #include "vector.h" +#include "alstring.h" #include "compat.h" @@ -780,6 +781,69 @@ ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t return AL_TRUE; } +ALboolean vector_resize(void *ptr, size_t base_size, size_t obj_count, size_t obj_size) +{ + vector_ *vecptr = ptr; + if(!vector_reserve(vecptr, (*vecptr)->Capacity, base_size, obj_count, obj_size, AL_TRUE)) + return AL_FALSE; + (*vecptr)->Size = (ALsizei)obj_count; + return AL_TRUE; +} + + +extern inline ALsizei al_string_length(const_al_string str); +extern inline ALsizei al_string_empty(const_al_string str); +extern inline const al_string_char_type *al_string_get_cstr(const_al_string str); + +void al_string_clear(al_string *str) +{ + /* Reserve one more character than the total size of the string. This is to + * ensure we have space to add a null terminator in the string data so it + * can be used as a C-style string. */ + VECTOR_RESERVE(*str, 1); + VECTOR_RESIZE(*str, 0); + *VECTOR_ITER_END(*str) = 0; +} + +void al_string_copy(al_string *str, const_al_string from) +{ + ALsizei len = VECTOR_SIZE(from); + VECTOR_RESERVE(*str, len+1); + VECTOR_RESIZE(*str, len); + memcpy(&VECTOR_FRONT(*str), &VECTOR_FRONT(from), + len*sizeof(al_string_char_type)); + *VECTOR_ITER_END(*str) = 0; +} + +void al_string_copy_cstr(al_string *str, const al_string_char_type *from) +{ + ALsizei len = strlen(from); + VECTOR_RESERVE(*str, len+1); + VECTOR_RESIZE(*str, len); + memcpy(&VECTOR_FRONT(*str), from, len*sizeof(al_string_char_type)); + *VECTOR_ITER_END(*str) = 0; +} + +void al_string_append_char(al_string *str, const al_string_char_type c) +{ + VECTOR_RESERVE(*str, al_string_length(*str)+2); + VECTOR_PUSH_BACK(*str, c); + *VECTOR_ITER_END(*str) = 0; +} + +void al_string_append_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to) +{ + ptrdiff_t len = to - from; + if(len != 0) + { + VECTOR_RESERVE(*str, al_string_length(*str)+len+1); + VECTOR_RESIZE(*str, al_string_length(*str)+len); + memcpy(VECTOR_ITER_END(*str)-len, from, len); + *VECTOR_ITER_END(*str) = 0; + } +} + + void InitUIntMap(UIntMap *map, ALsizei limit) { diff --git a/Alc/vector.h b/Alc/vector.h index 4cb6d2b9..7ff65146 100644 --- a/Alc/vector.h +++ b/Alc/vector.h @@ -15,7 +15,8 @@ typedef struct vector__s { ALsizei Capacity; \ ALsizei Size; \ T Data[]; \ -} *vector_##T; +} *vector_##T; \ +typedef const struct vector_##T##_s *const_vector_##T; #define VECTOR_INIT(_x) do { (_x) = calloc(1, sizeof(*(_x))); } while(0) #define VECTOR_DEINIT(_x) do { free((_x)); (_x) = NULL; } while(0) @@ -24,6 +25,10 @@ typedef struct vector__s { ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t obj_count, size_t obj_size, ALboolean exact); #define VECTOR_RESERVE(_x, _c) (vector_reserve(&(_x), (_x)->Capacity, sizeof(*(_x)), (_c), sizeof((_x)->Data[0]), AL_TRUE)) +/* Helper to change a vector's size. Do not call directly. */ +ALboolean vector_resize(void *ptr, size_t base_size, size_t obj_count, size_t obj_size); +#define VECTOR_RESIZE(_x, _c) (vector_resize(&(_x), sizeof(*(_x)), (_c), sizeof((_x)->Data[0]))) + #define VECTOR_CAPACITY(_x) ((const ALsizei)(_x)->Capacity) #define VECTOR_SIZE(_x) ((const ALsizei)(_x)->Size) |