2009-11-23 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web / BrowserCapabilities.cs
index ac1037bbd10af9ab2ca7fbba598a652b6a783239..c75f572a2e9455a29277ef4b2a770cbb81364e3a 100644 (file)
@@ -5,7 +5,7 @@
 //   Patrik Torstensson (Patrik.Torstensson@labs2.com)
 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
-// (c) 2003 Novell, Inc. (http://www.novell.com)
+// (c) 2003-2009 Novell, Inc. (http://www.novell.com)
 //
 
 //
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-using System;
+
 using System.Collections;
+using System.Globalization;
 using System.Web.Configuration;
 using System.Web.UI;
+using System.Security.Permissions;
+using System.Web.Util;
 
-#if NET_2_0
-namespace System.Web.Configuration {
+namespace System.Web.Configuration
+{
        public partial class HttpCapabilitiesBase
-#else
-
-namespace System.Web {
-       public partial class HttpBrowserCapabilities : HttpCapabilitiesBase
-#endif
        {
-               const int HaveActiveXControls = 1;
-               const int HaveAOL = 2;
-               const int HaveBackGroundSounds = 3;
-               const int HaveBeta = 4;
-               const int HaveBrowser = 5;
-               const int HaveCDF = 6;
-               //const int HaveClrVersion = 7;
-               const int HaveCookies = 8;
-               const int HaveCrawler = 9;
-               const int HaveEcmaScriptVersion = 10;
-               const int HaveFrames = 11;
-               const int HaveJavaApplets = 12;
-               const int HaveJavaScript = 13;
-               const int HaveMajorVersion = 14;
-               const int HaveMinorVersion = 15;
-               //const int HaveMSDomVersion = 16;
-               const int HavePlatform = 17;
-               const int HaveTables = 18;
-               //const int HaveTagWriter = 19;
-               const int HaveVBScript = 20;
-               const int HaveVersion = 21;
-               const int HaveW3CDomVersion = 22;
-               const int HaveWin16 = 23;
-               const int HaveWin32 = 24;
-
-               int flags;
+               const int HaveActiveXControls = 1; // 1;
+               const int HaveAdapters = 2;
+               const int HaveAOL = 3; // 2;
+               const int HaveBackGroundSounds = 4; // 3;
+               const int HaveBeta = 5; // 4;
+               const int HaveBrowser = 6; // 5;
+               const int HaveBrowsers = 7;
+               const int HaveCanCombineFormsInDeck = 8;
+               const int HaveCanInitiateVoiceCall = 9;
+               const int HaveCanRenderAfterInputOrSelectElement = 10;
+               const int HaveCanRenderEmptySelects = 11;
+               const int HaveCanRenderInputAndSelectElementsTogether = 12;
+               const int HaveCanRenderMixedSelects = 13;
+               const int HaveCanRenderOneventAndPrevElementsTogether = 14;
+               const int HaveCanRenderPostBackCards = 15;
+               const int HaveCanRenderSetvarZeroWithMultiSelectionList = 16;
+               const int HaveCanSendMail = 17;
+               const int HaveCDF = 18; // 6;
+               //const int HaveClrVersion = 19; // 7;
+               const int HaveCookies = 20; // 8;
+               const int HaveCrawler = 21; // 9;
+               const int HaveDefaultSubmitButtonLimit = 22;
+               const int HaveEcmaScriptVersion = 23;
+               const int HaveFrames = 24; // 11;
+               const int HaveGatewayMajorVersion = 25;
+               const int HaveGatewayMinorVersion = 26;
+               const int HaveGatewayVersion = 27;
+               const int HaveHasBackButton = 28;
+               const int HaveHidesRightAlignedMultiselectScrollbars = 29;
+               const int HaveHtmlTextWriter = 30;
+               const int HaveId = 31;
+               const int HaveInputType = 32;
+               const int HaveIsColor = 33;
+               const int HaveIsMobileDevice = 34;
+               const int HaveJavaApplets = 35; // 12;
+               const int HaveJavaScript = 36; // 13;
+               const int HaveJScriptVersion = 37;
+               const int HaveMajorVersion = 38; // 14;
+               const int HaveMaximumHrefLength = 39;
+               const int HaveMaximumRenderedPageSize = 40;
+               const int HaveMaximumSoftkeyLabelLength = 41;
+               const int HaveMinorVersion = 42; // 15;
+               const int HaveMinorVersionString = 43;
+               const int HaveMobileDeviceManufacturer = 44;
+               const int HaveMobileDeviceModel = 45;
+               const int HaveMSDomVersion = 46; // 16;
+               const int HaveNumberOfSoftkeys = 47;
+               const int HavePlatform = 48; // 17;
+               const int HavePreferredImageMime = 49;
+               const int HavePreferredRenderingMime = 50;
+               const int HavePreferredRenderingType = 51;
+               const int HavePreferredRequestEncoding = 52;
+               const int HavePreferredResponseEncoding = 53;
+               const int HaveRendersBreakBeforeWmlSelectAndInput = 54;
+               const int HaveRendersBreaksAfterHtmlLists = 55;
+               const int HaveRendersBreaksAfterWmlAnchor = 56;
+               const int HaveRendersBreaksAfterWmlInput = 57;
+               const int HaveRendersWmlDoAcceptsInline = 58;
+               const int HaveRendersWmlSelectsAsMenuCards = 59;
+               const int HaveRequiredMetaTagNameValue = 60;
+               const int HaveRequiresAttributeColonSubstitution = 61;
+               const int HaveRequiresContentTypeMetaTag = 62;
+               const int HaveRequiresControlStateInSession = 63;
+               const int HaveRequiresDBCSCharacter = 64;
+               const int HaveRequiresHtmlAdaptiveErrorReporting = 65;
+               const int HaveRequiresLeadingPageBreak = 66;
+               const int HaveRequiresNoBreakInFormatting = 67;
+               const int HaveRequiresOutputOptimization = 68;
+               const int HaveRequiresPhoneNumbersAsPlainText = 69;
+               const int HaveRequiresSpecialViewStateEncoding = 70;
+               const int HaveRequiresUniqueFilePathSuffix = 71;
+               const int HaveRequiresUniqueHtmlCheckboxNames = 72;
+               const int HaveRequiresUniqueHtmlInputNames = 73;
+               const int HaveRequiresUrlEncodedPostfieldValues = 74;
+               const int HaveScreenBitDepth = 75;
+               const int HaveScreenCharactersHeight = 76;
+               const int HaveScreenCharactersWidth = 77;
+               const int HaveScreenPixelsHeight = 78;
+               const int HaveScreenPixelsWidth = 79;
+               const int HaveSupportsAccesskeyAttribute = 80;
+               const int HaveSupportsBodyColor = 81;
+               const int HaveSupportsBold = 82;
+               const int HaveSupportsCacheControlMetaTag = 83;
+               const int HaveSupportsCallback = 84;
+               const int HaveSupportsCss = 85;
+               const int HaveSupportsDivAlign = 86;
+               const int HaveSupportsDivNoWrap = 87;
+               const int HaveSupportsEmptyStringInCookieValue = 88;
+               const int HaveSupportsFontColor = 89;
+               const int HaveSupportsFontName = 90;
+               const int HaveSupportsFontSize = 91;
+               const int HaveSupportsImageSubmit = 92;
+               const int HaveSupportsIModeSymbols = 93;
+               const int HaveSupportsInputIStyle = 94;
+               const int HaveSupportsInputMode = 95;
+               const int HaveSupportsItalic = 96;
+               const int HaveSupportsJPhoneMultiMediaAttributes = 97;
+               const int HaveSupportsJPhoneSymbols = 98;
+               const int HaveSupportsQueryStringInFormAction = 99;
+               const int HaveSupportsRedirectWithCookie = 100;
+               const int HaveSupportsSelectMultiple = 101;
+               const int HaveSupportsUncheck = 102;
+               const int HaveSupportsXmlHttp = 103;
+               const int HaveTables = 104; // 18;
+               const int HaveTagWriter = 105; // 19;
+               const int HaveType = 106;
+               const int HaveUseOptimizedCacheKey = 107;
+               const int HaveVBScript = 108; // 20;
+               const int HaveVersion = 109; // 21;
+               const int HaveW3CDomVersion = 110; // 22;
+               const int HaveWin16 = 111; // 23;
+               const int HaveWin32 = 112; // 24;
+               const int LastHaveFlag = 113;
+
+               BitArray flags = new BitArray (LastHaveFlag);
                bool activeXControls;
                bool aol;
                bool backgroundSounds;
@@ -83,10 +170,10 @@ namespace System.Web {
                bool javaScript;
                int majorVersion;
                double minorVersion;
-               //Version msDomVersion;
+               Version msDomVersion;
                string platform;
                bool tables;
-               //Type tagWriter;
+               Type tagWriter;
                bool vbscript;
                string version;
                Version w3CDomVersion;
@@ -98,8 +185,8 @@ namespace System.Web {
                public bool ActiveXControls {
                        get {
                                if (!Get (HaveActiveXControls)) {
+                                       activeXControls = ReadBoolean ("activexcontrols");
                                        Set (HaveActiveXControls);
-                                       activeXControls = ReadBoolean ("activexcontrols", false);
                                }
 
                                return activeXControls;
@@ -109,8 +196,8 @@ namespace System.Web {
                public bool AOL {
                        get {
                                if (!Get (HaveAOL)) {
+                                       aol = ReadBoolean ("aol");
                                        Set (HaveAOL);
-                                       aol = ReadBoolean ("aol", false);
                                }
 
                                return aol;
@@ -120,8 +207,8 @@ namespace System.Web {
                public bool BackgroundSounds {
                        get {
                                if (!Get (HaveBackGroundSounds)) {
+                                       backgroundSounds = ReadBoolean ("backgroundsounds");
                                        Set (HaveBackGroundSounds);
-                                       backgroundSounds = ReadBoolean ("backgroundsounds", false);
                                }
 
                                return backgroundSounds;
@@ -131,8 +218,8 @@ namespace System.Web {
                public bool Beta {
                        get {
                                if (!Get (HaveBeta)) {
+                                       beta = ReadBoolean ("beta");
                                        Set (HaveBeta);
-                                       beta = ReadBoolean ("beta", false);
                                }
 
                                return beta;
@@ -142,21 +229,46 @@ namespace System.Web {
                public string Browser {
                        get {
                                if (!Get (HaveBrowser)) {
-                                       Set (HaveBrowser);
                                        browser = this ["browser"];
-                                       if (browser == null)
+                                       if (browser == null || browser.Length == 0)
                                                browser = "Unknown";
+                                       Set (HaveBrowser);
                                }
 
                                return browser;
                        }
                }
 
+               ArrayList browsers = null;
+               public ArrayList Browsers {
+                       get {
+                               if (!Get (HaveBrowsers)) {
+                                       browsers = ReadArrayList ("browsers");
+                                       Set (HaveBrowsers);
+                               }
+
+                               return browsers;
+                       }
+               }
+
+               public bool IsBrowser (string browserName) 
+               {
+                       foreach (string browser in Browsers) {
+                               if (0 == String.Compare (browser, "Unknown", StringComparison.OrdinalIgnoreCase)) {
+                                       continue;
+                               }
+                               if (0 == String.Compare (browserName, browser, StringComparison.OrdinalIgnoreCase)) {
+                                       return true;
+                               }
+                       }
+                       return false;
+               }
+
                public bool CDF {
                        get {
                                if (!Get (HaveCDF)) {
+                                       cdf = ReadBoolean ("cdf");
                                        Set (HaveCDF);
-                                       cdf = ReadBoolean ("cdf", false);
                                }
 
                                return cdf;
@@ -175,8 +287,8 @@ namespace System.Web {
                public bool Cookies {
                        get {
                                if (!Get (HaveCookies)) {
+                                       cookies = ReadBoolean ("cookies");
                                        Set (HaveCookies);
-                                       cookies = ReadBoolean ("cookies", false);
                                }
 
                                return cookies;
@@ -186,8 +298,8 @@ namespace System.Web {
                public bool Crawler {
                        get {
                                if (!Get (HaveCrawler)) {
+                                       crawler = ReadBoolean ("crawler");
                                        Set (HaveCrawler);
-                                       crawler = ReadBoolean ("crawler", false);
                                }
 
                                return crawler;
@@ -197,13 +309,8 @@ namespace System.Web {
                public Version EcmaScriptVersion {
                        get {
                                if (!Get (HaveEcmaScriptVersion)) {
-                                       string ver_str;
+                                       ecmaScriptVersion = ReadVersion ("ecmascriptversion");
                                        Set (HaveEcmaScriptVersion);
-                                       ver_str = this ["ecmascriptversion"];
-                                       if (ver_str == null)
-                                               ecmaScriptVersion = new Version (0, 0);
-                                       else
-                                               ecmaScriptVersion = new Version (ver_str);
                                }
 
                                return ecmaScriptVersion;
@@ -213,8 +320,8 @@ namespace System.Web {
                public bool Frames {
                        get {
                                if (!Get (HaveFrames)) {
+                                       frames = ReadBoolean ("frames");
                                        Set (HaveFrames);
-                                       frames = ReadBoolean ("frames", false);
                                }
 
                                return frames;
@@ -224,19 +331,21 @@ namespace System.Web {
                public bool JavaApplets {
                        get {
                                if (!Get (HaveJavaApplets)) {
+                                       javaApplets = ReadBoolean ("javaapplets");
                                        Set (HaveJavaApplets);
-                                       javaApplets = ReadBoolean ("javaapplets", false);
                                }
 
                                return javaApplets;
                        }
                }
 
+
+               [Obsolete]
                public bool JavaScript {
                        get {
                                if (!Get (HaveJavaScript)) {
+                                       javaScript = ReadBoolean ("javascript");
                                        Set (HaveJavaScript);
-                                       javaScript = ReadBoolean ("javascript", false);
                                }
 
                                return javaScript;
@@ -246,8 +355,8 @@ namespace System.Web {
                public int MajorVersion {
                        get {
                                if (!Get (HaveMajorVersion)) {
+                                       majorVersion = ReadInt32 ("majorver");
                                        Set (HaveMajorVersion);
-                                       majorVersion = ReadInt32 ("majorver", 0);
                                }
 
                                return majorVersion;
@@ -257,8 +366,8 @@ namespace System.Web {
                public double MinorVersion {
                        get {
                                if (!Get (HaveMinorVersion)) {
+                                       minorVersion = ReadDouble ("minorver");
                                        Set (HaveMinorVersion);
-                                       minorVersion = ReadDouble ("minorver", 0);
                                }
 
                                return minorVersion;
@@ -267,17 +376,20 @@ namespace System.Web {
 
                public Version MSDomVersion {
                        get {
-                               return new Version (0, 0);
+                               if (!Get (HaveMSDomVersion)) {
+                                       msDomVersion = ReadVersion ("msdomversion");
+                                       Set (HaveMSDomVersion);
+                               }
+
+                               return msDomVersion;
                        }
                }
 
                public string Platform {
                        get {
                                if (!Get (HavePlatform)) {
+                                       platform = ReadString ("platform");
                                        Set (HavePlatform);
-                                       platform = this ["platform"];
-                                       if (platform == null)
-                                               platform = "";
                                }
 
                                return platform;
@@ -287,8 +399,8 @@ namespace System.Web {
                public bool Tables {
                        get {
                                if (!Get (HaveTables)) {
+                                       tables = ReadBoolean ("tables");
                                        Set (HaveTables);
-                                       tables = ReadBoolean ("tables", false);
                                }
 
                                return tables;
@@ -297,9 +409,18 @@ namespace System.Web {
 
                public Type TagWriter {
                        get {
-                               return typeof (HtmlTextWriter);
+                               if (!Get (HaveTagWriter)) {
+                                       tagWriter = GetTagWriter ();
+                                       Set (HaveTagWriter);
+                               }
+                               return tagWriter;
                        }
                }
+               
+               internal virtual Type GetTagWriter ()
+               {
+                               return typeof (HtmlTextWriter);                 
+               }
 
                public string Type {
                        get {
@@ -310,8 +431,8 @@ namespace System.Web {
                public bool VBScript {
                        get {
                                if (!Get (HaveVBScript)) {
+                                       vbscript = ReadBoolean ("vbscript");
                                        Set (HaveVBScript);
-                                       vbscript = ReadBoolean ("vbscript", false);
                                }
 
                                return vbscript;
@@ -321,10 +442,8 @@ namespace System.Web {
                public string Version {
                        get {
                                if (!Get (HaveVersion)) {
+                                       version = ReadString ("version");
                                        Set (HaveVersion);
-                                       version = this ["version"];
-                                       if (version == null)
-                                               version = "";
                                }
 
                                return version;
@@ -334,13 +453,8 @@ namespace System.Web {
                public Version W3CDomVersion {
                        get {
                                if (!Get (HaveW3CDomVersion)) {
-                                       string ver_str;
+                                       w3CDomVersion = ReadVersion ("w3cdomversion");
                                        Set (HaveW3CDomVersion);
-                                       ver_str = this ["w3cdomversion"];
-                                       if (ver_str == null)
-                                               w3CDomVersion = new Version (0, 0);
-                                       else
-                                               w3CDomVersion = new Version (ver_str);
                                }
 
                                return w3CDomVersion;
@@ -350,8 +464,8 @@ namespace System.Web {
                public bool Win16 {
                        get {
                                if (!Get (HaveWin16)) {
+                                       win16 = ReadBoolean ("win16");
                                        Set (HaveWin16);
-                                       win16 = ReadBoolean ("win16", false);
                                }
 
                                return win16;
@@ -363,15 +477,14 @@ namespace System.Web {
                                // This is the list of different windows platforms that browscap.ini has.
                                // Win16 Win2000 Win2003 Win32 Win95 Win98 WinME WinNT WinVI WinXP
                                if (!Get (HaveWin32)) {
-                                       Set (HaveWin32);
                                        string platform = Platform;
                                        win32 = (platform != "Win16" && platform.StartsWith ("Win"));
+                                       Set (HaveWin32);
                                }
                                return win32;
                        }
                }
 
-#if NET_1_1
                public Version [] GetClrVersions ()
                {
                        if (clrVersions == null)
@@ -379,7 +492,6 @@ namespace System.Web {
 
                        return clrVersions;
                }
-#endif
 
                void InternalGetClrVersions ()
                {
@@ -387,7 +499,7 @@ namespace System.Web {
                        string s = useragent;
                        ArrayList list = null;
                        int idx;
-                       while ((idx = s.IndexOf (".NET CLR ")) != -1) {
+                       while ((s != null) && (idx = s.IndexOf (".NET CLR ")) != -1) {
                                int end = s.IndexOfAny (anychars, idx + 9);
                                if (end == -1)
                                        break;
@@ -409,56 +521,98 @@ namespace System.Web {
                        
                        if (list == null || list.Count == 0) {
                                clrVersion = new Version ();
-                               clrVersions = new Version [] { clrVersion };
+                               clrVersions = null;
                        } else {
                                list.Sort ();
                                clrVersions = (Version []) list.ToArray (typeof (Version));
                        }
                }
 
-               bool ReadBoolean (string key, bool dflt)
+               bool ReadBoolean (string key)
                {
                        string v = this [key];
-                       if (v == null)
-                               return dflt;
+                       if (v == null) {
+                               throw CreateCapabilityNotFoundException (key);
+                       }
 
-                       return (v == "True");
+                       return (String.Compare (v, "True", true, Helpers.InvariantCulture) == 0);
                }
 
-               int ReadInt32 (string key, int dflt)
+               int ReadInt32 (string key)
                {
                        string v = this [key];
-                       if (v == null)
-                               return dflt;
+                       if (v == null) {
+                               throw CreateCapabilityNotFoundException (key);
+                       }
 
                        try {
                                return Int32.Parse (v);
                        } catch {
-                               return dflt;
+                               throw CreateCapabilityNotFoundException (key);
                        }
                }
 
-               double ReadDouble (string key, double dflt)
+               double ReadDouble (string key)
                {
                        string v = this [key];
-                       if (v == null)
-                               return dflt;
+                       if (v == null) {
+                               throw CreateCapabilityNotFoundException (key);
+                       }
 
                        try {
                                return Double.Parse (v);
                        } catch {
-                               return dflt;
+                               throw CreateCapabilityNotFoundException (key);
+                       }
+               }
+
+               string ReadString (string key) 
+               {
+                       string v = this [key];
+                       if (v == null) {
+                               throw CreateCapabilityNotFoundException (key);
+                       }
+
+                       return v;
+               }
+
+               Version ReadVersion (string key) 
+               {
+                       string v = this [key];
+                       if (v == null) {
+                               throw CreateCapabilityNotFoundException (key);
+                       }
+
+                       try {
+                               return new Version (v);
+                       }
+                       catch {
+                               throw CreateCapabilityNotFoundException (key);
+                       }
+               }
+
+               ArrayList ReadArrayList (string key) 
+               {
+                       ArrayList v = (ArrayList)this.capabilities [key];
+                       if (v == null) {
+                               throw CreateCapabilityNotFoundException (key);
                        }
+
+                       return v;
+               }
+
+               Exception CreateCapabilityNotFoundException (string key) {
+                       return new ArgumentNullException (String.Format ("browscaps.ini does not contain a definition for capability {0} for userAgent {1}", key, Browser));
                }
 
                bool Get (int idx)
                {
-                       return (flags & (1 << idx)) != 0;
+                       return flags.Get (idx);
                }
 
                void Set (int idx)
                {
-                       flags |= (1 << idx);
+                       flags.Set (idx, true);
                }
        }
 }