Beispiel #1
0
 public Uri FromCBORObject(CBORObject obj)
 {
     if (obj.HasMostOuterTag(32) ||
         obj.HasMostOuterTag(266) ||
         obj.HasMostOuterTag(267))
     {
         ValidateObject(obj);
         try {
             return(new Uri(obj.AsString()));
         } catch (Exception ex) {
             throw new CBORException(ex.Message, ex);
         }
     }
     throw new CBORException();
 }
Beispiel #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: {
                // TODO: Avoid converting to double
                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());
        }
Beispiel #3
0
        public static object TypeToObject(
            CBORObject objThis,
            Type t,
            CBORTypeMapper mapper,
            PODOptions options,
            int depth)
        {
            if (t.Equals(typeof(int)))
            {
                return(objThis.AsInt32());
            }
            if (t.Equals(typeof(short)))
            {
                return(objThis.AsNumber().ToInt16Checked());
            }
            if (t.Equals(typeof(ushort)))
            {
                return(objThis.AsUInt16Legacy());
            }
            if (t.Equals(typeof(byte)))
            {
                return(objThis.AsByteLegacy());
            }
            if (t.Equals(typeof(sbyte)))
            {
                return(objThis.AsSByteLegacy());
            }
            if (t.Equals(typeof(long)))
            {
                return(objThis.AsNumber().ToInt64Checked());
            }
            if (t.Equals(typeof(uint)))
            {
                return(objThis.AsUInt32Legacy());
            }
            if (t.Equals(typeof(ulong)))
            {
                return(objThis.AsUInt64Legacy());
            }
            if (t.Equals(typeof(double)))
            {
                return(objThis.AsDouble());
            }
            if (t.Equals(typeof(decimal)))
            {
                return(objThis.AsDecimal());
            }
            if (t.Equals(typeof(float)))
            {
                return(objThis.AsSingle());
            }
            if (t.Equals(typeof(bool)))
            {
                return(objThis.AsBoolean());
            }
            if (t.Equals(typeof(char)))
            {
                if (objThis.Type == CBORType.TextString)
                {
                    string s = objThis.AsString();
                    if (s.Length != 1)
                    {
                        throw new CBORException("Can't convert to char");
                    }
                    return(s[0]);
                }
                if (objThis.IsNumber && objThis.AsNumber().CanFitInInt32())
                {
                    int c = objThis.AsNumber().ToInt32IfExact();
                    if (c < 0 || c >= 0x10000)
                    {
                        throw new CBORException("Can't convert to char");
                    }
                    return((char)c);
                }
                throw new CBORException("Can't convert to char");
            }
            if (t.Equals(typeof(DateTime)))
            {
                return(new CBORDateConverter().FromCBORObject(objThis));
            }
            if (t.Equals(typeof(Guid)))
            {
                return(new CBORUuidConverter().FromCBORObject(objThis));
            }
            if (t.Equals(typeof(Uri)))
            {
                return(new CBORUriConverter().FromCBORObject(objThis));
            }
            if (IsAssignableFrom(typeof(Enum), t))
            {
                return(ObjectToEnum(objThis, t));
            }
            if (IsGenericType(t))
            {
                Type td = t.GetGenericTypeDefinition();
                // Nullable types
                if (td.Equals(typeof(Nullable <>)))
                {
                    Type nullableType = Nullable.GetUnderlyingType(t);
                    if (objThis.IsNull)
                    {
                        return(Activator.CreateInstance(t));
                    }
                    else
                    {
                        object wrappedObj = objThis.ToObject(
                            nullableType,
                            mapper,
                            options,
                            depth + 1);
                        return(Activator.CreateInstance(
                                   t,
                                   wrappedObj));
                    }
                }
            }
            if (objThis.Type == CBORType.ByteString)
            {
                if (t.Equals(typeof(byte[])))
                {
                    byte[] bytes   = objThis.GetByteString();
                    var    byteret = new byte[bytes.Length];
                    Array.Copy(bytes, 0, byteret, 0, byteret.Length);
                    return(byteret);
                }
            }
            if (objThis.Type == CBORType.Array)
            {
                Type   objectType = typeof(object);
                var    isList     = false;
                object listObject = null;
        #if NET40 || NET20
                if (IsAssignableFrom(typeof(Array), t))
                {
                    Type  elementType = t.GetElementType();
                    Array array       = Array.CreateInstance(
                        elementType,
                        GetDimensions(objThis));
                    return(FillArray(
                               array,
                               elementType,
                               objThis,
                               mapper,
                               options,
                               depth));
                }
                if (t.IsGenericType)
                {
                    Type td = t.GetGenericTypeDefinition();
                    isList = td.Equals(typeof(List <>)) || td.Equals(typeof(IList <>)) ||
                             td.Equals(typeof(ICollection <>)) ||
                             td.Equals(typeof(IEnumerable <>));
                }
                isList = isList && t.GetGenericArguments().Length == 1;
                if (isList)
                {
                    objectType = t.GetGenericArguments()[0];
                    Type listType = typeof(List <>).MakeGenericType(objectType);
                    listObject = Activator.CreateInstance(listType);
                }
        #else
                if (IsAssignableFrom(typeof(Array), t))
                {
                    Type  elementType = t.GetElementType();
                    Array array       = Array.CreateInstance(
                        elementType,
                        GetDimensions(objThis));
                    return(FillArray(
                               array,
                               elementType,
                               objThis,
                               mapper,
                               options,
                               depth));
                }
                if (t.GetTypeInfo().IsGenericType)
                {
                    Type td = t.GetGenericTypeDefinition();
                    isList = td.Equals(typeof(List <>)) || td.Equals(typeof(IList <>)) ||
                             td.Equals(typeof(ICollection <>)) ||

                             td.Equals(typeof(IEnumerable <>));
                }
                isList = isList && t.GenericTypeArguments.Length == 1;
                if (isList)
                {
                    objectType = t.GenericTypeArguments[0];
                    Type listType = typeof(List <>).MakeGenericType(objectType);
                    listObject = Activator.CreateInstance(listType);
                }
        #endif
                if (listObject == null)
                {
                    if (t.Equals(typeof(IList)) ||
                        t.Equals(typeof(ICollection)) || t.Equals(typeof(IEnumerable)))
                    {
                        listObject = new List <object>();
                        objectType = typeof(object);
                    }
                }
                if (listObject != null)
                {
                    System.Collections.IList ie = (System.Collections.IList)listObject;
                    foreach (CBORObject value in objThis.Values)
                    {
                        ie.Add(value.ToObject(objectType, mapper, options, depth + 1));
                    }
                    return(listObject);
                }
            }
            if (objThis.Type == CBORType.Map)
            {
                var    isDict     = false;
                Type   keyType    = null;
                Type   valueType  = null;
                object dictObject = null;
        #if NET40 || NET20
                isDict = t.IsGenericType;
                if (t.IsGenericType)
                {
                    Type td = t.GetGenericTypeDefinition();
                    isDict = td.Equals(typeof(Dictionary <,>)) ||
                             td.Equals(typeof(IDictionary <,>));
                }
                // DebugUtility.Log("list=" + isDict);
                isDict = isDict && t.GetGenericArguments().Length == 2;
                // DebugUtility.Log("list=" + isDict);
                if (isDict)
                {
                    keyType   = t.GetGenericArguments()[0];
                    valueType = t.GetGenericArguments()[1];
                    Type listType = typeof(Dictionary <,>).MakeGenericType(
                        keyType,
                        valueType);
                    dictObject = Activator.CreateInstance(listType);
                }
        #else
                isDict = t.GetTypeInfo().IsGenericType;
                if (t.GetTypeInfo().IsGenericType)
                {
                    Type td = t.GetGenericTypeDefinition();
                    isDict = td.Equals(typeof(Dictionary <,>)) ||
                             td.Equals(typeof(IDictionary <,>));
                }
                // DebugUtility.Log("list=" + isDict);
                isDict = isDict && t.GenericTypeArguments.Length == 2;
                // DebugUtility.Log("list=" + isDict);
                if (isDict)
                {
                    keyType   = t.GenericTypeArguments[0];
                    valueType = t.GenericTypeArguments[1];
                    Type listType = typeof(Dictionary <,>).MakeGenericType(
                        keyType,
                        valueType);
                    dictObject = Activator.CreateInstance(listType);
                }
        #endif
                if (dictObject == null)
                {
                    if (t.Equals(typeof(IDictionary)))
                    {
                        dictObject = new Dictionary <object, object>();
                        keyType    = typeof(object);
                        valueType  = typeof(object);
                    }
                }
                if (dictObject != null)
                {
                    System.Collections.IDictionary idic =
                        (System.Collections.IDictionary)dictObject;
                    foreach (CBORObject key in objThis.Keys)
                    {
                        CBORObject value = objThis[key];
                        idic.Add(
                            key.ToObject(keyType, mapper, options, depth + 1),
                            value.ToObject(valueType, mapper, options, depth + 1));
                    }
                    return(dictObject);
                }
                if (mapper != null)
                {
                    if (!mapper.FilterTypeName(t.FullName))
                    {
                        throw new CBORException("Type " + t.FullName +
                                                " not supported");
                    }
                }
                else
                {
                    if (t.FullName != null && (
                            StartsWith(t.FullName, "Microsoft.Win32.") ||
                            StartsWith(t.FullName, "System.IO.")))
                    {
                        throw new CBORException("Type " + t.FullName +
                                                " not supported");
                    }
                    if (StartsWith(t.FullName, "System.") &&
                        !HasCustomAttribute(t, "System.SerializableAttribute"))
                    {
                        throw new CBORException("Type " + t.FullName +
                                                " not supported");
                    }
                }
                var values    = new List <KeyValuePair <string, CBORObject> >();
                var propNames = PropertyMap.GetPropertyNames(
                    t,
                    options != null ? options.UseCamelCase : true);
                foreach (string key in propNames)
                {
                    if (objThis.ContainsKey(key))
                    {
                        CBORObject cborValue = objThis[key];
                        var        dict      = new KeyValuePair <string, CBORObject>(
                            key,
                            cborValue);
                        values.Add(dict);
                    }
                }
                return(PropertyMap.ObjectWithProperties(
                           t,
                           values,
                           mapper,
                           options,
                           depth));
            }
            else
            {
                throw new CBORException();
            }
        }
Beispiel #4
0
        internal static void WriteJSONToInternal(
            CBORObject obj,
            StringOutput writer,
            JSONOptions options,
            IList <CBORObject> stack)
        {
            if (obj.IsNumber)
            {
                writer.WriteString(CBORNumber.FromCBORObject(obj).ToJSONString());
                return;
            }
            switch (obj.Type)
            {
            case CBORType.Integer:
            case CBORType.FloatingPoint: {
                CBORObject untaggedObj = obj.Untag();
                writer.WriteString(
                    CBORNumber.FromCBORObject(untaggedObj).ToJSONString());
                break;
            }

            case CBORType.Boolean: {
                if (obj.IsTrue)
                {
                    writer.WriteString("true");
                    return;
                }
                if (obj.IsFalse)
                {
                    writer.WriteString("false");
                    return;
                }
                return;
            }

            case CBORType.SimpleValue: {
                writer.WriteString("null");
                return;
            }

            case CBORType.ByteString: {
                byte[] byteArray = obj.GetByteString();
                if (byteArray.Length == 0)
                {
                    writer.WriteString("\"\"");
                    return;
                }
                writer.WriteCodePoint((int)'\"');
                if (obj.HasTag(22))
                {
                    // Base64 with padding
                    Base64.WriteBase64(
                        writer,
                        byteArray,
                        0,
                        byteArray.Length,
                        true);
                }
                else if (obj.HasTag(23))
                {
                    // Write as base16
                    for (int i = 0; i < byteArray.Length; ++i)
                    {
                        writer.WriteCodePoint((int)Hex16[(byteArray[i] >> 4) & 15]);
                        writer.WriteCodePoint((int)Hex16[byteArray[i] & 15]);
                    }
                }
                else
                {
                    // Base64url no padding
                    Base64.WriteBase64URL(
                        writer,
                        byteArray,
                        0,
                        byteArray.Length,
                        false);
                }
                writer.WriteCodePoint((int)'\"');
                break;
            }

            case CBORType.TextString: {
                string thisString = obj.AsString();
                if (thisString.Length == 0)
                {
                    writer.WriteString("\"\"");
                    return;
                }
                writer.WriteCodePoint((int)'\"');
                WriteJSONStringUnquoted(thisString, writer, options);
                writer.WriteCodePoint((int)'\"');
                break;
            }

            case CBORType.Array: {
                writer.WriteCodePoint((int)'[');
                for (var i = 0; i < obj.Count; ++i)
                {
                    if (i > 0)
                    {
                        writer.WriteCodePoint((int)',');
                    }
                    bool pop = CheckCircularRef(stack, obj, obj[i]);
                    WriteJSONToInternal(obj[i], writer, options, stack);
                    PopRefIfNeeded(stack, pop);
                }
                writer.WriteCodePoint((int)']');
                break;
            }

            case CBORType.Map: {
                var first            = true;
                var hasNonStringKeys = false;
                ICollection <KeyValuePair <CBORObject, CBORObject> > entries =
                    obj.Entries;
                foreach (KeyValuePair <CBORObject, CBORObject> entry in entries)
                {
                    CBORObject key = entry.Key;
                    if (key.Type != CBORType.TextString ||
                        key.IsTagged)
                    {
                        // treat a non-text-string item or a tagged item
                        // as having non-string keys
                        hasNonStringKeys = true;
                        break;
                    }
                }
                if (!hasNonStringKeys)
                {
                    writer.WriteCodePoint((int)'{');
                    foreach (KeyValuePair <CBORObject, CBORObject> entry in entries)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        if (!first)
                        {
                            writer.WriteCodePoint((int)',');
                        }
                        writer.WriteCodePoint((int)'\"');
                        WriteJSONStringUnquoted(key.AsString(), writer, options);
                        writer.WriteCodePoint((int)'\"');
                        writer.WriteCodePoint((int)':');
                        bool pop = CheckCircularRef(stack, obj, value);
                        WriteJSONToInternal(value, writer, options, stack);
                        PopRefIfNeeded(stack, pop);
                        first = false;
                    }
                    writer.WriteCodePoint((int)'}');
                }
                else
                {
                    // This map has non-string keys
                    IDictionary <string, CBORObject> stringMap = new
                                                                 Dictionary <string, CBORObject>();
                    // Copy to a map with String keys, since
                    // some keys could be duplicates
                    // when serialized to strings
                    foreach (KeyValuePair <CBORObject, CBORObject> entry
                             in entries)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        string     str   = null;
                        switch (key.Type)
                        {
                        case CBORType.TextString:
                            str = key.AsString();
                            break;

                        case CBORType.Array:
                        case CBORType.Map: {
                            var  sb  = new StringBuilder();
                            var  sw  = new StringOutput(sb);
                            bool pop = CheckCircularRef(stack, obj, key);
                            WriteJSONToInternal(key, sw, options, stack);
                            PopRefIfNeeded(stack, pop);
                            str = sb.ToString();
                            break;
                        }

                        default: str = key.ToJSONString(options);
                            break;
                        }
                        if (stringMap.ContainsKey(str))
                        {
                            throw new CBORException(
                                      "Duplicate JSON string equivalents of map" +
                                      "\u0020keys");
                        }
                        stringMap[str] = value;
                    }
                    first = true;
                    writer.WriteCodePoint((int)'{');
                    foreach (KeyValuePair <string, CBORObject> entry in stringMap)
                    {
                        string     key   = entry.Key;
                        CBORObject value = entry.Value;
                        if (!first)
                        {
                            writer.WriteCodePoint((int)',');
                        }
                        writer.WriteCodePoint((int)'\"');
                        WriteJSONStringUnquoted((string)key, writer, options);
                        writer.WriteCodePoint((int)'\"');
                        writer.WriteCodePoint((int)':');
                        bool pop = CheckCircularRef(stack, obj, value);
                        WriteJSONToInternal(value, writer, options, stack);
                        PopRefIfNeeded(stack, pop);
                        first = false;
                    }
                    writer.WriteCodePoint((int)'}');
                }
                break;
            }

            default:
                throw new InvalidOperationException("Unexpected item" +
                                                    "\u0020type");
            }
        }