From 3c4e3257f24ff0efe34b2759e5fa47e0025118b0 Mon Sep 17 00:00:00 2001 From: Frederik Carlier Date: Tue, 24 May 2016 22:49:37 +0200 Subject: [PATCH] NSNumber: Keep track of the original number type when parsing from XML --- plist-cil.test/IssueTest.cs | 12 ++++ plist-cil.test/NSNumberTests.cs | 22 +++++++ plist-cil.test/plist-cil.test.csproj | 4 ++ plist-cil.test/test-files/ResourceRules.plist | 8 +++ plist-cil/NSNumber.cs | 65 ++++++++++++------- plist-cil/XmlPropertyListParser.cs | 10 ++- 6 files changed, 94 insertions(+), 27 deletions(-) create mode 100644 plist-cil.test/NSNumberTests.cs create mode 100644 plist-cil.test/test-files/ResourceRules.plist diff --git a/plist-cil.test/IssueTest.cs b/plist-cil.test/IssueTest.cs index 134cb53..3ca6d4f 100644 --- a/plist-cil.test/IssueTest.cs +++ b/plist-cil.test/IssueTest.cs @@ -126,6 +126,18 @@ namespace plistcil.test NSDictionary dict = (NSDictionary)PropertyListParser.Parse(new FileInfo("test-files/issue49.plist")); Assert.AreEqual(0, dict.Count); } + + [Test] + public static void TestRealInResourceRule() + { + NSDictionary dict = (NSDictionary)XmlPropertyListParser.Parse(new FileInfo("test-files/ResourceRules.plist")); + Assert.AreEqual(1, dict.Count); + Assert.IsTrue(dict.ContainsKey("weight")); + + var weight = dict["weight"].ToObject(); + Assert.IsInstanceOf(weight); + Assert.AreEqual(10d, (double)weight); + } } } diff --git a/plist-cil.test/NSNumberTests.cs b/plist-cil.test/NSNumberTests.cs new file mode 100644 index 0000000..8dfdfc3 --- /dev/null +++ b/plist-cil.test/NSNumberTests.cs @@ -0,0 +1,22 @@ +using Claunia.PropertyList; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace plistcil.test +{ + [TestFixture] + public class NSNumberTests + { + [Test] + public static void NSNumberConstructorTest() + { + var number = new NSNumber("10032936613", NSNumber.INTEGER); + Assert.AreEqual(NSNumber.INTEGER, number.GetNSNumberType()); + Assert.AreEqual(10032936613, number.ToObject()); + } + } +} diff --git a/plist-cil.test/plist-cil.test.csproj b/plist-cil.test/plist-cil.test.csproj index 5df7326..5cc1427 100644 --- a/plist-cil.test/plist-cil.test.csproj +++ b/plist-cil.test/plist-cil.test.csproj @@ -36,6 +36,7 @@ + @@ -113,6 +114,9 @@ False PreserveNewest + + PreserveNewest + diff --git a/plist-cil.test/test-files/ResourceRules.plist b/plist-cil.test/test-files/ResourceRules.plist new file mode 100644 index 0000000..ba8e503 --- /dev/null +++ b/plist-cil.test/test-files/ResourceRules.plist @@ -0,0 +1,8 @@ + + + + + weight + 10 + + diff --git a/plist-cil/NSNumber.cs b/plist-cil/NSNumber.cs index 9e083de..9614da1 100644 --- a/plist-cil/NSNumber.cs +++ b/plist-cil/NSNumber.cs @@ -70,17 +70,36 @@ namespace Claunia.PropertyList /// /// public NSNumber(byte[] bytes, int type) + { + switch (type) + { + case INTEGER: + doubleValue = longValue = BinaryPropertyListParser.ParseLong(bytes); + break; + + case REAL: + doubleValue = BinaryPropertyListParser.ParseDouble(bytes); + longValue = (long)Math.Round(doubleValue); + break; + + default: + throw new ArgumentException("Type argument is not valid."); + } + this.type = type; + } + + public NSNumber(string text, int type) { switch (type) { case INTEGER: { - doubleValue = longValue = BinaryPropertyListParser.ParseLong(bytes); + doubleValue = longValue = long.Parse(text); break; } case REAL: { - doubleValue = BinaryPropertyListParser.ParseDouble(bytes); + doubleValue = double.Parse(text); longValue = (long)Math.Round(doubleValue); break; } @@ -103,36 +122,34 @@ namespace Claunia.PropertyList { if (text == null) throw new ArgumentException("The given string is null and cannot be parsed as number."); - try + + long l; + double d; + + if (long.TryParse(text, out l)) { - long l = long.Parse(text); doubleValue = longValue = l; type = INTEGER; } - catch (Exception) + else if (double.TryParse(text, out d)) { - try + doubleValue = d; + longValue = (long)Math.Round(doubleValue); + type = REAL; + } + else + { + bool isTrue = text.ToLower().Equals("true") || text.ToLower().Equals("yes"); + bool isFalse = text.ToLower().Equals("false") || text.ToLower().Equals("no"); + + if (isTrue || isFalse) { - doubleValue = double.Parse(text, CultureInfo.InvariantCulture); - longValue = (long)Math.Round(doubleValue); - type = REAL; + type = BOOLEAN; + doubleValue = longValue = boolValue ? 1 : 0; } - catch (Exception) + else { - try - { - boolValue = text.ToLower().Equals("true") || text.ToLower().Equals("yes"); - if (!boolValue && !(text.ToLower().Equals("false") || text.ToLower().Equals("no"))) - { - throw new Exception("not a bool"); - } - type = BOOLEAN; - doubleValue = longValue = boolValue ? 1 : 0; - } - catch (Exception) - { - throw new ArgumentException("The given string neither represents a double, an int nor a bool value."); - } + throw new ArgumentException("The given string neither represents a double, an int nor a bool value."); } } } diff --git a/plist-cil/XmlPropertyListParser.cs b/plist-cil/XmlPropertyListParser.cs index 85f07b7..31a05b4 100644 --- a/plist-cil/XmlPropertyListParser.cs +++ b/plist-cil/XmlPropertyListParser.cs @@ -44,7 +44,11 @@ namespace Claunia.PropertyList public static NSObject Parse(FileInfo f) { XmlDocument doc = new XmlDocument(); - doc.Load(f.OpenRead()); + + using (Stream stream = f.OpenRead()) + { + doc.Load(stream); + } return ParseDocument(doc); } @@ -153,9 +157,9 @@ namespace Claunia.PropertyList if (n.Name.Equals("false")) return new NSNumber(false); if (n.Name.Equals("integer")) - return new NSNumber(GetNodeTextContents(n)); + return new NSNumber(GetNodeTextContents(n), NSNumber.INTEGER); if (n.Name.Equals("real")) - return new NSNumber(GetNodeTextContents(n)); + return new NSNumber(GetNodeTextContents(n), NSNumber.REAL); if (n.Name.Equals("string")) return new NSString(GetNodeTextContents(n)); if (n.Name.Equals("data"))