a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
137 lines
3.9 KiB
C#
137 lines
3.9 KiB
C#
//
|
|
// Mono.Unix.Catalog.cs: Wrappers for the libintl library.
|
|
//
|
|
// 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.
|
|
//
|
|
// This file tries to stay close to the low-level API as much as possible
|
|
// using enumerations, structures and in a few cases, using existing .NET
|
|
// data types.
|
|
//
|
|
// Implementation notes:
|
|
//
|
|
// Since the values for the various constants on the API changes
|
|
// from system to system (even Linux on different architectures will
|
|
// have different values), we define our own set of values, and we
|
|
// use a set of C helper routines to map from the constants we define
|
|
// to the values of the native OS.
|
|
//
|
|
// Bitfields are flagged with the [Map] attribute, and a helper program
|
|
// generates a set of map_XXXX routines that we can call to convert
|
|
// from our value definitions to the value definitions expected by the
|
|
// OS.
|
|
//
|
|
// Methods that require tuning are bound as `internal syscal_NAME' methods
|
|
// and then a `NAME' method is exposed.
|
|
//
|
|
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Mono.Unix {
|
|
|
|
public class Catalog {
|
|
private Catalog () {}
|
|
|
|
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
|
|
static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname);
|
|
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
|
|
static extern IntPtr bind_textdomain_codeset (IntPtr domainname,
|
|
IntPtr codeset);
|
|
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
|
|
static extern IntPtr textdomain (IntPtr domainname);
|
|
|
|
public static void Init (String package, String localedir)
|
|
{
|
|
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("intl", CallingConvention=CallingConvention.Cdecl)]
|
|
static extern IntPtr gettext (IntPtr instring);
|
|
|
|
public static String GetString (String s)
|
|
{
|
|
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("intl", CallingConvention=CallingConvention.Cdecl)]
|
|
static extern IntPtr ngettext (IntPtr singular, IntPtr plural, Int32 n);
|
|
|
|
public static String GetPluralString (String s, String p, Int32 n)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|