From 06f4f1a4a80d20d125ce670c6502ba0db18d4740 Mon Sep 17 00:00:00 2001 From: Peter O Date: Wed, 2 Oct 2019 19:10:26 -0400 Subject: [PATCH] version 4.0.1 --- CBOR.nuspec | 52 ++------------------------ CBOR/CBOR.csproj | 10 ++--- CBOR/PeterO/Cbor/CBORObject.cs | 8 ++-- CBOR/docs.xml | 61 ++++++++++++++++++++----------- CBOR20/Properties/AssemblyInfo.cs | 6 +-- CBOR40/Properties/AssemblyInfo.cs | 6 +-- CBORDocs/DocVisitor.cs | 2 +- CBORTest/CBORExtraTest.cs | 7 ++-- CBORTest/CBORObjectTest.cs | 24 ++++++------ CBORTest/CBORTest.cs | 2 +- CBORTest/TestCommon.cs | 56 ++++++++++++++++++++++++++++ History.md | 4 ++ Properties/AssemblyInfo.cs | 6 +-- docs/PeterO.Cbor.CBORObject.md | 29 +++++++++------ 14 files changed, 154 insertions(+), 119 deletions(-) diff --git a/CBOR.nuspec b/CBOR.nuspec index e270d554..871ec4f2 100644 --- a/CBOR.nuspec +++ b/CBOR.nuspec @@ -1,51 +1,5 @@ 4.0.0PeterO.CborfalseVersion 4.0.0: +>4.0.1PeterO.CborfalseVersion 4.0.1: -- Fix issues with CTAP2 Canonical CBOR form -- Support field serialization and deserialization in ToObject and FromObject - -Version 4.0.0-beta2: - -The features in this version include: - -- The CBOR library no longer stores numbers in a special form beyond the CBOR data model, which represents all "65-bit" signed integers and all "double" values. This means the CBOR library no longer stores certain numbers as EDecimal, EInteger, EFloat, etc., rather than as tagged CBOR objects. -- CBORObject.CompareTo now compares objects using the default deterministic encoding comparison in the draft revision of the CBOR specification, and no longer treats numbers (objects with the former type CBORType.Number) as a special class. -- CBORType.Number is deprecated; CBORObjects no longer have this type. In its place, certain numbers now have new CBORTypes Integer or FloatingPoint. -- CBORObject now stores floating-point numbers internally as the bits that make them up, rather than as `double`s, to avoid data loss in conversions. -- Methods were added to CBORObject to read and write floating-point numbers in terms of their bit patterns rather than as `double`s or `float`s. -- Ctap2Canonical was made more strict and now works when decoding CBOR objects. -- Added ReadSequence and DecodeSequence to CBORObject for reading CBOR sequences. -- New CBORNumber class for storing numbers representable in CBOR. The new CBORObject.IsNumber property checks whether a CBOR object represents a number. -- Bug fixes - -Version 4.0.0-beta1: - -- Support nullable types in CBORObject.ToObject. -- Update Numbers library to newer version -- JSONOptions.Base64Padding now has no effect. The library will now write padding as necessary when - writing traditional base64 to JSON and write no padding when writing base64url to JSON. -- JSONOptions.ReplaceSurrogates property added. -- Restrict valid shared reference indices to integers 0 or greater. -- Reject writing JSON where CBOR maps have two keys with the same string equivalent. -- Improve performance of CBOR object comparisons involving big floats. - -Version 4.0.0-alpha2: - -- Support CBOR tags for IRIs and IRI references. -- Add CBOREncodeOptions.DefaultCtap2Canonical field. - -Version 4.0.0-alpha1: - -- Remove all APIs obsoleted since version 3.4. This - includes the BigInteger, ExtendedDecimal, and ExtendedFloat APIs, - which were renamed and moved to a different library, as well as the - ICBORTag and CBORTypeFilter APIs. -- Changed implementation of FromObject, including imposing a nesting depth - limit and supporting a CBORTypeMapper parameter. -- Property name conversion rules (in PODOptions) were changed - in this version with respect to FromObject. In this sense, - PODOptions.RemoveIsPrefix was removed. -- Certain other changes in CBOR object reading and validation were - made; they are largely compatible with previous versions but may be - backwards-incompatible in certain rare casesCC0-1.0https://github.com/peteroupc/CBORPeter OccilA C# implementation of Concise Binary Object Representation (CBOR), a general-purpose binary data format defined in RFC 7049.Peter OccilCBOR (Concise Binary Object Representation)cbor data serialization binary json +- Fix issue with unexpected CBORObject#ToString result for True and False.CC0-1.0https://github.com/peteroupc/CBORPeter OccilA C# implementation of Concise Binary Object Representation (CBOR), a general-purpose binary data format defined in RFC 7049.Peter OccilCBOR (Concise Binary Object Representation)cbor data serialization binary json \ No newline at end of file diff --git a/CBOR/CBOR.csproj b/CBOR/CBOR.csproj index a8aa5d54..70b3c4dc 100644 --- a/CBOR/CBOR.csproj +++ b/CBOR/CBOR.csproj @@ -3,7 +3,7 @@ netstandard1.0 True - 4.0.0 + 4.0.1 Peter Occil A C# implementation of Concise Binary Object Representation (CBOR), a general-purpose binary data format defined in RFC 7049. A C# implementation of Concise Binary Object Representation (CBOR), a general-purpose binary data format defined in RFC 7049. @@ -13,10 +13,9 @@ CC0-1.0 https://github.com/peteroupc/CBOR -Version 4.0.0: +Version 4.0.1: -- Fix issues with CTAP2 Canonical CBOR form -- Support field serialization and deserialization in ToObject and FromObject +- Fix issue with unexpected CBORObject#ToString result for True and False. cbor data serialization binary json @@ -62,7 +61,4 @@ Version 4.0.0: - - - diff --git a/CBOR/PeterO/Cbor/CBORObject.cs b/CBOR/PeterO/Cbor/CBORObject.cs index 2fc6bc1d..fd054e88 100644 --- a/CBOR/PeterO/Cbor/CBORObject.cs +++ b/CBOR/PeterO/Cbor/CBORObject.cs @@ -3463,9 +3463,9 @@ public int AsInt32Value() { /// CBORObject obj = CBORObject.FromInt64(99999); /// if (obj.Type == /// CBORType.Integer && obj.CanValueFitInInt64()) { - /// // Not an Int64; handle the error - /// Console.WriteLine("Not a 64-bit integer."); } else { - /// Console.WriteLine("The value is " + obj.AsInt64Value()); } + /// /* Not an Int64; handle the error*/ + /// Console.WriteLine("Not a 64-bit integer."); } else { + /// Console.WriteLine("The value is " + obj.AsInt64Value()); } /// . /// public long AsInt64Value() { @@ -5467,7 +5467,7 @@ public static int WriteValue( /// CBORObject.WriteValue(stream, 4, 3); /// /* item 1 */ /// CBORObject.Write("hello world", stream); - /// CBORObject.Write(25, stream); // item 2 + /// CBORObject.Write(25, stream); /* item 2*/ /// CBORObject.Write(false, stream); /* item 3*/ /// In the following example, a map consisting of two key-value /// pairs is written as CBOR to a data stream. diff --git a/CBOR/docs.xml b/CBOR/docs.xml index 00e536b9..03c3605c 100644 --- a/CBOR/docs.xml +++ b/CBOR/docs.xml @@ -181,7 +181,8 @@ according to the FIDO Client-to-Authenticator Protocol 2 specification. true if CBOR objects are written out using the CTAP2 - canonical CBOR encoding form; otherwise, false. The default is false. + canonical CBOR encoding form; otherwise, false. The default + is false. @@ -876,9 +877,10 @@ The following example code (originally written in C# for the.NET Framework) shows a way to check whether a given CBOR object stores a 32-bit signed integer before getting its value. - CBORObject obj = CBORObject.FromInt32(99999); if (obj.IsIntegral - && obj.CanTruncatedIntFitInInt32()) { /* Not an Int32; handle*/ - the error Console.WriteLine("Not a 32-bit integer."); } else { + CBORObject obj = CBORObject.FromInt32(99999); + if (obj.IsIntegral && obj.CanTruncatedIntFitInInt32()) { + /* Not an Int32; handle the error */ + Console.WriteLine("Not a 32-bit integer."); } else { Console.WriteLine("The value is " + obj.AsInt32()); } . @@ -941,10 +943,12 @@ The following example code (originally written in C# for the.NET Framework) shows a way to check whether a given CBOR object stores a 64-bit signed integer before getting its value. - CBORObject obj = CBORObject.FromInt64(99999); if (obj.Type == - CBORType.Integer && obj.CanValueFitInInt64()) { /* Not an Int64; - handle the error */ Console.WriteLine("Not a 64-bit integer."); } else { - Console.WriteLine("The value is " + obj.AsInt64Value()); } . + CBORObject obj = CBORObject.FromInt64(99999); + if (obj.Type == + CBORType.Integer && obj.CanValueFitInInt64()) { + /* Not an Int64; handle the error*/ + Console.WriteLine("Not a 64-bit integer."); } else { + Console.WriteLine("The value is " + obj.AsInt64Value()); } . @@ -3591,7 +3595,7 @@ The following example (written in C# for the.NET version) shows how to use the LimitedMemoryStream class (implemented in LimitedMemoryStream.cs - in the peteroupc/CBOR open-source + in the peteroupc/CBOR open-source repository) to limit the size of supported JSON serializations of CBOR objects. /* maximum supported JSON size in bytes*/ @@ -3673,7 +3677,8 @@ out certain keys of a CBOR map in a given order. In the case of CBOR objects of type FloatingPoint, the number is written using the shortest floating-point encoding possible; this is a change from - previous versions. + previous versions. + A writable data stream. The parameter is null. An I/O error @@ -3726,7 +3731,7 @@ outputStream.WriteByte((byte)0xff); } The following example (written in C# for the.NET version) shows how to use the LimitedMemoryStream class (implemented in LimitedMemoryStream.cs - in the peteroupc/CBOR open-source + in the peteroupc/CBOR open-source repository) to limit the size of supported CBOR serializations. /* maximum supported CBOR size in bytes*/ @@ -3862,13 +3867,17 @@ The parameter is null. In the following example, an array of three objects is written as CBOR to a data stream. - CBORObject.WriteValue(stream, 4, 3); /* array, length 3*/ - CBORObject.Write("hello world", stream); /* item 1 CBORObject.Write(25,*/ - stream); /* item 2 */ CBORObject.Write(false, stream); /* item 3*/ In the following example, a map consisting of two key-value + /* array, length 3*/ + CBORObject.WriteValue(stream, 4, 3); + /* item 1 */ + CBORObject.Write("hello world", stream); + CBORObject.Write(25, stream); /* item 2*/ + CBORObject.Write(false, stream); /* item 3*/ In the following example, a map consisting of two key-value pairs is written as CBOR to a data stream. CBORObject.WriteValue(stream, 5, 2); /* map, 2 pairs*/ - CBORObject.Write("number", stream); /* key 1 CBORObject.Write(25,*/ - stream); /* value 1 CBORObject.Write("string", stream); /* key 2*/*/ + CBORObject.Write("number", stream); /* key 1 */ + CBORObject.Write(25, stream); /* value 1 */ + CBORObject.Write("string", stream); /* key 2*/ CBORObject.Write("hello", stream); /* value 2*/ In the following example (originally written in C# for the.NET Framework version), a text string is written as CBOR to a data stream. @@ -4638,35 +4647,45 @@ -The rules only check for the appropriate delimiters when + + The rules only check for the appropriate delimiters when splitting the path, without checking if all the characters in each component are valid. Even with this mode, strings with unpaired surrogate code points are considered invalid. + -The rules follow the syntax for parsing IRIs. In + + The rules follow the syntax for parsing IRIs. In particular, many code points outside the Basic Latin range (U+0000 to U+007F) are allowed. Strings with unpaired surrogate code points are considered invalid. + -The rules only check for the appropriate delimiters when + + The rules only check for the appropriate delimiters when splitting the path, without checking if all the characters in each component are valid. Unpaired surrogate code points are treated as though they were replacement characters instead for the purposes of these rules, so that strings with those code points are not considered invalid strings. + -The rules only check for the appropriate delimiters when + + The rules only check for the appropriate delimiters when splitting the path, without checking if all the characters in each component are valid. Code points outside the Basic Latin range (U+0000 to U+007F) are not allowed. + -The rules follow the syntax for parsing IRIs, except that + + The rules follow the syntax for parsing IRIs, except that code points outside the Basic Latin range (U+0000 to U+007F) are not allowed. + Decodes percent-encoding (of the form "%XX" where X is a hexadecimal diff --git a/CBOR20/Properties/AssemblyInfo.cs b/CBOR20/Properties/AssemblyInfo.cs index 63576512..f38c6d1a 100644 --- a/CBOR20/Properties/AssemblyInfo.cs +++ b/CBOR20/Properties/AssemblyInfo.cs @@ -1,8 +1,8 @@ using System.Reflection; [assembly: System.CLSCompliant(true)] -[assembly: AssemblyInformationalVersion("4.0.0")] -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: AssemblyInformationalVersion("4.0.1")] +[assembly: AssemblyVersion("4.0.1.0")] +[assembly: AssemblyFileVersion("4.0.1.0")] [assembly: AssemblyProduct("CBOR (Concise Binary Object Representati" + "on)")] [assembly: AssemblyTitle("CBOR (Concise Binary Object Representati" + diff --git a/CBOR40/Properties/AssemblyInfo.cs b/CBOR40/Properties/AssemblyInfo.cs index 63576512..f38c6d1a 100644 --- a/CBOR40/Properties/AssemblyInfo.cs +++ b/CBOR40/Properties/AssemblyInfo.cs @@ -1,8 +1,8 @@ using System.Reflection; [assembly: System.CLSCompliant(true)] -[assembly: AssemblyInformationalVersion("4.0.0")] -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: AssemblyInformationalVersion("4.0.1")] +[assembly: AssemblyVersion("4.0.1.0")] +[assembly: AssemblyFileVersion("4.0.1.0")] [assembly: AssemblyProduct("CBOR (Concise Binary Object Representati" + "on)")] [assembly: AssemblyTitle("CBOR (Concise Binary Object Representati" + diff --git a/CBORDocs/DocVisitor.cs b/CBORDocs/DocVisitor.cs index 164c3ac1..f4aaf1b2 100644 --- a/CBORDocs/DocVisitor.cs +++ b/CBORDocs/DocVisitor.cs @@ -492,7 +492,7 @@ public void VisitNode(INode node) { var t = node.GetContent(); // Collapse multiple spaces into a single space t = Regex.Replace(t, @"\s+", " "); - if (t.Length!=1 || t[0]!=' ') { + if (t.Length != 1 || t[0] != ' ') { // Don't write if result is a single space this.Write(t); } diff --git a/CBORTest/CBORExtraTest.cs b/CBORTest/CBORExtraTest.cs index 69998c73..5be705a1 100644 --- a/CBORTest/CBORExtraTest.cs +++ b/CBORTest/CBORExtraTest.cs @@ -382,14 +382,13 @@ from i in RangeExclusive(0, 10) CBORTestCommon.AssertRoundTrip(obj); // Select all even numbers var query2 = - from i in RangeExclusive(0, 10) - where i % 2 == 0 - select new { A = i, B = i + 1 }; +from i in RangeExclusive(0, 10) + where i % 2 == 0 select new { A = i, B = i + 1 }; obj = CBORObject.FromObject(query2); Assert.AreEqual(5, obj.Count); Assert.AreEqual(0, obj[0]["a"].AsInt32()); Assert.AreEqual(3, obj[1]["b"].AsInt32()); - CBORTestCommon.AssertRoundTrip(obj); + CBORTestCommon.AssertRoundTrip(obj); #endif } diff --git a/CBORTest/CBORObjectTest.cs b/CBORTest/CBORObjectTest.cs index dc41ffdc..ebbf507a 100644 --- a/CBORTest/CBORObjectTest.cs +++ b/CBORTest/CBORObjectTest.cs @@ -5703,17 +5703,17 @@ public void TestToString() { stringTemp); } CBORObject cbor = CBORObject.True; - Assert.AreNotEqual("21", cbor.ToString()); - Assert.AreNotEqual("simple(21)", cbor.ToString()); + TestCommon.AssertNotEqual("21", cbor.ToString()); + TestCommon.AssertNotEqual("simple(21)", cbor.ToString()); cbor = CBORObject.False; - Assert.AreNotEqual("20", cbor.ToString()); - Assert.AreNotEqual("simple(20)", cbor.ToString()); + TestCommon.AssertNotEqual("20", cbor.ToString()); + TestCommon.AssertNotEqual("simple(20)", cbor.ToString()); cbor = CBORObject.Null; - Assert.AreNotEqual("22", cbor.ToString()); - Assert.AreNotEqual("simple(22)", cbor.ToString()); + TestCommon.AssertNotEqual("22", cbor.ToString()); + TestCommon.AssertNotEqual("simple(22)", cbor.ToString()); cbor = CBORObject.Undefined; - Assert.AreNotEqual("23", cbor.ToString()); - Assert.AreNotEqual("simple(23)", cbor.ToString()); + TestCommon.AssertNotEqual("23", cbor.ToString()); + TestCommon.AssertNotEqual("simple(23)", cbor.ToString()); { string stringTemp = CBORObject.FromSimpleValue(50).ToString(); Assert.AreEqual( @@ -5725,13 +5725,13 @@ public void TestToString() { [Test] public void TestSimpleValuesNotIntegers() { CBORObject cbor = CBORObject.True; - Assert.AreNotEqual(CBORObject.FromObject(21), cbor); + TestCommon.AssertNotEqual(CBORObject.FromObject(21), cbor); cbor = CBORObject.False; - Assert.AreNotEqual(CBORObject.FromObject(20), cbor); + TestCommon.AssertNotEqual(CBORObject.FromObject(20), cbor); cbor = CBORObject.Null; - Assert.AreNotEqual(CBORObject.FromObject(22), cbor); + TestCommon.AssertNotEqual(CBORObject.FromObject(22), cbor); cbor = CBORObject.Undefined; - Assert.AreNotEqual(CBORObject.FromObject(23), cbor); + TestCommon.AssertNotEqual(CBORObject.FromObject(23), cbor); } [Test] diff --git a/CBORTest/CBORTest.cs b/CBORTest/CBORTest.cs index fbbf33a4..e58e4e29 100644 --- a/CBORTest/CBORTest.cs +++ b/CBORTest/CBORTest.cs @@ -1451,7 +1451,7 @@ public static CBORObject ReferenceTestObject() { } [Test] - [Timeout(2000)] + [Timeout(5000)] public void TestNoRecursiveExpansion() { CBORObject root = ReferenceTestObject(); byte[] bytes = root.EncodeToBytes(); diff --git a/CBORTest/TestCommon.cs b/CBORTest/TestCommon.cs index 66d05033..83f81cd3 100644 --- a/CBORTest/TestCommon.cs +++ b/CBORTest/TestCommon.cs @@ -104,6 +104,41 @@ public static void AssertByteArraysEqual(byte[] arr1, byte[] arr2) { } } + public static void AssertNotEqual(object o, object o2, string msg) { + if (o == null) { + throw new ArgumentNullException(nameof(o)); + } + if (o.Equals(o2)) { + string str = msg + "\r\n" + ObjectMessages( + o, + o2, + "Unexpectedly equal"); + Assert.Fail(str); + } + } + + public static void AssertEquals(object o, object o2, string msg) { + if (o == null) { + throw new ArgumentNullException(nameof(o)); + } + if (!o.Equals(o2)) { + Assert.AreEqual(o, o2, msg); + } + } + + public static void AssertNotEqual(Object o, Object o2) { + if (o == null) { + throw new ArgumentNullException(nameof(o)); + } + if (o.Equals(o2)) { + string str = ObjectMessages( + o, + o2, + "Unexpectedly equal"); + Assert.Fail(str); + } + } + public static void AssertEquals(Object o, Object o2) { if (o == null) { throw new ArgumentNullException(nameof(o)); @@ -179,6 +214,27 @@ public static void CompareTestConsistency(T o1, T o2, T o3) where T : Assert.AreEqual(cmp3 == 0, o3.Equals(o1)); } + public static void CompareTestNotEqual(T o1, T o2) where T : + IComparable { + if (CompareTestReciprocal(o1, o2) == 0) { + Assert.Fail(ObjectMessages( + o1, + o2, + "Unexpectedly equal: " + CompareTestReciprocal(o1, o2))); + } + } + + public static void CompareTestNotEqual(T o1, T o2, string msg) where T : + IComparable { + if (CompareTestReciprocal(o1, o2) == 0) { + string str = msg + "\r\n" + ObjectMessages( + o1, + o2, + "Unexpectedly equal: " + CompareTestReciprocal(o1, o2)); + Assert.Fail(str); + } + } + public static void CompareTestEqual(T o1, T o2) where T : IComparable { if (CompareTestReciprocal(o1, o2) != 0) { diff --git a/History.md b/History.md index 9ea6e458..a86037fb 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,10 @@ Release notes --------------------- +### Version 4.0.1: + +- Fix issue with unexpected CBORObject#ToString result for True and False. + ### Version 4.0.0: - Fix issues with CTAP2 Canonical CBOR form diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 63576512..f38c6d1a 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -1,8 +1,8 @@ using System.Reflection; [assembly: System.CLSCompliant(true)] -[assembly: AssemblyInformationalVersion("4.0.0")] -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: AssemblyInformationalVersion("4.0.1")] +[assembly: AssemblyVersion("4.0.1.0")] +[assembly: AssemblyFileVersion("4.0.1.0")] [assembly: AssemblyProduct("CBOR (Concise Binary Object Representati" + "on)")] [assembly: AssemblyTitle("CBOR (Concise Binary Object Representati" + diff --git a/docs/PeterO.Cbor.CBORObject.md b/docs/PeterO.Cbor.CBORObject.md index 497adc70..b21e390d 100644 --- a/docs/PeterO.Cbor.CBORObject.md +++ b/docs/PeterO.Cbor.CBORObject.md @@ -902,9 +902,10 @@ Converts this object to a 32-bit signed integer. Non-integer number values are t The following example code (originally written in C# for the.NET Framework) shows a way to check whether a given CBOR object stores a 32-bit signed integer before getting its value. - CBORObject obj = CBORObject.FromInt32(99999); if (obj.IsIntegral - && obj.CanTruncatedIntFitInInt32()) { /* Not an Int32; handle*/ - the error Console.WriteLine("Not a 32-bit integer."); } else { + CBORObject obj = CBORObject.FromInt32(99999); + if (obj.IsIntegral && obj.CanTruncatedIntFitInInt32()) { + /* Not an Int32; handle the error */ + Console.WriteLine("Not a 32-bit integer."); } else { Console.WriteLine("The value is " + obj.AsInt32()); } . @@ -986,9 +987,11 @@ Converts this object to a 64-bit signed integer if this CBOR object's type is In The following example code (originally written in C# for the.NET Framework) shows a way to check whether a given CBOR object stores a 64-bit signed integer before getting its value. - CBORObject obj = CBORObject.FromInt64(99999); if (obj.Type == - CBORType.Integer && obj.CanValueFitInInt64()) { /* Not an Int64; - handle the error */ Console.WriteLine("Not a 64-bit integer."); } else { + CBORObject obj = CBORObject.FromInt64(99999); + if (obj.Type == + CBORType.Integer && obj.CanValueFitInInt64()) { + /* Not an Int64; handle the error*/ + Console.WriteLine("Not a 64-bit integer."); } else { Console.WriteLine("The value is " + obj.AsInt64Value()); } . @@ -4449,15 +4452,19 @@ Writes a CBOR major type number and an integer 0 or greater associated with it t In the following example, an array of three objects is written as CBOR to a data stream. - CBORObject.WriteValue(stream, 4, 3); /* array, length 3*/ - CBORObject.Write("hello world", stream); /* item 1 CBORObject.Write(25,*/ - stream); /* item 2 */ CBORObject.Write(false, stream); /* item 3*/ + /* array, length 3*/ + CBORObject.WriteValue(stream, 4, 3); + /* item 1 */ + CBORObject.Write("hello world", stream); + CBORObject.Write(25, stream); /* item 2*/ + CBORObject.Write(false, stream); /* item 3*/ In the following example, a map consisting of two key-value pairs is written as CBOR to a data stream. CBORObject.WriteValue(stream, 5, 2); /* map, 2 pairs*/ - CBORObject.Write("number", stream); /* key 1 CBORObject.Write(25,*/ - stream); /* value 1 CBORObject.Write("string", stream); // key 2*/ + CBORObject.Write("number", stream); /* key 1 */ + CBORObject.Write(25, stream); /* value 1 */ + CBORObject.Write("string", stream); /* key 2*/ CBORObject.Write("hello", stream); /* value 2*/ In the following example (originally written in C# for the.NET Framework version), a text string is written as CBOR to a data stream.