public CBORObject ToCBORObject(Uri uri) { if (uri == null) { throw new ArgumentNullException(nameof(uri)); } string uriString = uri.ToString(); var nonascii = false; for (var i = 0; i < uriString.Length; ++i) { nonascii |= uriString[i] >= 0x80; } int tag = nonascii ? 266 : 32; if (!URIUtility.HasScheme(uriString)) { tag = 267; } return(CBORObject.FromObjectAndTag(uriString, (int)tag)); }
/// <summary>Internal API.</summary> /// <param name='obj'>The parameter <paramref name='obj'/> is an /// internal parameter.</param> /// <returns>A CBORObject object.</returns> public CBORObject ToCBORObject(Guid obj) { byte[] bytes = PropertyMap.UUIDToBytes(obj); return(CBORObject.FromObjectAndTag(bytes, (int)37)); }
public CBORObject ReadForFirstByte(int firstbyte) { if (this.depth > 500) { throw new CBORException("Too deeply nested"); } if (firstbyte < 0) { throw new CBORException("Premature end of data"); } if (firstbyte == 0xff) { throw new CBORException("Unexpected break code encountered"); } int type = (firstbyte >> 5) & 0x07; int additional = firstbyte & 0x1f; long uadditional; CBORObject fixedObject; if (this.options.Ctap2Canonical) { if (additional >= 0x1c) { // NOTE: Includes stop byte and indefinite length data items throw new CBORException("Invalid canonical CBOR encountered"); } // Check if this represents a fixed object (NOTE: All fixed objects // comply with CTAP2 canonical CBOR). fixedObject = CBORObject.GetFixedObject(firstbyte); if (fixedObject != null) { return(fixedObject); } if (type == 6) { throw new CBORException("Tags not allowed in canonical CBOR"); } uadditional = ReadDataLength( this.stream, firstbyte, type, type == 7); if (type == 0) { return((uadditional >> 63) != 0 ? CBORObject.FromObject(ToUnsignedEInteger(uadditional)) : CBORObject.FromObject(uadditional)); } else if (type == 1) { return((uadditional >> 63) != 0 ? CBORObject.FromObject( ToUnsignedEInteger(uadditional).Add(1).Negate()) : CBORObject.FromObject((-uadditional) - 1L)); } else if (type == 7) { if (additional < 24) { return(CBORObject.FromSimpleValue(additional)); } else if (additional == 24 && uadditional < 32) { throw new CBORException("Invalid simple value encoding"); } else if (additional == 24) { return(CBORObject.FromSimpleValue((int)uadditional)); } else if (additional == 25) { return(CBORObject.FromFloatingPointBits(uadditional, 2)); } else if (additional == 26) { return(CBORObject.FromFloatingPointBits(uadditional, 4)); } else if (additional == 27) { return(CBORObject.FromFloatingPointBits(uadditional, 8)); } } else if (type >= 2 && type <= 5) { return(this.ReadStringArrayMap(type, uadditional)); } throw new CBORException("Unexpected data encountered"); } int expectedLength = CBORObject.GetExpectedLength(firstbyte); // Data checks if (expectedLength == -1) { // if the head byte is invalid throw new CBORException("Unexpected data encountered"); } // Check if this represents a fixed object fixedObject = CBORObject.GetFixedObject(firstbyte); if (fixedObject != null) { return(fixedObject); } // Read fixed-length data byte[] data = null; if (expectedLength != 0) { data = new byte[expectedLength]; // include the first byte because GetFixedLengthObject // will assume it exists for some head bytes data[0] = unchecked ((byte)firstbyte); if (expectedLength > 1 && this.stream.Read(data, 1, expectedLength - 1) != expectedLength - 1) { throw new CBORException("Premature end of data"); } CBORObject cbor = CBORObject.GetFixedLengthObject(firstbyte, data); if (this.stringRefs != null && (type == 2 || type == 3)) { this.stringRefs.AddStringIfNeeded(cbor, expectedLength - 1); } return(cbor); } if (additional == 31) { // Indefinite-length for major types 2 to 5 (other major // types were already handled in the call to // GetFixedLengthObject). switch (type) { case 2: { // Streaming byte string using (var ms = new MemoryStream()) { // Requires same type as this one while (true) { int nextByte = this.stream.ReadByte(); if (nextByte == 0xff) { // break if the "break" code was read break; } long len = ReadDataLength(this.stream, nextByte, 2); if ((len >> 63) != 0 || len > Int32.MaxValue) { throw new CBORException("Length" + ToUnsignedEInteger(len) + " is bigger than supported "); } if (nextByte != 0x40) { // NOTE: 0x40 means the empty byte string ReadByteData(this.stream, len, ms); } } if (ms.Position > Int32.MaxValue) { throw new CBORException("Length of bytes to be streamed is bigger" + "\u0020than supported "); } data = ms.ToArray(); return(CBORObject.FromRaw(data)); } } case 3: { // Streaming text string var builder = new StringBuilder(); while (true) { int nextByte = this.stream.ReadByte(); if (nextByte == 0xff) { // break if the "break" code was read break; } long len = ReadDataLength(this.stream, nextByte, 3); if ((len >> 63) != 0 || len > Int32.MaxValue) { throw new CBORException("Length" + ToUnsignedEInteger(len) + " is bigger than supported"); } if (nextByte != 0x60) { // NOTE: 0x60 means the empty string if (PropertyMap.ExceedsKnownLength(this.stream, len)) { throw new CBORException("Premature end of data"); } switch ( DataUtilities.ReadUtf8( this.stream, (int)len, builder, false)) { case -1: throw new CBORException("Invalid UTF-8"); case -2: throw new CBORException("Premature end of data"); } } } return(CBORObject.FromRaw(builder.ToString())); } case 4: { CBORObject cbor = CBORObject.NewArray(); var vtindex = 0; // Indefinite-length array while (true) { int headByte = this.stream.ReadByte(); if (headByte < 0) { throw new CBORException("Premature end of data"); } if (headByte == 0xff) { // Break code was read break; } ++this.depth; CBORObject o = this.ReadForFirstByte( headByte); --this.depth; cbor.Add(o); ++vtindex; } return(cbor); } case 5: { CBORObject cbor = CBORObject.NewMap(); // Indefinite-length map while (true) { int headByte = this.stream.ReadByte(); if (headByte < 0) { throw new CBORException("Premature end of data"); } if (headByte == 0xff) { // Break code was read break; } ++this.depth; CBORObject key = this.ReadForFirstByte(headByte); CBORObject value = this.ReadInternal(); --this.depth; int oldCount = cbor.Count; cbor[key] = value; int newCount = cbor.Count; if (!this.options.AllowDuplicateKeys && oldCount == newCount) { throw new CBORException("Duplicate key already exists"); } } return(cbor); } default: throw new CBORException("Unexpected data encountered"); } } EInteger bigintAdditional = EInteger.Zero; uadditional = ReadDataLength(this.stream, firstbyte, type); // The following doesn't check for major types 0 and 1, // since all of them are fixed-length types and are // handled in the call to GetFixedLengthObject. if (type >= 2 && type <= 5) { return(this.ReadStringArrayMap(type, uadditional)); } if (type == 6) // Tagged item { var haveFirstByte = false; var newFirstByte = -1; if (this.options.ResolveReferences && (uadditional >> 32) == 0) { // NOTE: HandleItemTag treats only certain tags up to 256 specially this.HandleItemTag(uadditional); } ++this.depth; CBORObject o = haveFirstByte ? this.ReadForFirstByte( newFirstByte) : this.ReadInternal(); --this.depth; if ((uadditional >> 63) != 0) { return(CBORObject.FromObjectAndTag(o, ToUnsignedEInteger(uadditional))); } if (uadditional < 65536) { if (this.options.ResolveReferences) { int uaddl = uadditional >= 257 ? 257 : (uadditional < 0 ? 0 : (int)uadditional); switch (uaddl) { case 256: // string tag this.stringRefs.Pop(); break; case 25: // stringref tag if (o.IsTagged || o.Type != CBORType.Integer) { throw new CBORException("stringref must be an unsigned" + "\u0020integer"); } return(this.stringRefs.GetString(o.AsEIntegerValue())); } } return(CBORObject.FromObjectAndTag( o, (int)uadditional)); } return(CBORObject.FromObjectAndTag( o, (EInteger)uadditional)); } throw new CBORException("Unexpected data encountered"); }
/// <summary>Converts a date/time in the form of a year, month, day, /// hour, minute, second, fractional seconds, and time offset to a CBOR /// object.</summary> /// <param name='bigYear'>The parameter <paramref name='bigYear'/> is a /// Numbers.EInteger object.</param> /// <param name='lesserFields'>An array that will store the fields /// (other than the year) of the date and time. See the /// TryGetDateTimeFields method for information on the "lesserFields" /// parameter.</param> /// <returns>A CBOR object encoding the given date fields according to /// the conversion type used to create this date converter.</returns> /// <exception cref='ArgumentNullException'>The parameter <paramref /// name='bigYear'/> or <paramref name='lesserFields'/> is /// null.</exception> /// <exception cref='PeterO.Cbor2.CBORException'>An error occurred in /// conversion.</exception> public CBORObject DateTimeFieldsToCBORObject(EInteger bigYear, int[] lesserFields) { // TODO: In next minor version, add overload that takes int rather than // EInteger if (bigYear == null) { throw new ArgumentNullException(nameof(bigYear)); } if (lesserFields == null) { throw new ArgumentNullException(nameof(lesserFields)); } // TODO: Make into CBORException in next major version if (lesserFields.Length < 7) { throw new ArgumentException("\"lesserFields\" + \"'s length\" (" + lesserFields.Length + ") is not greater or equal to 7"); } try { CBORUtilities.CheckYearAndLesserFields(bigYear, lesserFields); switch (this.convType) { case ConversionType.TaggedString: { string str = CBORUtilities.ToAtomDateTimeString(bigYear, lesserFields); return(CBORObject.FromObjectAndTag(str, 0)); } case ConversionType.TaggedNumber: case ConversionType.UntaggedNumber: try { var status = new int[1]; EFloat ef = CBORUtilities.DateTimeToIntegerOrDouble( bigYear, lesserFields, status); if (status[0] == 0) { return(this.convType == ConversionType.TaggedNumber ? CBORObject.FromObjectAndTag(ef.ToEInteger(), 1) : CBORObject.FromObject(ef.ToEInteger())); } else if (status[0] == 1) { return(this.convType == ConversionType.TaggedNumber ? CBORObject.FromFloatingPointBits(ef.ToDoubleBits(), 8).WithTag(1) : CBORObject.FromFloatingPointBits(ef.ToDoubleBits(), 8)); } else { throw new CBORException("Too big or small to fit an integer" + "\u0020or" + "\u0020floating-point number"); } } catch (ArgumentException ex) { throw new CBORException(ex.Message, ex); } default: throw new CBORException("Internal error"); } } catch (ArgumentException ex) { throw new CBORException(ex.Message, ex); } }