Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

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);
}
}
}
}