public static void WriteBase64URL(
     StringOutput writer,
     byte[] data,
     int offset,
     int count,
     bool padding)
 {
     WriteBase64(writer, data, offset, count, false, padding);
 }
Ejemplo n.º 2
0
 public static void WriteBase64(
     StringOutput writer,
     byte[] data,
     int offset,
     int count,
     bool padding)
 {
     WriteBase64(writer, data, offset, count, Base64Classic, padding);
 }
Ejemplo n.º 3
0
       public static void WriteBase64URL(
 StringOutput writer,
 byte[] data,
 int offset,
 int count,
 bool padding)
       {
           WriteBase64(writer, data, offset, count, Base64URL, padding);
       }
Ejemplo n.º 4
0
 internal static void WriteJSONToInternal(
     CBORObject obj,
     StringOutput writer,
     JSONOptions options)
 {
     if (obj.Type == CBORType.Array || obj.Type == CBORType.Map)
     {
         var stack = new List <CBORObject>();
         WriteJSONToInternal(obj, writer, options, stack);
     }
     else
     {
         WriteJSONToInternal(obj, writer, options, null);
     }
 }
Ejemplo n.º 5
0
   internal static void WriteJSONStringUnquoted(
 string str,
 StringOutput sb)
   {
       // Surrogates were already verified when this
         // string was added to the CBOR object; that check
         // is not repeated here
         var first = true;
         for (var i = 0; i < str.Length; ++i) {
       char c = str[i];
       if (c == '\\' || c == '"') {
         if (first) {
       first = false;
       sb.WriteString(str, 0, i);
         }
         sb.WriteCodePoint((int)'\\');
         sb.WriteCodePoint((int)c);
       } else if (c < 0x20 || (c >= 0x85 && (c == 0x2028 || c == 0x2029 ||
               c == 0x85 || c == 0xfeff || c == 0xfffe ||
               c == 0xffff))) {
         // Control characters, and also the line and paragraph separators
         // which apparently can't appear in JavaScript (as opposed to
         // JSON) strings
         // TODO: Also include 0x7f..0x9f in version 3
         if (first) {
       first = false;
       sb.WriteString(str, 0, i);
         }
         if (c == 0x0d) {
       sb.WriteString("\\r");
         } else if (c == 0x0a) {
       sb.WriteString("\\n");
         } else if (c == 0x08) {
       sb.WriteString("\\b");
         } else if (c == 0x0c) {
       sb.WriteString("\\f");
         } else if (c == 0x09) {
       sb.WriteString("\\t");
         } else if (c == 0x85) {
       sb.WriteString("\\u0085");
         } else if (c >= 0x2028) {
       sb.WriteString("\\u");
       sb.WriteCodePoint((int)Hex16[(int)((c >> 12) & 15)]);
       sb.WriteCodePoint((int)Hex16[(int)((c >> 8) & 15)]);
       sb.WriteCodePoint((int)Hex16[(int)((c >> 4) & 15)]);
       sb.WriteCodePoint((int)Hex16[(int)(c & 15)]);
         } else {
       sb.WriteString("\\u00");
       sb.WriteCodePoint((int)Hex16[(int)(c >> 4)]);
       sb.WriteCodePoint((int)Hex16[(int)(c & 15)]);
         }
       } else if (!first) {
         if ((c & 0xfc00) == 0xd800) {
       sb.WriteString(str, i, 2);
       ++i;
         } else {
       sb.WriteCodePoint((int)c);
         }
       }
         }
         if (first) {
       sb.WriteString(str);
         }
   }
Ejemplo n.º 6
0
   internal static void WriteJSONToInternal(
 CBORObject obj,
 StringOutput writer)
   {
       int type = obj.ItemType;
         object thisItem = obj.ThisItem;
         switch (type) {
         case CBORObject.CBORObjectTypeSimpleValue: {
       if (obj.IsTrue) {
         writer.WriteString("true");
         return;
       }
       if (obj.IsFalse) {
         writer.WriteString("false");
         return;
       }
       writer.WriteString("null");
       return;
         }
         case CBORObject.CBORObjectTypeSingle: {
       var f = (float)thisItem;
       if (Single.IsNegativeInfinity(f) ||
           Single.IsPositiveInfinity(f) || Single.IsNaN(f)) {
         writer.WriteString("null");
         return;
       }
       writer.WriteString(
         CBORObject.TrimDotZero(
           CBORUtilities.SingleToString(f)));
       return;
         }
         case CBORObject.CBORObjectTypeDouble: {
       var f = (double)thisItem;
       if (Double.IsNegativeInfinity(f) || Double.IsPositiveInfinity(f) ||
           Double.IsNaN(f)) {
         writer.WriteString("null");
         return;
       }
       string dblString = CBORUtilities.DoubleToString(f);
       writer.WriteString(
         CBORObject.TrimDotZero(dblString));
       return;
         }
         case CBORObject.CBORObjectTypeInteger: {
       var longItem = (long)thisItem;
       writer.WriteString(CBORUtilities.LongToString(longItem));
       return;
         }
         case CBORObject.CBORObjectTypeBigInteger: {
       writer.WriteString(
         CBORUtilities.BigIntToString((EInteger)thisItem));
       return;
         }
         case CBORObject.CBORObjectTypeExtendedDecimal: {
       var dec = (EDecimal)thisItem;
       if (dec.IsInfinity() || dec.IsNaN()) {
         writer.WriteString("null");
       } else {
         writer.WriteString(dec.ToString());
       }
       return;
         }
         case CBORObject.CBORObjectTypeExtendedFloat: {
       var flo = (EFloat)thisItem;
       if (flo.IsInfinity() || flo.IsNaN()) {
         writer.WriteString("null");
         return;
       }
       if (flo.IsFinite &&
           flo.Exponent.Abs().CompareTo((EInteger)2500) > 0) {
         // Too inefficient to convert to a decimal number
         // from a bigfloat with a very high exponent,
         // so convert to double instead
         double f = flo.ToDouble();
         if (Double.IsNegativeInfinity(f) ||
             Double.IsPositiveInfinity(f) || Double.IsNaN(f)) {
           writer.WriteString("null");
           return;
         }
         string dblString =
             CBORUtilities.DoubleToString(f);
         writer.WriteString(
           CBORObject.TrimDotZero(dblString));
         return;
       }
       writer.WriteString(flo.ToString());
       return;
         }
       case CBORObject.CBORObjectTypeByteString:
         {
       var byteArray = (byte[])thisItem;
       if (byteArray.Length == 0) {
         writer.WriteString("\"\"");
         return;
       }
       writer.WriteCodePoint((int)'\"');
       if (obj.HasTag(22)) {
         Base64.WriteBase64(
           writer,
           byteArray,
           0,
           byteArray.Length,
           false);
       } 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 {
         Base64.WriteBase64URL(
           writer,
           byteArray,
           0,
           byteArray.Length,
           false);
       }
       writer.WriteCodePoint((int)'\"');
       break;
         }
         case CBORObject.CBORObjectTypeTextString: {
       var thisString = (string)thisItem;
       if (thisString.Length == 0) {
         writer.WriteString("\"\"");
         return;
       }
       writer.WriteCodePoint((int)'\"');
       WriteJSONStringUnquoted(thisString, writer);
       writer.WriteCodePoint((int)'\"');
       break;
         }
         case CBORObject.CBORObjectTypeArray: {
       var first = true;
       writer.WriteCodePoint((int)'[');
       foreach (CBORObject i in obj.AsList()) {
         if (!first) {
           writer.WriteCodePoint((int)',');
         }
         WriteJSONToInternal(i, writer);
         first = false;
       }
       writer.WriteCodePoint((int)']');
       break;
         }
         case CBORObject.CBORObjectTypeExtendedRational: {
       var dec = (ERational)thisItem;
       EDecimal f = dec.ToEDecimalExactIfPossible(
         EContext.Decimal128.WithUnlimitedExponents());
       if (!f.IsFinite) {
         writer.WriteString("null");
       } else {
         writer.WriteString(f.ToString());
       }
       break;
         }
         case CBORObject.CBORObjectTypeMap: {
       var first = true;
       var hasNonStringKeys = false;
       IDictionary<CBORObject, CBORObject> objMap = obj.AsMap();
       foreach (KeyValuePair<CBORObject, CBORObject> entry in objMap) {
         CBORObject key = entry.Key;
         if (key.ItemType != CBORObject.CBORObjectTypeTextString) {
           hasNonStringKeys = true;
           break;
         }
       }
       if (!hasNonStringKeys) {
         writer.WriteCodePoint((int)'{');
         foreach (KeyValuePair<CBORObject, CBORObject> entry in objMap) {
           CBORObject key = entry.Key;
           CBORObject value = entry.Value;
           if (!first) {
             writer.WriteCodePoint((int)',');
           }
           writer.WriteCodePoint((int)'\"');
           WriteJSONStringUnquoted((string)key.ThisItem, writer);
           writer.WriteCodePoint((int)'\"');
           writer.WriteCodePoint((int)':');
           WriteJSONToInternal(value, writer);
           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 objMap) {
           CBORObject key = entry.Key;
           CBORObject value = entry.Value;
          string str = (key.ItemType == CBORObject.CBORObjectTypeTextString) ?
             ((string)key.ThisItem) : key.ToJSONString();
           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);
           writer.WriteCodePoint((int)'\"');
           writer.WriteCodePoint((int)':');
           WriteJSONToInternal(value, writer);
           first = false;
         }
         writer.WriteCodePoint((int)'}');
       }
       break;
         }
       default:
         throw new InvalidOperationException("Unexpected item type");
         }
   }
Ejemplo n.º 7
0
        internal static void WriteJSONStringUnquoted(
            string str,
            StringOutput sb,
            JSONOptions options)
        {
            var i = 0;

            for (; i < str.Length; ++i)
            {
                char c = str[i];
                if (c < 0x20 || c >= 0x7f || c == '\\' || c == '"')
                {
                    sb.WriteString(str, 0, i);
                    break;
                }
            }
            if (i == str.Length)
            {
                sb.WriteString(str, 0, i);
                return;
            }
            for (; i < str.Length; ++i)
            {
                char c = str[i];
                if (c == '\\' || c == '"')
                {
                    sb.WriteCodePoint((int)'\\');
                    sb.WriteCodePoint((int)c);
                }
                else if (c < 0x20 || (c >= 0x7f && (c == 0x2028 || c == 0x2029 ||
                                                    (c >= 0x7f && c <= 0xa0) || c == 0xfeff || c == 0xfffe ||
                                                    c == 0xffff)))
                {
                    // Control characters, and also the line and paragraph separators
                    // which apparently can't appear in JavaScript (as opposed to
                    // JSON) strings
                    if (c == 0x0d)
                    {
                        sb.WriteString("\\r");
                    }
                    else if (c == 0x0a)
                    {
                        sb.WriteString("\\n");
                    }
                    else if (c == 0x08)
                    {
                        sb.WriteString("\\b");
                    }
                    else if (c == 0x0c)
                    {
                        sb.WriteString("\\f");
                    }
                    else if (c == 0x09)
                    {
                        sb.WriteString("\\t");
                    }
                    else if (c == 0x85)
                    {
                        sb.WriteString("\\u0085");
                    }
                    else if (c >= 0x100)
                    {
                        sb.WriteString("\\u");
                        sb.WriteCodePoint((int)Hex16[(int)((c >> 12) & 15)]);
                        sb.WriteCodePoint((int)Hex16[(int)((c >> 8) & 15)]);
                        sb.WriteCodePoint((int)Hex16[(int)((c >> 4) & 15)]);
                        sb.WriteCodePoint((int)Hex16[(int)(c & 15)]);
                    }
                    else
                    {
                        sb.WriteString("\\u00");
                        sb.WriteCodePoint((int)Hex16[(int)(c >> 4)]);
                        sb.WriteCodePoint((int)Hex16[(int)(c & 15)]);
                    }
                }
                else if ((c & 0xfc00) == 0xd800)
                {
                    if (i >= str.Length - 1 || (str[i + 1] & 0xfc00) != 0xdc00)
                    {
                        // NOTE: RFC 8259 doesn't prohibit any particular
                        // error-handling behavior when a writer of JSON
                        // receives a string with an unpaired surrogate.
                        if (options.ReplaceSurrogates)
                        {
                            // Replace unpaired surrogate with U+FFFD
                            sb.WriteCodePoint(0xfffd);
                        }
                        else
                        {
                            throw new CBORException("Unpaired surrogate in string");
                        }
                    }
                    else
                    {
                        sb.WriteString(str, i, 2);
                        ++i;
                    }
                }
                else
                {
                    sb.WriteCodePoint((int)c);
                }
            }
        }
Ejemplo n.º 8
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");
            }
        }
Ejemplo n.º 9
0
        internal static void WriteJSONToInternal(
            CBORObject obj,
            StringOutput writer)
        {
            int    type     = obj.ItemType;
            object thisItem = obj.ThisItem;

            switch (type)
            {
            case CBORObject.CBORObjectTypeSimpleValue: {
                if (obj.IsTrue)
                {
                    writer.WriteString("true");
                    return;
                }
                if (obj.IsFalse)
                {
                    writer.WriteString("false");
                    return;
                }
                writer.WriteString("null");
                return;
            }

            case CBORObject.CBORObjectTypeSingle: {
                var f = (float)thisItem;
                if (Single.IsNegativeInfinity(f) ||
                    Single.IsPositiveInfinity(f) || Single.IsNaN(f))
                {
                    writer.WriteString("null");
                    return;
                }
                writer.WriteString(
                    CBORObject.TrimDotZero(
                        CBORUtilities.SingleToString(f)));
                return;
            }

            case CBORObject.CBORObjectTypeDouble: {
                var f = (double)thisItem;
                if (Double.IsNegativeInfinity(f) || Double.IsPositiveInfinity(f) ||
                    Double.IsNaN(f))
                {
                    writer.WriteString("null");
                    return;
                }
                string dblString = CBORUtilities.DoubleToString(f);
                writer.WriteString(
                    CBORObject.TrimDotZero(dblString));
                return;
            }

            case CBORObject.CBORObjectTypeInteger: {
                var longItem = (long)thisItem;
                writer.WriteString(CBORUtilities.LongToString(longItem));
                return;
            }

            case CBORObject.CBORObjectTypeBigInteger: {
                writer.WriteString(
                    CBORUtilities.BigIntToString((EInteger)thisItem));
                return;
            }

            case CBORObject.CBORObjectTypeExtendedDecimal: {
                var dec = (EDecimal)thisItem;
                if (dec.IsInfinity() || dec.IsNaN())
                {
                    writer.WriteString("null");
                }
                else
                {
                    writer.WriteString(dec.ToString());
                }
                return;
            }

            case CBORObject.CBORObjectTypeExtendedFloat: {
                var flo = (EFloat)thisItem;
                if (flo.IsInfinity() || flo.IsNaN())
                {
                    writer.WriteString("null");
                    return;
                }
                if (flo.IsFinite &&
                    flo.Exponent.Abs().CompareTo((EInteger)2500) > 0)
                {
                    // Too inefficient to convert to a decimal number
                    // from a bigfloat with a very high exponent,
                    // so convert to double instead
                    double f = flo.ToDouble();
                    if (Double.IsNegativeInfinity(f) ||
                        Double.IsPositiveInfinity(f) || Double.IsNaN(f))
                    {
                        writer.WriteString("null");
                        return;
                    }
                    string dblString =
                        CBORUtilities.DoubleToString(f);
                    writer.WriteString(
                        CBORObject.TrimDotZero(dblString));
                    return;
                }
                writer.WriteString(flo.ToString());
                return;
            }

            case CBORObject.CBORObjectTypeByteString:
            {
                var byteArray = (byte[])thisItem;
                if (byteArray.Length == 0)
                {
                    writer.WriteString("\"\"");
                    return;
                }
                writer.WriteCodePoint((int)'\"');
                if (obj.HasTag(22))
                {
                    Base64.WriteBase64(
                        writer,
                        byteArray,
                        0,
                        byteArray.Length,
                        false);
                }
                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
                {
                    Base64.WriteBase64URL(
                        writer,
                        byteArray,
                        0,
                        byteArray.Length,
                        false);
                }
                writer.WriteCodePoint((int)'\"');
                break;
            }

            case CBORObject.CBORObjectTypeTextString: {
                var thisString = (string)thisItem;
                if (thisString.Length == 0)
                {
                    writer.WriteString("\"\"");
                    return;
                }
                writer.WriteCodePoint((int)'\"');
                WriteJSONStringUnquoted(thisString, writer);
                writer.WriteCodePoint((int)'\"');
                break;
            }

            case CBORObject.CBORObjectTypeArray: {
                var first = true;
                writer.WriteCodePoint((int)'[');
                foreach (CBORObject i in obj.AsList())
                {
                    if (!first)
                    {
                        writer.WriteCodePoint((int)',');
                    }
                    WriteJSONToInternal(i, writer);
                    first = false;
                }
                writer.WriteCodePoint((int)']');
                break;
            }

            case CBORObject.CBORObjectTypeExtendedRational: {
                var      dec = (ERational)thisItem;
                EDecimal f   = dec.ToEDecimalExactIfPossible(
                    EContext.Decimal128.WithUnlimitedExponents());
                if (!f.IsFinite)
                {
                    writer.WriteString("null");
                }
                else
                {
                    writer.WriteString(f.ToString());
                }
                break;
            }

            case CBORObject.CBORObjectTypeMap: {
                var first            = true;
                var hasNonStringKeys = false;
                IDictionary <CBORObject, CBORObject> objMap = obj.AsMap();
                foreach (KeyValuePair <CBORObject, CBORObject> entry in objMap)
                {
                    CBORObject key = entry.Key;
                    if (key.ItemType != CBORObject.CBORObjectTypeTextString)
                    {
                        hasNonStringKeys = true;
                        break;
                    }
                }
                if (!hasNonStringKeys)
                {
                    writer.WriteCodePoint((int)'{');
                    foreach (KeyValuePair <CBORObject, CBORObject> entry in objMap)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        if (!first)
                        {
                            writer.WriteCodePoint((int)',');
                        }
                        writer.WriteCodePoint((int)'\"');
                        WriteJSONStringUnquoted((string)key.ThisItem, writer);
                        writer.WriteCodePoint((int)'\"');
                        writer.WriteCodePoint((int)':');
                        WriteJSONToInternal(value, writer);
                        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 objMap)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        string     str   = (key.ItemType == CBORObject.CBORObjectTypeTextString) ?
                                           ((string)key.ThisItem) : key.ToJSONString();
                        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);
                        writer.WriteCodePoint((int)'\"');
                        writer.WriteCodePoint((int)':');
                        WriteJSONToInternal(value, writer);
                        first = false;
                    }
                    writer.WriteCodePoint((int)'}');
                }
                break;
            }

            default:
                throw new InvalidOperationException("Unexpected item type");
            }
        }
Ejemplo n.º 10
0
        internal static void WriteJSONStringUnquoted(
            string str,
            StringOutput sb)
        {
            // Surrogates were already verified when this
            // string was added to the CBOR object; that check
            // is not repeated here
            var first = true;

            for (var i = 0; i < str.Length; ++i)
            {
                char c = str[i];
                if (c == '\\' || c == '"')
                {
                    if (first)
                    {
                        first = false;
                        sb.WriteString(str, 0, i);
                    }
                    sb.WriteCodePoint((int)'\\');
                    sb.WriteCodePoint((int)c);
                }
                else if (c < 0x20 || (c >= 0x7f && (c == 0x2028 || c == 0x2029 ||
                                                    (c >= 0x7f && c <= 0xa0) || c == 0xfeff || c == 0xfffe ||
                                                    c == 0xffff)))
                {
                    // Control characters, and also the line and paragraph separators
                    // which apparently can't appear in JavaScript (as opposed to
                    // JSON) strings
                    if (first)
                    {
                        first = false;
                        sb.WriteString(str, 0, i);
                    }
                    if (c == 0x0d)
                    {
                        sb.WriteString("\\r");
                    }
                    else if (c == 0x0a)
                    {
                        sb.WriteString("\\n");
                    }
                    else if (c == 0x08)
                    {
                        sb.WriteString("\\b");
                    }
                    else if (c == 0x0c)
                    {
                        sb.WriteString("\\f");
                    }
                    else if (c == 0x09)
                    {
                        sb.WriteString("\\t");
                    }
                    else if (c == 0x85)
                    {
                        sb.WriteString("\\u0085");
                    }
                    else if (c >= 0x100)
                    {
                        sb.WriteString("\\u");
                        sb.WriteCodePoint((int)Hex16[(int)((c >> 12) & 15)]);
                        sb.WriteCodePoint((int)Hex16[(int)((c >> 8) & 15)]);
                        sb.WriteCodePoint((int)Hex16[(int)((c >> 4) & 15)]);
                        sb.WriteCodePoint((int)Hex16[(int)(c & 15)]);
                    }
                    else
                    {
                        sb.WriteString("\\u00");
                        sb.WriteCodePoint((int)Hex16[(int)(c >> 4)]);
                        sb.WriteCodePoint((int)Hex16[(int)(c & 15)]);
                    }
                }
                else if (!first)
                {
                    if ((c & 0xfc00) == 0xd800)
                    {
                        sb.WriteString(str, i, 2);
                        ++i;
                    }
                    else
                    {
                        sb.WriteCodePoint((int)c);
                    }
                }
            }
            if (first)
            {
                sb.WriteString(str);
            }
        }
        private static void WriteBase64(
            StringOutput writer,
            byte[] data,
            int offset,
            int count,
            bool classic,
            bool padding)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            if (offset < 0)
            {
                throw new ArgumentException("offset(" + offset + ") is less than " +
                                            "0 ");
            }
            if (offset > data.Length)
            {
                throw new ArgumentException("offset(" + offset + ") is more than " +
                                            data.Length);
            }
            if (count < 0)
            {
                throw new ArgumentException("count(" + count + ") is less than " +
                                            "0 ");
            }
            if (count > data.Length)
            {
                throw new ArgumentException("count(" + count + ") is more than " +
                                            data.Length);
            }
            if (data.Length - offset < count)
            {
                throw new ArgumentException("data's length minus " + offset + "(" +
                                            (data.Length - offset) + ") is less than " + count);
            }
            string alphabet = classic ? Base64Classic : Base64URL;
            int    length   = offset + count;
            int    i        = offset;
            var    buffer   = new char[4];

            for (i = offset; i < (length - 2); i += 3)
            {
                buffer[0] = (char)alphabet[(data[i] >> 2) & 63];
                buffer[1] = (char)alphabet[((data[i] & 3) << 4) +
                                           ((data[i + 1] >> 4) & 15)];
                buffer[2] = (char)alphabet[((data[i + 1] & 15) << 2) + ((data[i +
                                                                              2] >> 6) & 3)];
                buffer[3] = (char)alphabet[data[i + 2] & 63];
                writer.WriteCodePoint((int)buffer[0]);
                writer.WriteCodePoint((int)buffer[1]);
                writer.WriteCodePoint((int)buffer[2]);
                writer.WriteCodePoint((int)buffer[3]);
            }
            int lenmod3 = count % 3;

            if (lenmod3 != 0)
            {
                i         = length - lenmod3;
                buffer[0] = (char)alphabet[(data[i] >> 2) & 63];
                if (lenmod3 == 2)
                {
                    buffer[1] = (char)alphabet[((data[i] & 3) << 4) + ((data[i + 1] >>
                                                                        4) & 15)];
                    buffer[2] = (char)alphabet[(data[i + 1] & 15) << 2];
                    writer.WriteCodePoint((int)buffer[0]);
                    writer.WriteCodePoint((int)buffer[1]);
                    writer.WriteCodePoint((int)buffer[2]);
                    if (padding)
                    {
                        writer.WriteCodePoint((int)'=');
                    }
                }
                else
                {
                    buffer[1] = (char)alphabet[(data[i] & 3) << 4];
                    writer.WriteCodePoint((int)buffer[0]);
                    writer.WriteCodePoint((int)buffer[1]);
                    if (padding)
                    {
                        writer.WriteCodePoint((int)'=');
                        writer.WriteCodePoint((int)'=');
                    }
                }
            }
        }
Ejemplo n.º 12
0
        internal static void WriteJSONToInternal(
            CBORObject obj,
            StringOutput writer,
            JSONOptions options)
        {
            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: {
                var 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: {
                var thisString = obj.AsString();
                if (thisString.Length == 0)
                {
                    writer.WriteString("\"\"");
                    return;
                }
                writer.WriteCodePoint((int)'\"');
                WriteJSONStringUnquoted(thisString, writer, options);
                writer.WriteCodePoint((int)'\"');
                break;
            }

            case CBORType.Array: {
                var first = true;
                writer.WriteCodePoint((int)'[');
                foreach (CBORObject i in obj.AsList())
                {
                    if (!first)
                    {
                        writer.WriteCodePoint((int)',');
                    }
                    WriteJSONToInternal(i, writer, options);
                    first = false;
                }
                writer.WriteCodePoint((int)']');
                break;
            }

            case CBORType.Map: {
                var first            = true;
                var hasNonStringKeys = false;
                IDictionary <CBORObject, CBORObject> objMap = obj.AsMap();
                foreach (KeyValuePair <CBORObject, CBORObject> entry in objMap)
                {
                    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 objMap)
                    {
                        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)':');
                        WriteJSONToInternal(value, writer, options);
                        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 objMap)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        string     str   = (key.Type == CBORType.TextString) ?
                                           key.AsString() : key.ToJSONString();
                        if (stringMap.ContainsKey(str))
                        {
                            throw new
                                  CBORException("Duplicate JSON string equivalents of map keys");
                        }
                        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)':');
                        WriteJSONToInternal(value, writer, options);
                        first = false;
                    }
                    writer.WriteCodePoint((int)'}');
                }
                break;
            }

            default: throw new InvalidOperationException("Unexpected item type");
            }
        }
Ejemplo n.º 13
0
       private static void WriteBase64(
 StringOutput writer,
 byte[] data,
 int offset,
 int count,
 string alphabet,
 bool padding)
       {
           if (writer == null) {
           throw new ArgumentNullException("writer");
             }
             if (offset < 0) {
           throw new ArgumentException("offset (" + offset + ") is less than " +
                   "0 ");
             }
             if (offset > data.Length) {
           throw new ArgumentException("offset (" + offset + ") is more than " +
                   data.Length);
             }
             if (count < 0) {
           throw new ArgumentException("count (" + count + ") is less than " +
                   "0 ");
             }
             if (count > data.Length) {
           throw new ArgumentException("count (" + count + ") is more than " +
                   data.Length);
             }
             if (data.Length - offset < count) {
           throw new ArgumentException("data's length minus " + offset + " (" +
               (data.Length - offset) + ") is less than " + count);
             }
             int length = offset + count;
             int i = offset;
             var buffer = new char[4];
             for (i = offset; i < (length - 2); i += 3) {
           buffer[0] = (char)alphabet[(data[i] >> 2) & 63];
           buffer[1] = (char)alphabet[((data[i] & 3) << 4) +
               ((data[i + 1] >> 4) & 15)];
           buffer[2] = (char)alphabet[((data[i + 1] & 15) << 2) + ((data[i +
               2] >> 6) & 3)];
           buffer[3] = (char)alphabet[data[i + 2] & 63];
           writer.WriteCodePoint((int)buffer[0]);
           writer.WriteCodePoint((int)buffer[1]);
           writer.WriteCodePoint((int)buffer[2]);
           writer.WriteCodePoint((int)buffer[3]);
             }
             int lenmod3 = count % 3;
             if (lenmod3 != 0) {
           i = length - lenmod3;
           buffer[0] = (char)alphabet[(data[i] >> 2) & 63];
           if (lenmod3 == 2) {
             buffer[1] = (char)alphabet[((data[i] & 3) << 4) + ((data[i + 1] >>
               4) & 15)];
             buffer[2] = (char)alphabet[(data[i + 1] & 15) << 2];
             writer.WriteCodePoint((int)buffer[0]);
             writer.WriteCodePoint((int)buffer[1]);
             writer.WriteCodePoint((int)buffer[2]);
             if (padding) {
           writer.WriteCodePoint((int)'=');
             }
           } else {
             buffer[1] = (char)alphabet[(data[i] & 3) << 4];
             writer.WriteCodePoint((int)buffer[0]);
             writer.WriteCodePoint((int)buffer[1]);
             if (padding) {
           writer.WriteCodePoint((int)'=');
           writer.WriteCodePoint((int)'=');
             }
           }
             }
       }