示例#1
0
        private static CBORObject ResolveSharedRefs(
            CBORObject obj,
            SharedRefs sharedRefs)
        {
            if (obj == null)
            {
                return(null);
            }
            CBORType type   = obj.Type;
            bool     hasTag = obj.HasMostOuterTag(29);

            if (hasTag)
            {
                CBORObject untagged = obj.UntagOne();
                if (untagged.IsTagged ||
                    untagged.Type != CBORType.Integer ||
                    untagged.AsNumber().IsNegative())
                {
                    throw new CBORException(
                              "Shared ref index must be an untagged integer 0 or greater");
                }
                return(sharedRefs.GetObject(untagged.AsEIntegerValue()));
            }
            hasTag = obj.HasMostOuterTag(28);
            if (hasTag)
            {
                obj = obj.UntagOne();
                sharedRefs.AddObject(obj);
            }
            if (type == CBORType.Map)
            {
                foreach (CBORObject key in obj.Keys)
                {
                    CBORObject value    = obj[key];
                    CBORObject newvalue = ResolveSharedRefs(value, sharedRefs);
                    if (value != newvalue)
                    {
                        obj[key] = newvalue;
                    }
                }
            }
            else if (type == CBORType.Array)
            {
                for (var i = 0; i < obj.Count; ++i)
                {
                    obj[i] = ResolveSharedRefs(obj[i], sharedRefs);
                }
            }
            return(obj);
        }
示例#2
0
        internal static string ToStringHelper(CBORObject obj, int depth)
        {
            StringBuilder sb       = null;
            string        simvalue = null;
            CBORType      type     = obj.Type;
            CBORObject    curobject;

            if (obj.IsTagged)
            {
                if (sb == null)
                {
                    if (type == CBORType.TextString)
                    {
                        // The default capacity of StringBuilder may be too small
                        // for many strings, so set a suggested capacity
                        // explicitly
                        string str = obj.AsString();
                        sb = new StringBuilder(Math.Min(str.Length, 4096) + 16);
                    }
                    else
                    {
                        sb = new StringBuilder();
                    }
                }
                // Append opening tags if needed
                curobject = obj;
                while (curobject.IsTagged)
                {
                    EInteger ei = curobject.MostOuterTag;
                    sb.Append(ei.ToString());
                    sb.Append('(');
                    curobject = curobject.UntagOne();
                }
            }
            switch (type)
            {
            case CBORType.SimpleValue:
                sb = sb ?? new StringBuilder();
                if (obj.IsUndefined)
                {
                    sb.Append("undefined");
                }
                else if (obj.IsNull)
                {
                    sb.Append("null");
                }
                else
                {
                    sb.Append("simple(");
                    int  thisItemInt = obj.SimpleValue;
                    char c;
                    if (thisItemInt >= 100)
                    {
                        // NOTE: '0'-'9' have ASCII code 0x30-0x39
                        c = (char)(0x30 + ((thisItemInt / 100) % 10));
                        sb.Append(c);
                    }
                    if (thisItemInt >= 10)
                    {
                        c = (char)(0x30 + ((thisItemInt / 10) % 10));
                        sb.Append(c);
                        c = (char)(0x30 + (thisItemInt % 10));
                    }
                    else
                    {
                        c = (char)(0x30 + thisItemInt);
                    }
                    sb.Append(c);
                    sb.Append(")");
                }
                break;

            case CBORType.Boolean:
            case CBORType.Integer:
                simvalue = obj.Untag().ToJSONString();
                if (sb == null)
                {
                    return(simvalue);
                }
                sb.Append(simvalue);
                break;

            case CBORType.FloatingPoint: {
                double f = obj.AsDoubleValue();
                simvalue = Double.IsNegativeInfinity(f) ? "-Infinity" :
                           (Double.IsPositiveInfinity(f) ? "Infinity" : (Double.IsNaN(f) ?

                                                                         "NaN" : obj.Untag().ToJSONString()));
                if (sb == null)
                {
                    return(simvalue);
                }
                sb.Append(simvalue);
                break;
            }

            case CBORType.ByteString: {
                sb = sb ?? new StringBuilder();
                sb.Append("h'");
                byte[] data   = obj.GetByteString();
                int    length = data.Length;
                for (var i = 0; i < length; ++i)
                {
                    sb.Append(HexAlphabet[(data[i] >> 4) & 15]);
                    sb.Append(HexAlphabet[data[i] & 15]);
                }
                sb.Append("'");
                break;
            }

            case CBORType.TextString: {
                if (sb == null)
                {
                    return("\"" + obj.AsString() + "\"");
                }
                sb.Append('\"');
                sb.Append(obj.AsString());
                sb.Append('\"');
                break;
            }

            case CBORType.Array: {
                sb = sb ?? new StringBuilder();
                var first = true;
                sb.Append("[");
                if (depth >= 50)
                {
                    sb.Append("...");
                }
                else
                {
                    for (var i = 0; i < obj.Count; ++i)
                    {
                        if (!first)
                        {
                            sb.Append(", ");
                        }
                        sb.Append(ToStringHelper(obj[i], depth + 1));
                        first = false;
                    }
                }
                sb.Append("]");
                break;
            }

            case CBORType.Map: {
                sb = sb ?? new StringBuilder();
                var first = true;
                sb.Append("{");
                if (depth >= 50)
                {
                    sb.Append("...");
                }
                else
                {
                    ICollection <KeyValuePair <CBORObject, CBORObject> > entries =
                        obj.Entries;
                    foreach (KeyValuePair <CBORObject, CBORObject> entry
                             in entries)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        if (!first)
                        {
                            sb.Append(", ");
                        }
                        sb.Append(ToStringHelper(key, depth + 1));
                        sb.Append(": ");
                        sb.Append(ToStringHelper(value, depth + 1));
                        first = false;
                    }
                }
                sb.Append("}");
                break;
            }

            default: {
                sb = sb ?? new StringBuilder();
                sb.Append("???");
                break;
            }
            }
            // Append closing tags if needed
            curobject = obj;
            while (curobject.IsTagged)
            {
                sb.Append(')');
                curobject = curobject.UntagOne();
            }
            return(sb.ToString());
        }
示例#3
0
        private static byte[] CtapCanonicalEncode(CBORObject a, int depth)
        {
            CBORObject cbor       = a.Untag();
            CBORType   valueAType = cbor.Type;

            try {
                if (valueAType == CBORType.Array)
                {
                    using (var ms = new MemoryStream()) {
                        CBORObject.WriteValue(ms, 4, cbor.Count);
                        for (var i = 0; i < cbor.Count; ++i)
                        {
                            if (depth >= 3 && IsArrayOrMap(cbor[i]))
                            {
                                throw new CBORException("Nesting level too deep");
                            }
                            byte[] bytes = CtapCanonicalEncode(cbor[i], depth + 1);
                            ms.Write(bytes, 0, bytes.Length);
                        }
                        return(ms.ToArray());
                    }
                }
                else if (valueAType == CBORType.Map)
                {
                    KeyValuePair <byte[], byte[]>         kv1;
                    List <KeyValuePair <byte[], byte[]> > sortedKeys;
                    sortedKeys = new List <KeyValuePair <byte[], byte[]> >();
                    foreach (CBORObject key in cbor.Keys)
                    {
                        if (depth >= 3 && (IsArrayOrMap(key) ||
                                           IsArrayOrMap(cbor[key])))
                        {
                            throw new CBORException("Nesting level too deep");
                        }
                        CheckDepth(key, depth + 1);
                        CheckDepth(cbor[key], depth + 1);
                        // Check if key and value can be canonically encoded
                        // (will throw an exception if they cannot)
                        kv1 = new KeyValuePair <byte[], byte[]>(
                            CtapCanonicalEncode(key, depth + 1),
                            CtapCanonicalEncode(cbor[key], depth + 1));
                        sortedKeys.Add(kv1);
                    }
                    sortedKeys.Sort(ByteComparer);
                    using (var ms = new MemoryStream()) {
                        CBORObject.WriteValue(ms, 5, cbor.Count);
                        byte[] lastKey = null;
                        for (var i = 0; i < sortedKeys.Count; ++i)
                        {
                            kv1 = sortedKeys[i];
                            byte[] bytes = kv1.Key;
                            if (lastKey != null && ByteArraysEqual(bytes, lastKey))
                            {
                                throw new CBORException("duplicate canonical CBOR key");
                            }
                            lastKey = bytes;
                            ms.Write(bytes, 0, bytes.Length);
                            bytes = kv1.Value;
                            ms.Write(bytes, 0, bytes.Length);
                        }
                        return(ms.ToArray());
                    }
                }
            } catch (IOException ex) {
                throw new InvalidOperationException(ex.ToString(), ex);
            }
            if (valueAType == CBORType.SimpleValue ||
                valueAType == CBORType.Boolean || valueAType == CBORType.ByteString ||
                valueAType == CBORType.TextString)
            {
                return(cbor.EncodeToBytes(CBOREncodeOptions.Default));
            }
            else if (valueAType == CBORType.FloatingPoint)
            {
                long bits = cbor.AsDoubleBits();
                return(new byte[] {
                    (byte)0xfb,
                    (byte)((bits >> 56) & 0xffL),
                    (byte)((bits >> 48) & 0xffL),
                    (byte)((bits >> 40) & 0xffL),
                    (byte)((bits >> 32) & 0xffL),
                    (byte)((bits >> 24) & 0xffL),
                    (byte)((bits >> 16) & 0xffL),
                    (byte)((bits >> 8) & 0xffL),
                    (byte)(bits & 0xffL),
                });
            }
            else if (valueAType == CBORType.Integer)
            {
                return(cbor.EncodeToBytes(CBOREncodeOptions.Default));
            }
            else
            {
                throw new ArgumentException("Invalid CBOR type.");
            }
        }
示例#4
0
        private static byte[] CtapCanonicalEncode(CBORObject a, int depth)
        {
            CBORObject cbor       = a.Untag();
            CBORType   valueAType = cbor.Type;

            try {
                if (valueAType == CBORType.Array)
                {
                    using (var ms = new MemoryStream()) {
                        CBORObject.WriteValue(ms, 4, cbor.Count);
                        for (var i = 0; i < cbor.Count; ++i)
                        {
                            if (depth >= 3 && IsArrayOrMap(cbor[i]))
                            {
                                throw new CBORException("Nesting level too deep");
                            }
                            byte[] bytes = CtapCanonicalEncode(cbor[i], depth + 1);
                            ms.Write(bytes, 0, bytes.Length);
                        }
                        return(ms.ToArray());
                    }
                }
                else if (valueAType == CBORType.Map)
                {
                    var sortedKeys = new List <CBORObject>();
                    foreach (CBORObject key in cbor.Keys)
                    {
                        if (depth >= 3 && (IsArrayOrMap(key) ||
                                           IsArrayOrMap(cbor[key])))
                        {
                            throw new CBORException("Nesting level too deep");
                        }
                        sortedKeys.Add(key);
                    }
                    sortedKeys.Sort(Comparer);
                    using (var ms = new MemoryStream()) {
                        CBORObject.WriteValue(ms, 5, cbor.Count);
                        foreach (CBORObject key in sortedKeys)
                        {
                            byte[] bytes = CtapCanonicalEncode(key, depth + 1);
                            ms.Write(bytes, 0, bytes.Length);
                            bytes = CtapCanonicalEncode(cbor[key], depth + 1);
                            ms.Write(bytes, 0, bytes.Length);
                        }
                        return(ms.ToArray());
                    }
                }
            } catch (IOException ex) {
                throw new InvalidOperationException(ex.ToString(), ex);
            }
            if (valueAType == CBORType.SimpleValue ||
                valueAType == CBORType.Boolean || valueAType == CBORType.ByteString ||
                valueAType == CBORType.TextString)
            {
                return(cbor.EncodeToBytes(CBOREncodeOptions.Default));
            }
            else if (valueAType == CBORType.FloatingPoint)
            {
                long bits = cbor.AsDoubleBits();
                using (var ms = new MemoryStream()) {
                    CBORObject.WriteFloatingPointBits(ms, bits, 8);
                    return(ms.ToArray());
                }
            }
            else if (valueAType == CBORType.Integer)
            {
                return(cbor.EncodeToBytes(CBOREncodeOptions.Default));
            }
            else
            {
                throw new ArgumentException("Invalid CBOR type.");
            }
        }
示例#5
0
        public static byte[] CtapCanonicalEncode(CBORObject a)
        {
            CBORObject cbor       = a.Untag();
            CBORType   valueAType = cbor.Type;

            try {
                if (valueAType == CBORType.Array)
                {
                    using (var ms = new MemoryStream()) {
                        CBORObject.WriteValue(ms, 4, cbor.Count);
                        for (var i = 0; i < cbor.Count; ++i)
                        {
                            byte[] bytes = CtapCanonicalEncode(cbor[i]);
                            ms.Write(bytes, 0, bytes.Length);
                        }
                        return(ms.ToArray());
                    }
                }
                else if (valueAType == CBORType.Map)
                {
                    var sortedKeys = new List <CBORObject>();
                    foreach (CBORObject key in cbor.Keys)
                    {
                        sortedKeys.Add(key);
                    }
                    sortedKeys.Sort(new CtapComparer());
                    using (var ms = new MemoryStream()) {
                        CBORObject.WriteValue(ms, 5, cbor.Count);
                        foreach (CBORObject key in sortedKeys)
                        {
                            byte[] bytes = CtapCanonicalEncode(key);
                            ms.Write(bytes, 0, bytes.Length);
                            bytes = CtapCanonicalEncode(cbor[key]);
                            ms.Write(bytes, 0, bytes.Length);
                        }
                        return(ms.ToArray());
                    }
                }
            } catch (IOException ex) {
                throw new InvalidOperationException(ex.ToString(), ex);
            }
            if (valueAType == CBORType.SimpleValue ||
                valueAType == CBORType.Boolean || valueAType == CBORType.ByteString ||
                valueAType == CBORType.TextString)
            {
                return(cbor.EncodeToBytes(CBOREncodeOptions.Default));
            }
            else if (valueAType == CBORType.Number)
            {
                if (cbor.CanFitInInt64())
                {
                    return(cbor.EncodeToBytes(CBOREncodeOptions.Default));
                }
                else
                {
                    cbor = CBORObject.FromObject(cbor.AsDouble());
                    return(cbor.EncodeToBytes(CBOREncodeOptions.Default));
                }
            }
            else
            {
                throw new ArgumentException("Invalid CBOR type.");
            }
        }