Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Catalog.cs « Mono.Unix « Mono.Posix « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1ba51307f99ced65ae11b83379356a5a4614b5db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//
// 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")]
		static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname);
		[DllImport("intl")]
		static extern IntPtr bind_textdomain_codeset (IntPtr domainname,
			IntPtr codeset);
		[DllImport("intl")]
		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 OutOfMemoryException ("bindtextdomain");
				if (bind_textdomain_codeset (ipackage, iutf8) == IntPtr.Zero)
					throw new OutOfMemoryException ("bind_textdomain_codeset");
				if (textdomain (ipackage) == IntPtr.Zero)
					throw new OutOfMemoryException ("textdomain");
			}
			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")]
		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")]
		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);
			}
		}
	}
}