* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / Catalog.cs
1 //
2 // Mono.Unix.Catalog.cs: Wrappers for the libintl library.
3 //
4 // Authors:
5 //   Edd Dumbill (edd@usefulinc.com)
6 //   Jonathan Pryor (jonpryor@vt.edu)
7 //
8 // (C) 2004 Edd Dumbill
9 // (C) 2005-2006 Jonathan Pryor
10 //
11 // This file implements the low-level syscall interface to the POSIX
12 // subsystem.
13 //
14 // This file tries to stay close to the low-level API as much as possible
15 // using enumerations, structures and in a few cases, using existing .NET
16 // data types.
17 //
18 // Implementation notes:
19 //
20 //    Since the values for the various constants on the API changes
21 //    from system to system (even Linux on different architectures will
22 //    have different values), we define our own set of values, and we
23 //    use a set of C helper routines to map from the constants we define
24 //    to the values of the native OS.
25 //
26 //    Bitfields are flagged with the [Map] attribute, and a helper program
27 //    generates a set of map_XXXX routines that we can call to convert
28 //    from our value definitions to the value definitions expected by the
29 //    OS.
30 //
31 //    Methods that require tuning are bound as `internal syscal_NAME' methods
32 //    and then a `NAME' method is exposed.
33 //
34
35 using System;
36 using System.Runtime.InteropServices;
37
38 namespace Mono.Unix {
39
40         public class Catalog {
41                 private Catalog () {}
42
43                 [DllImport("intl")]
44                 static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname);
45                 [DllImport("intl")]
46                 static extern IntPtr bind_textdomain_codeset (IntPtr domainname,
47                         IntPtr codeset);
48                 [DllImport("intl")]
49                 static extern IntPtr textdomain (IntPtr domainname);
50                 
51                 public static void Init (String package, String localedir)
52                 {
53                         IntPtr ipackage, ilocaledir, iutf8;
54                         MarshalStrings (package, out ipackage, localedir, out ilocaledir, 
55                                         "UTF-8", out iutf8);
56                         try {
57                                 if (bindtextdomain (ipackage, ilocaledir) == IntPtr.Zero)
58                                         throw new UnixIOException (Native.Errno.ENOMEM);
59                                 if (bind_textdomain_codeset (ipackage, iutf8) == IntPtr.Zero)
60                                         throw new UnixIOException (Native.Errno.ENOMEM);
61                                 if (textdomain (ipackage) == IntPtr.Zero)
62                                         throw new UnixIOException (Native.Errno.ENOMEM);
63                         }
64                         finally {
65                                 UnixMarshal.FreeHeap (ipackage);
66                                 UnixMarshal.FreeHeap (ilocaledir);
67                                 UnixMarshal.FreeHeap (iutf8);
68                         }
69                 }
70
71                 private static void MarshalStrings (string s1, out IntPtr p1, 
72                                 string s2, out IntPtr p2, string s3, out IntPtr p3)
73                 {
74                         p1 = p2 = p3 = IntPtr.Zero;
75
76                         bool cleanup = true;
77
78                         try {
79                                 p1 = UnixMarshal.StringToHeap (s1);
80                                 p2 = UnixMarshal.StringToHeap (s2);
81                                 if (s3 != null)
82                                         p3 = UnixMarshal.StringToHeap (s3);
83                                 cleanup = false;
84                         }
85                         finally {
86                                 if (cleanup) {
87                                         UnixMarshal.FreeHeap (p1);
88                                         UnixMarshal.FreeHeap (p2);
89                                         UnixMarshal.FreeHeap (p3);
90                                 }
91                         }
92                 }
93         
94                 [DllImport("intl")]
95                 static extern IntPtr gettext (IntPtr instring);
96                 
97                 public static String GetString (String s)
98                 {
99                         IntPtr ints = UnixMarshal.StringToHeap (s);
100                         try {
101                                 // gettext(3) returns the input pointer if no translation is found
102                                 IntPtr r = gettext (ints);
103                                 if (r != ints)
104                                         return UnixMarshal.PtrToStringUnix (r);
105                                 return s;
106                         }
107                         finally {
108                                 UnixMarshal.FreeHeap (ints);
109                         }
110                 }
111         
112                 [DllImport("intl")]
113                 static extern IntPtr ngettext (IntPtr singular, IntPtr plural, Int32 n);
114                 
115                 public static String GetPluralString (String s, String p, Int32 n)
116                 {
117                         IntPtr ints, intp, _ignore;
118                         MarshalStrings (s, out ints, p, out intp, null, out _ignore);
119
120                         try {
121                                 // ngettext(3) returns an input pointer if no translation is found
122                                 IntPtr r = ngettext (ints, intp, n);
123                                 if (r == ints)
124                                         return s;
125                                 if (r == intp)
126                                         return p;
127                                 return UnixMarshal.PtrToStringUnix (r); 
128                         }
129                         finally {
130                                 UnixMarshal.FreeHeap (ints);
131                                 UnixMarshal.FreeHeap (intp);
132                         }
133                 }
134         }
135 }
136