aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c77
-rw-r--r--Alc/alstring.h32
-rw-r--r--Alc/helpers.c64
-rw-r--r--Alc/vector.h7
4 files changed, 130 insertions, 50 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 5ebe0205..93e773c3 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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)