public Guid FromCBORObject(CBORObject obj) { if (!obj.HasMostOuterTag(37)) { throw new CBORException("Must have outermost tag 37"); } ValidateObject(obj); byte[] bytes = obj.GetByteString(); var guidChars = new char[36]; string hex = "0123456789abcdef"; var index = 0; for (var i = 0; i < 16; ++i) { if (i == 4 || i == 6 || i == 8 || i == 10) { guidChars[index++] = '-'; } guidChars[index++] = hex[(int)(bytes[i] >> 4) & 15]; guidChars[index++] = hex[(int)bytes[i] & 15]; } string guidString = new String(guidChars); return(new Guid(guidString)); }
private static CBORObject ValidateObject(CBORObject obj) { if (obj.Type != CBORType.ByteString) { throw new CBORException("UUID must be a byte string"); } byte[] bytes = obj.GetByteString(); if (bytes.Length != 16) { throw new CBORException("UUID must be 16 bytes long"); } return(obj); }
public CBORObject GetString(long smallIndex) { if (smallIndex < 0) { throw new CBORException("Unexpected index"); } if (smallIndex > Int32.MaxValue) { throw new CBORException("Index " + smallIndex + " is bigger than supported "); } var index = (int)smallIndex; List <CBORObject> lastList = this.stack[this.stack.Count - 1]; if (index >= lastList.Count) { throw new CBORException("Index " + index + " is not valid"); } CBORObject ret = lastList[index]; // Byte strings are mutable, so make a copy return((ret.Type == CBORType.ByteString) ? CBORObject.FromObject(ret.GetByteString()) : ret); }
public CBORObject GetString(EInteger bigIndex) { if (bigIndex.Sign < 0) { throw new CBORException("Unexpected index"); } if (!bigIndex.CanFitInInt32()) { throw new CBORException("Index " + bigIndex + " is bigger than supported "); } var index = (int)bigIndex; List <CBORObject> lastList = this.stack[this.stack.Count - 1]; if (index >= lastList.Count) { throw new CBORException("Index " + index + " is not valid"); } CBORObject ret = lastList[index]; // Byte strings are mutable, so make a copy return((ret.Type == CBORType.ByteString) ? CBORObject.FromObject(ret.GetByteString()) : ret); }
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()); }
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(); } }
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"); } }