Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region --- License ---
2
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
3
 * See license.txt for license info
4
 */
5
#endregion
6
 
7
using System;
8
using System.Collections.Generic;
9
using System.IO;
10
using System.Xml.XPath;
11
 
12
namespace Bind.Structures
13
{
14
    public class Type : IComparable<Type>
15
    {
16
        internal static Dictionary<string, string> GLTypes;
17
        internal static Dictionary<string, string> CSTypes;
18
 
19
        private static bool typesLoaded;
20
 
21
        string current_qualifier = "", previous_qualifier = "";
22
 
23
        #region internal static void Initialize(string glTypes, string csTypes)
24
 
25
        internal static void Initialize(string glTypes, string csTypes)
26
        {
27
            if (!typesLoaded)
28
            {
29
                if (GLTypes == null)
30
                {
31
                    using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, glTypes))
32
                    {
33
                        GLTypes = MainClass.Generator.ReadTypeMap(sr);
34
                    }
35
                }
36
                if (CSTypes == null)
37
                {
38
                    using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, csTypes))
39
                    {
40
                        CSTypes = MainClass.Generator.ReadCSTypeMap(sr);
41
                    }
42
                }
43
                typesLoaded = true;
44
            }
45
        }
46
 
47
        #endregion
48
 
49
        #region --- Constructors ---
50
 
51
        public Type()
52
        {
53
        }
54
 
55
        public Type(Type t)
56
        {
57
            if (t != null)
58
            {
59
                QualifiedType = t.QualifiedType; // Covers current type and qualifier
60
                PreviousType = t.PreviousType;
61
                PreviousQualifier = t.PreviousQualifier;
62
                WrapperType = t.WrapperType;
63
                Array = t.Array;
64
                Pointer = t.Pointer;
65
                Reference = t.Reference;
66
                ElementCount = t.ElementCount;
67
            }
68
        }
69
 
70
        #endregion
71
 
72
        public string CurrentQualifier
73
        {
74
            get { return current_qualifier; }
75
            set { PreviousQualifier = CurrentQualifier; current_qualifier = value; }
76
        }
77
 
78
        public string PreviousQualifier
79
        {
80
            get { return previous_qualifier; }
81
            private set { previous_qualifier = value; }
82
        }
83
 
84
        public string QualifiedType {
85
            get
86
            {
87
                if (!String.IsNullOrEmpty(CurrentQualifier))
88
                    return String.Format("{0}.{1}", CurrentQualifier, CurrentType);
89
                else
90
                    return CurrentType;
91
            }
92
            set
93
            {
94
                if (String.IsNullOrEmpty(value))
95
                    throw new ArgumentException();
96
 
97
                int qualifier_end = value.LastIndexOf('.');
98
                if (qualifier_end > -1)
99
                {
100
                    CurrentQualifier = value.Substring(0, qualifier_end);
101
                    CurrentType = value.Substring(qualifier_end + 1);
102
                }
103
                else
104
                {
105
                    CurrentType = value;
106
                }
107
            }
108
        }
109
 
110
        #region public string CurrentType
111
 
112
        string type;
113
        /// <summary>
114
        /// Gets the type of the parameter.
115
        /// </summary>
116
        public virtual string CurrentType
117
        {
118
            //get { return _type; }
119
            get
120
            {
121
                if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && Pointer != 0 && type.Contains("void"))
122
                    return "IntPtr";
123
 
124
                return type;
125
            }
126
            set
127
            {
128
                if (String.IsNullOrEmpty(value))
129
                    throw new ArgumentException();
130
 
131
                if (!String.IsNullOrEmpty(type))
132
                    PreviousType = type;
133
                if (!String.IsNullOrEmpty(value))
134
                    type = value.Trim();
135
 
136
                while (type.EndsWith("*"))
137
                {
138
                    type = type.Substring(0, type.Length - 1);
139
                    Pointer++;
140
                }
141
            }
142
        }
143
 
144
        #endregion
145
 
146
        #region public string PreviousType
147
 
148
        private string _previous_type;
149
 
150
        public string PreviousType
151
        {
152
            get { return _previous_type; }
153
            private set { _previous_type = value; }
154
        }
155
 
156
        #endregion
157
 
158
        #region public bool Reference
159
 
160
        bool reference;
161
 
162
        public bool Reference
163
        {
164
            get { return reference; }
165
            set { reference = value; }
166
        }
167
 
168
        #endregion
169
 
170
        #region public int Array
171
 
172
        int array;
173
 
174
        public int Array
175
        {
176
            get { return array; }
177
            set { array = value > 0 ? value : 0; }
178
        }
179
 
180
        #endregion
181
 
182
        #region public int ElementCount
183
 
184
        int element_count;
185
 
186
        // If the type is an array and ElementCount > 0, then ElemenCount defines the expected array length.
187
        public int ElementCount
188
        {
189
            get { return element_count; }
190
            set { element_count = value > 0 ? value : 0; }
191
        }
192
 
193
        #endregion
194
 
195
        #region public int Pointer
196
 
197
        int pointer;
198
 
199
        public int Pointer
200
        {
201
            get { return pointer; }
202
            set { pointer = value > 0 ? value : 0; }
203
        }
204
 
205
        #endregion
206
 
207
        // Returns true if parameter is an enum.
208
        public bool IsEnum
209
        {
210
            get
211
            {
212
                return Enum.GLEnums.ContainsKey(CurrentType) ||
213
                    Enum.AuxEnums.ContainsKey(CurrentType);
214
            }
215
        }
216
 
217
        #region IndirectionLevel
218
 
219
        // Gets the the level of indirection for this type. For example,
220
        // type 'foo' has indirection level = 0, while 'ref foo*[]' has
221
        // an indirection level of 3.
222
        public int IndirectionLevel
223
        {
224
            get { return Pointer + Array + (Reference ? 1 : 0); }
225
        }
226
 
227
        #endregion
228
 
229
        #region public bool CLSCompliant
230
 
231
        public bool CLSCompliant
232
        {
233
            get
234
            {
235
                bool compliant = true;
236
 
237
                switch (CurrentType.ToLower())
238
                {
239
                    case "sbyte":
240
                    case "ushort":
241
                    case "uint":
242
                    case "ulong":
243
                    case "uintptr":
244
                    case "uint16":
245
                    case "uint32":
246
                    case "uint64":
247
                         compliant = false;
248
                        break;
249
 
250
                    default:
251
                        compliant = Pointer == 0;
252
                       break;
253
                }
254
 
255
                return compliant;
256
 
257
                /*
258
                if (Pointer != 0)
259
                {
260
                    compliant &= CurrentType.Contains("IntPtr");    // IntPtr's are CLSCompliant.
261
                    // If the NoPublicUnsageFunctions is set, the pointer will be CLSCompliant.
262
                    compliant |= (Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None;
263
                }
264
                return compliant;
265
                */
266
                //return compliant && (!Pointer || CurrentType.Contains("IntPtr"));
267
                //return compliant && !(Pointer && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) == Settings.Legacy.None));
268
 
269
                /*
270
                 * return !(
271
                    (Pointer && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) == Settings.Legacy.None ) ||
272
                    CurrentType.Contains("UInt") ||
273
                    CurrentType.Contains("SByte")));
274
                */
275
 
276
                /*(Type.Contains("GLu") && !Type.Contains("GLubyte")) ||
277
                Type == "GLbitfield" ||
278
                Type.Contains("GLhandle") ||
279
                Type.Contains("GLhalf") ||
280
                Type == "GLbyte");*/
281
            }
282
        }
283
 
284
        #endregion
285
 
286
        #region public bool Unsigned
287
 
288
        public bool Unsigned
289
        {
290
            get
291
            {
292
                return (CurrentType.Contains("UInt") || CurrentType.Contains("Byte"));
293
            }
294
        }
295
 
296
        #endregion
297
 
298
        #region public WrapperTypes WrapperType
299
 
300
        private WrapperTypes _wrapper_type = WrapperTypes.None;
301
 
302
        public WrapperTypes WrapperType
303
        {
304
            get { return _wrapper_type; }
305
            set { _wrapper_type = value; }
306
        }
307
 
308
        #endregion
309
 
310
        #region public string GetCLSCompliantType()
311
 
312
        public string GetCLSCompliantType()
313
        {
314
            if (!CLSCompliant)
315
            {
316
                if (Pointer != 0 && Settings.Compatibility == Settings.Legacy.Tao)
317
                    return "IntPtr";
318
 
319
                switch (CurrentType)
320
                {
321
                    case "UInt16":
322
                    case "ushort":
323
                        return "Int16";
324
                    case "UInt32":
325
                    case "uint":
326
                        return "Int32";
327
                    case "UInt64":
328
                    case "ulong":
329
                        return "Int64";
330
                    case "SByte":
331
                    case "sbyte":
332
                        return "Byte";
333
                    case "UIntPtr":
334
                        return "IntPtr";
335
                }
336
            }
337
 
338
            return CurrentType;
339
        }
340
 
341
        #endregion
342
 
343
        #region public override string ToString()
344
 
345
        public override string ToString()
346
        {
347
            return QualifiedType;
348
        }
349
 
350
        #endregion
351
 
352
        #region public virtual void Translate(XPathNavigator overrides, string category)
353
 
354
        public virtual void Translate(XPathNavigator overrides, string category)
355
        {
356
            Enum @enum;
357
            string s;
358
 
359
            // Try to find out if it is an enum. If the type exists in the normal GLEnums list, use this.
360
            // Otherwise, try to find it in the aux enums list. If it exists in neither, it is not an enum.
361
            // Special case for Boolean - it is an enum, but it is dumb to use that instead of the 'bool' type.
362
            bool normal = false;
363
            bool aux = false;
364
            normal = Enum.GLEnums.TryGetValue(CurrentType, out @enum);
365
            if (!normal)
366
                aux = Enum.AuxEnums != null && Enum.AuxEnums.TryGetValue(CurrentType, out @enum);
367
 
368
            // Translate enum types
369
            if ((normal || aux) && @enum.Name != "GLenum" && @enum.Name != "Boolean")
370
            {
371
                if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None)
372
                    QualifiedType = "int";
373
                else
374
                {
375
#warning "Unecessary code"
376
                    if (normal)
377
                        QualifiedType = CurrentType.Insert(0, String.Format("{0}.", Settings.EnumsOutput));
378
                    else if (aux)
379
                        QualifiedType = CurrentType.Insert(0, String.Format("{0}.", Settings.EnumsAuxOutput));
380
                }
381
            }
382
            else if (GLTypes.TryGetValue(CurrentType, out s))
383
            {
384
                // Check if the parameter is a generic GLenum. If it is, search for a better match,
385
                // otherwise fallback to Settings.CompleteEnumName (named 'All' by default).
386
                if (s.Contains("GLenum") /*&& !String.IsNullOrEmpty(category)*/)
387
                {
388
                    if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None)
389
                    {
390
                        QualifiedType = "int";
391
                    }
392
                    else
393
                    {
394
                        // Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc)
395
                        if (Enum.GLEnums.ContainsKey(category))
396
                        {
397
                            QualifiedType = String.Format("{0}.{1}", Settings.EnumsOutput, Enum.TranslateName(category));
398
                        }
399
                        else
400
                        {
401
                            QualifiedType = String.Format("{0}.{1}", Settings.EnumsOutput, Settings.CompleteEnumName);
402
                        }
403
                    }
404
                }
405
                else
406
                {
407
                    // A few translations for consistency
408
                    switch (CurrentType.ToLower())
409
                    {
410
                        case "string": QualifiedType = "String"; break;
411
                    }
412
 
413
#warning "Stale code"
414
                    // This is not enum, default translation:
415
                    if (CurrentType == "PIXELFORMATDESCRIPTOR" || CurrentType == "LAYERPLANEDESCRIPTOR" ||
416
                        CurrentType == "GLYPHMETRICSFLOAT")
417
                    {
418
                        if (Settings.Compatibility == Settings.Legacy.Tao)
419
                            CurrentType = CurrentType.Insert(0, "Gdi.");
420
                        else
421
                        {
422
                            if (CurrentType == "PIXELFORMATDESCRIPTOR")
423
                                CurrentType = "PixelFormatDescriptor";
424
                            else if (CurrentType == "LAYERPLANEDESCRIPTOR")
425
                                CurrentType = "LayerPlaneDescriptor";
426
                            else if (CurrentType == "GLYPHMETRICSFLOAT")
427
                                CurrentType = "GlyphMetricsFloat";
428
                        }
429
                    }
430
                    else if (CurrentType == "XVisualInfo")
431
                    {
432
                        //p.Pointer = false;
433
                        //p.Reference = true;
434
                    }
435
                    else
436
                        QualifiedType = s;
437
                }
438
            }
439
 
440
            CurrentType =
441
                CSTypes.ContainsKey(CurrentType) ?
442
                CSTypes[CurrentType] : CurrentType;
443
 
444
            // Make sure that enum parameters follow enum overrides, i.e.
445
            // if enum ErrorCodes is overriden to ErrorCode, then parameters
446
            // of type ErrorCodes should also be overriden to ErrorCode.
447
            XPathNavigator enum_override = overrides.SelectSingleNode(String.Format("/overrides/replace/enum[@name='{0}']/name", CurrentType));
448
            if (enum_override != null)
449
            {
450
                // For consistency - many overrides use string instead of String.
451
                if (enum_override.Value == "string")
452
                    QualifiedType = "String";
453
                else if (enum_override.Value == "StringBuilder")
454
                    QualifiedType = "StringBuilder";
455
                else
456
                    CurrentType = enum_override.Value;
457
            }
458
 
459
            if (CurrentType == "IntPtr" && String.IsNullOrEmpty(PreviousType))
460
                Pointer = 0;
461
        }
462
 
463
        #endregion
464
 
465
        #region IComparable<Type> Members
466
 
467
        public int CompareTo(Type other)
468
        {
469
            // Make sure that Pointer parameters are sorted last to avoid bug [#1098].
470
            // The rest of the comparisons are not important, but they are there to
471
            // guarantee a stable order between program executions.
472
            int result = this.CurrentType.CompareTo(other.CurrentType);
473
            if (result == 0)
474
                result = Pointer.CompareTo(other.Pointer);
475
            if (result == 0)
476
                result = Reference.CompareTo(other.Reference);
477
            if (result == 0)
478
                result = Array.CompareTo(other.Array);
479
            if (result == 0)
480
                result = CLSCompliant.CompareTo(other.CLSCompliant);
481
            if (result == 0)
482
                result = ElementCount.CompareTo(other.ElementCount);
483
            return result;
484
        }
485
 
486
        #endregion
487
    }
488
}