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.Diagnostics;
9
using System.Globalization;
10
using System.Linq;
11
using System.Text;
12
 
13
namespace Bind.Structures
14
{
15
    /// <summary>
16
    /// Represents an opengl constant in C# format. Both the constant name and value
17
    /// can be retrieved or set. The value can be either a number, another constant
18
    /// or an alias to a constant 
19
    /// </summary>
20
    public class Constant
21
    {
22
        static StringBuilder translator = new StringBuilder();
23
 
24
        #region PreviousName
25
 
26
        string previous_name;
27
 
28
        // Gets the name prior to translation.
29
        public string PreviousName
30
        {
31
            get { return previous_name; }
32
            private set { previous_name = value; }
33
        }
34
 
35
        #endregion
36
 
37
        #region public string Name
38
 
39
        string _name;
40
 
41
        /// <summary>
42
        /// Gets or sets the name of the opengl constant (eg. GL_LINES).
43
        /// Undergoes processing unless the Settings.Legacy.NoAdvancedEnumProcessing flag is set.
44
        /// </summary>
45
        public string Name
46
        {
47
            get { return _name; }
48
            set
49
            {
50
                if (!String.IsNullOrEmpty(value))
51
                    _name = Translate(value.Trim(), false);
52
                else _name = value;
53
 
54
                PreviousName = value;
55
            }
56
        }
57
 
58
        #endregion
59
 
60
        #region public string Value
61
 
62
        string _value;
63
 
64
        /// <summary>
65
        /// Gets or sets the value of the opengl constant (eg. 0x00000001).
66
        /// </summary>
67
        public string Value
68
        {
69
            get
70
            {
71
                return _value;
72
            }
73
            set
74
            {
75
                if (!String.IsNullOrEmpty(value))
76
                {
77
                    value = value.Trim();
78
 
79
                    if (value.ToLower() == " 0xffffffffffffffff") Debugger.Break();
80
                    // Check whether this value is a number and make sure the Unchecked property is set correctly.
81
                    ulong number;
82
                    if (value.ToLower().StartsWith("0x"))
83
                    {
84
                        // Trim the unsigned or long specifiers used in C constants ('u' or 'ull').
85
                        if (value.ToLower().EndsWith("ull"))
86
                            value = value.Substring(0, value.Length - 3);
87
                        if (value.ToLower().EndsWith("u"))
88
                            value = value.Substring(0, value.Length - 1);
89
                    }
90
                    if (UInt64.TryParse(value.ToLower().Replace("0x", String.Empty), NumberStyles.AllowHexSpecifier, null, out number))
91
                    {
92
                        // The value is a number, check if it should be unchecked.
93
                        if (number > 0x7FFFFFFF)
94
                            Unchecked = true;
95
                    }
96
                    else
97
                    {
98
                        // The value is not a number. Strip the prefix.
99
                        if (value.StartsWith(Settings.ConstantPrefix))
100
                            value = value.Substring(Settings.ConstantPrefix.Length);
101
 
102
                        // If the name now starts with a digit (doesn't matter whether we
103
                        // stripped "GL_" above), add a "GL_" prefix.
104
                        // (e.g. GL_4_BYTES).
105
                        if (Char.IsDigit(value[0]))
106
                            value = Settings.ConstantPrefix + value;
107
                    }
108
                }
109
 
110
                _value = Translate(value, true);
111
            }
112
        }
113
 
114
        #endregion
115
 
116
        #region public string Reference
117
 
118
        string _reference;
119
 
120
        /// <summary>
121
        /// Gets or sets a string indicating the OpenGL enum reference by this constant.
122
        /// Can be null.
123
        /// </summary>
124
        public string Reference
125
        {
126
            get { return _reference; }
127
            set
128
            {
129
                if (!String.IsNullOrEmpty(value))
130
                    _reference = Enum.TranslateName(value.Trim());
131
                else _reference = value;
132
            }
133
        }
134
 
135
        #endregion
136
 
137
        #region public bool Unchecked
138
 
139
        private bool @unchecked;
140
 
141
        public bool Unchecked
142
        {
143
            get { return @unchecked; }
144
            set { @unchecked = value; }
145
        }
146
 
147
        #endregion
148
 
149
        #region Constructors
150
 
151
        /// <summary>
152
        /// Creates an empty Constant.
153
        /// </summary>
154
        public Constant()
155
        {
156
        }
157
 
158
        /// <summary>
159
        /// Creates a Constant with the given name and value.
160
        /// </summary>
161
        /// <param name="name">The Name of the Constant.</param>
162
        /// <param name="value">The Type of the Constant.</param>
163
        public Constant(string name, string value)
164
        {
165
            Name = name;
166
            Value = value;
167
        }
168
 
169
        #endregion
170
 
171
        #region Translate
172
 
173
        public static string Translate(string s, bool isValue)
174
        {
175
            translator.Remove(0, translator.Length);
176
 
177
            // Translate the constant's name to match .Net naming conventions
178
            bool name_is_all_caps = s.AsEnumerable().All(c => Char.IsLetter(c) ? Char.IsUpper(c) : true);
179
            bool name_contains_underscore = s.Contains("_");
180
            if ((Settings.Compatibility & Settings.Legacy.NoAdvancedEnumProcessing) == Settings.Legacy.None &&
181
                (name_is_all_caps || name_contains_underscore))
182
            {
183
                bool next_char_uppercase = true;
184
                bool is_after_digit = false;
185
 
186
                if (!isValue && Char.IsDigit(s[0]))
187
                    translator.Insert(0, Settings.ConstantPrefix);
188
 
189
                foreach (char c in s)
190
                {
191
                    if (c == '_')
192
                        next_char_uppercase = true;
193
                    else if (Char.IsDigit(c))
194
                    {
195
                        is_after_digit = true;
196
                        translator.Append(c);
197
                    }
198
                    else
199
                    {
200
                        translator.Append(next_char_uppercase || (is_after_digit && c == 'd') ? Char.ToUpper(c) : Char.ToLower(c));
201
                        is_after_digit = next_char_uppercase = false;
202
                    }
203
                }
204
 
205
                translator[0] = Char.ToUpper(translator[0]);
206
            }
207
            else
208
                translator.Append(s);
209
 
210
            return translator.ToString();
211
        }
212
 
213
        #endregion
214
 
215
        /// <summary>
216
        /// Replces the Value of the given constant with the value referenced by the [c.Reference, c.Value] pair.
217
        /// </summary>
218
        /// <param name="c">The Constant to translate</param>
219
        /// <param name="enums">The list of enums to check.</param>
220
        /// <param name="auxEnums">The list of auxilliary enums to check.</param>
221
        /// <returns>True if the reference was found; false otherwise.</returns>
222
        public static bool TranslateConstantWithReference(Constant c, EnumCollection enums, EnumCollection auxEnums)
223
        {
224
            if (!String.IsNullOrEmpty(c.Reference))
225
            {
226
                Constant referenced_constant;
227
 
228
                if (enums.ContainsKey(c.Reference) && enums[c.Reference].ConstantCollection.ContainsKey(c.Value))
229
                {
230
                    TranslateConstantWithReference(enums[c.Reference].ConstantCollection[c.Value] as Constant, enums, auxEnums);
231
                    referenced_constant = (enums[c.Reference].ConstantCollection[c.Value] as Constant);
232
                }
233
                else if (auxEnums.ContainsKey(c.Reference) && auxEnums[c.Reference].ConstantCollection.ContainsKey(c.Value))
234
                {
235
                    TranslateConstantWithReference(auxEnums[c.Reference].ConstantCollection[c.Value] as Constant, enums, auxEnums);
236
                    referenced_constant = (auxEnums[c.Reference].ConstantCollection[c.Value] as Constant);
237
                }
238
                else
239
                {
240
                    Console.WriteLine("[Warning] Reference {0} not found for token {1}.", c.Reference, c);
241
                    return false;
242
                }
243
                //else throw new InvalidOperationException(String.Format("Unknown Enum \"{0}\" referenced by Constant \"{1}\"",
244
                //                                                       c.Reference, c.ToString()));
245
 
246
                c.Value = referenced_constant.Value;
247
                c.Reference = null;
248
                c.Unchecked = referenced_constant.Unchecked;
249
            }
250
 
251
            return true;
252
        }
253
 
254
        #region public override string ToString()
255
 
256
        /// <summary>
257
        /// Returns a string that represents the full constant declaration without decorations
258
        /// (eg GL_XXX_YYY = (int)0xDEADBEEF or GL_XXX_YYY = GL_ZZZ.FOOBAR).
259
        /// </summary>
260
        /// <returns></returns>
261
        public override string ToString()
262
        {
263
            if (String.IsNullOrEmpty(Name))
264
                return "";
265
            return String.Format("{0} = {1}((int){2}{3})",
266
                Name, Unchecked ? "unchecked" : "",
267
                !String.IsNullOrEmpty(Reference) ? Reference + "." : "", Value);
268
 
269
            //return String.Format("{0} = {1}((int){2})", Name, Unchecked ? "unchecked" : "", Value);
270
        }
271
 
272
        #endregion
273
    }
274
}