using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
/// <returns>A string containing the name of the Device.</returns>
public static string GetString(IntPtr device, AlcGetString param)
{
- return Marshal.PtrToStringAnsi(GetStringPrivate(device, param));
+ IntPtr pstr = GetStringPrivate(device, param);
+ string str = String.Empty;
+ if (pstr != IntPtr.Zero)
+ {
+ str = Marshal.PtrToStringAnsi(pstr);
+ }
+ return str;
}
/// <summary>This function returns a List of strings related to the context.</summary>
public static IList<string> GetString(IntPtr device, AlcGetStringList param)
{
List<string> result = new List<string>();
- IntPtr t = GetStringPrivate(IntPtr.Zero, (AlcGetString)param);
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- byte b;
- int offset = 0;
- do
+
+ // We cannot use Marshal.PtrToStringAnsi(),
+ // because alcGetString is defined to return either a nul-terminated string,
+ // or an array of nul-terminated strings terminated by an extra nul.
+ // Marshal.PtrToStringAnsi() will fail in the latter case (it will only
+ // return the very first string in the array.)
+ // We'll have to marshal this ourselves.
+ IntPtr t = GetStringPrivate(device, (AlcGetString)param);
+ if (t != IntPtr.Zero)
{
- b = Marshal.ReadByte(t, offset++);
- if (b != 0)
- sb.Append((char)b);
- if (b == 0)
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ byte b;
+ int offset = 0;
+ do
{
- result.Add(sb.ToString());
- if (Marshal.ReadByte(t, offset) == 0) // offset already properly increased through ++
- break; // 2x null
+ b = Marshal.ReadByte(t, offset++);
+ if (b != 0)
+ {
+ sb.Append((char)b);
+ }
else
- sb.Remove(0, sb.Length); // 1x null
+ {
+ // One string from the array is complete
+ result.Add(sb.ToString());
+
+ // Check whether the array has finished
+ // Note: offset already been increased through offset++ above
+ if (Marshal.ReadByte(t, offset) == 0)
+ {
+ // 2x consecutive nuls, we've read the whole array
+ break;
+ }
+ else
+ {
+ // Another string is starting, clear the StringBuilder
+ sb.Remove(0, sb.Length);
+ }
+ }
}
- } while (true);
+ while (true);
+ }
+ else
+ {
+ Debug.Print("[Audio] Alc.GetString({0}, {1}) returned null.",
+ device, param);
+ }
- return (IList<string>)result;
+ return result;
}
[DllImport(Alc.Lib, EntryPoint = "alcGetIntegerv", ExactSpelling = true, CallingConvention = Alc.Style, CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity()]