//
// Mono.Unix.Catalog.cs: Wrappers for the libintl library.
//
-// Author:
+// Authors:
// Edd Dumbill (edd@usefulinc.com)
+// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2004 Edd Dumbill
+// (C) 2005-2006 Jonathan Pryor
//
// This file implements the low-level syscall interface to the POSIX
// subsystem.
namespace Mono.Unix {
public class Catalog {
- [DllImport("libintl")]
+ private Catalog () {}
+
+ [DllImport("intl")]
static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname);
- [DllImport("libintl")]
+ [DllImport("intl")]
static extern IntPtr bind_textdomain_codeset (IntPtr domainname,
IntPtr codeset);
- [DllImport("libintl")]
+ [DllImport("intl")]
static extern IntPtr textdomain (IntPtr domainname);
public static void Init (String package, String localedir)
{
- IntPtr ipackage = Marshal.StringToHGlobalAuto (package);
- IntPtr ilocaledir = Marshal.StringToHGlobalAuto (localedir);
- IntPtr iutf8 = Marshal.StringToHGlobalAuto ("UTF-8");
- bindtextdomain (ipackage, ilocaledir);
- bind_textdomain_codeset (ipackage, iutf8);
- textdomain (ipackage);
- Marshal.FreeHGlobal (ipackage);
- Marshal.FreeHGlobal (ilocaledir);
- Marshal.FreeHGlobal (iutf8);
+ IntPtr ipackage, ilocaledir, iutf8;
+ MarshalStrings (package, out ipackage, localedir, out ilocaledir,
+ "UTF-8", out iutf8);
+ try {
+ if (bindtextdomain (ipackage, ilocaledir) == IntPtr.Zero)
+ throw new UnixIOException (Native.Errno.ENOMEM);
+ if (bind_textdomain_codeset (ipackage, iutf8) == IntPtr.Zero)
+ throw new UnixIOException (Native.Errno.ENOMEM);
+ if (textdomain (ipackage) == IntPtr.Zero)
+ throw new UnixIOException (Native.Errno.ENOMEM);
+ }
+ finally {
+ UnixMarshal.FreeHeap (ipackage);
+ UnixMarshal.FreeHeap (ilocaledir);
+ UnixMarshal.FreeHeap (iutf8);
+ }
+ }
+
+ private static void MarshalStrings (string s1, out IntPtr p1,
+ string s2, out IntPtr p2, string s3, out IntPtr p3)
+ {
+ p1 = p2 = p3 = IntPtr.Zero;
+
+ bool cleanup = true;
+
+ try {
+ p1 = UnixMarshal.StringToHeap (s1);
+ p2 = UnixMarshal.StringToHeap (s2);
+ if (s3 != null)
+ p3 = UnixMarshal.StringToHeap (s3);
+ cleanup = false;
+ }
+ finally {
+ if (cleanup) {
+ UnixMarshal.FreeHeap (p1);
+ UnixMarshal.FreeHeap (p2);
+ UnixMarshal.FreeHeap (p3);
+ }
+ }
}
- [DllImport("libintl")]
+ [DllImport("intl")]
static extern IntPtr gettext (IntPtr instring);
public static String GetString (String s)
{
- IntPtr ints = Marshal.StringToHGlobalAuto (s);
- String t = Marshal.PtrToStringAuto (gettext (ints));
- Marshal.FreeHGlobal (ints);
- return t;
+ IntPtr ints = UnixMarshal.StringToHeap (s);
+ try {
+ // gettext(3) returns the input pointer if no translation is found
+ IntPtr r = gettext (ints);
+ if (r != ints)
+ return UnixMarshal.PtrToStringUnix (r);
+ return s;
+ }
+ finally {
+ UnixMarshal.FreeHeap (ints);
+ }
}
- [DllImport("libintl")]
+ [DllImport("intl")]
static extern IntPtr ngettext (IntPtr singular, IntPtr plural, Int32 n);
public static String GetPluralString (String s, String p, Int32 n)
{
- IntPtr ints = Marshal.StringToHGlobalAuto (s);
- IntPtr intp = Marshal.StringToHGlobalAuto (p);
- String t = Marshal.PtrToStringAnsi (ngettext (ints, intp, n));
- Marshal.FreeHGlobal (ints);
- Marshal.FreeHGlobal (intp);
- return t;
+ IntPtr ints, intp, _ignore;
+ MarshalStrings (s, out ints, p, out intp, null, out _ignore);
+
+ try {
+ // ngettext(3) returns an input pointer if no translation is found
+ IntPtr r = ngettext (ints, intp, n);
+ if (r == ints)
+ return s;
+ if (r == intp)
+ return p;
+ return UnixMarshal.PtrToStringUnix (r);
+ }
+ finally {
+ UnixMarshal.FreeHeap (ints);
+ UnixMarshal.FreeHeap (intp);
+ }
}
-
}
}
+