private static IDictionary <RuntimeTypeHandle, string> BuildTypeHandleTypeCodeMap(IDictionary <string, Type> typeMap)
        {
            var result = new Dictionary <RuntimeTypeHandle, string>(typeMap.Count);

            foreach (var typeHandleTypeCodeMapping in typeMap.GroupBy(kv => kv.Value))
            {
                if (typeHandleTypeCodeMapping.Count() > 1)
                {
                    SerializationExceptions.ThrowSerializationException(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            "Type '{0}' is mapped to multiple extension type codes({1}).",
                            typeHandleTypeCodeMapping.Key,
                            String.Join(
                                CultureInfo.CurrentCulture.TextInfo.ListSeparator,
                                typeHandleTypeCodeMapping.Select(kv => kv.Key)
#if NETFX_35 || UNITY
                                .Select(b => b.ToString(CultureInfo.InvariantCulture)).ToArray()
#endif // NETFX_35 || UNITY
                                )
                            )
                        );
                }

                result.Add(typeHandleTypeCodeMapping.Key.TypeHandle, typeHandleTypeCodeMapping.First().Key);
            }

            return(result);
        }
        private MessagePackSerializer GetActualTypeSerializer(Type actualType)
        {
            var result = this.OwnerContext.GetSerializer(actualType, this._schema);

            if (result == null)
            {
                SerializationExceptions.ThrowSerializationException(
                    String.Format(CultureInfo.CurrentCulture, "Cannot get serializer for actual type {0} from context.", actualType)
                    );
            }

            return(result);
        }
        private Type GetTypeFromCode(string typeCode)
        {
            RuntimeTypeHandle typeHandle;

            if (!this._typeHandleMap.TryGetValue(typeCode, out typeHandle))
            {
                SerializationExceptions.ThrowSerializationException(
                    String.Format(CultureInfo.CurrentCulture, "Unknown type {0}.", StringEscape.ForDisplay(typeCode))
                    );
            }

            return(Type.GetTypeFromHandle(typeHandle));
        }
        private string GetTypeCode(T objectTree)
        {
            string typeCode;

            if (!this._typeCodeMap.TryGetValue(objectTree.GetType().TypeHandle, out typeCode))
            {
                SerializationExceptions.ThrowSerializationException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        "Type '{0}' in assembly '{1}' is not defined as known types.",
                        objectTree.GetType().GetFullName(),
                        objectTree.GetType().GetAssembly()
                        )
                    );
            }
            return(typeCode);
        }
Beispiel #5
0
        protected internal override async Task <TArray> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
            }

            if (UnpackHelpers.GetItemsCount(unpacker) != 2)
            {
                SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as 2 element array.");
            }

            using (var wholeUnpacker = unpacker.ReadSubtree())
            {
                if (!await wholeUnpacker.ReadAsync(cancellationToken).ConfigureAwait(false))
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                MessagePackExtendedTypeObject metadata;
                try
                {
                    metadata = wholeUnpacker.LastReadData.AsMessagePackExtendedTypeObject();
                }
                catch (InvalidOperationException ex)
                {
                    SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as ext type.", ex);
                    metadata = default(MessagePackExtendedTypeObject);                       // never reaches
                }

                if (metadata.TypeCode != this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray])
                {
                    SerializationExceptions.ThrowSerializationException(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            "Multidimensional array must be encoded as ext type 0x{0:X2}.",
                            this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray]
                            )
                        );
                }

                Tuple <int[], int[]> lengthsAndLowerBounds;

                using (var arrayMetadata = new MemoryStream(metadata.Body))
                    using (var metadataUnpacker = Unpacker.Create(arrayMetadata, false))
                    {
                        if (!metadataUnpacker.Read())
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        if (!metadataUnpacker.IsArrayHeader)
                        {
                            SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                        }

                        if (UnpackHelpers.GetItemsCount(metadataUnpacker) != 2)
                        {
                            SerializationExceptions.ThrowSerializationException("Multidimensional metadata array must be encoded as 2 element array.");
                        }

                        lengthsAndLowerBounds = await this.ReadArrayMetadataAsync(metadataUnpacker, cancellationToken).ConfigureAwait(false);
                    }

                if (!await wholeUnpacker.ReadAsync(cancellationToken).ConfigureAwait(false))
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                if (!wholeUnpacker.IsArrayHeader)
                {
                    SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                }

                using (var arrayUnpacker = wholeUnpacker.ReadSubtree())
                {
                    var result =
                        Array.CreateInstance(typeof(TItem), lengthsAndLowerBounds.Item1, lengthsAndLowerBounds.Item2);

                    var totalLength = UnpackHelpers.GetItemsCount(arrayUnpacker);
                    if (totalLength > 0)
                    {
                        ForEach(
                            result,
                            totalLength,
                            lengthsAndLowerBounds.Item2,
                            lengthsAndLowerBounds.Item1,
                            async indices =>
                        {
                            // ReSharper disable AccessToDisposedClosure
                            if (!await arrayUnpacker.ReadAsync(cancellationToken).ConfigureAwait(false))
                            {
                                SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                            }

                            result.SetValue(
                                await this._itemSerializer.UnpackFromAsync(arrayUnpacker, cancellationToken).ConfigureAwait(false),
                                indices
                                );
                            // ReSharper restore AccessToDisposedClosure
                        }
                            );
                    }

                    return(( TArray )( object )result);
                }
            }
        }
Beispiel #6
0
        protected internal override object UnpackFromCore(Unpacker unpacker)
#endif // !UNITY
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
            }

            if (UnpackHelpers.GetItemsCount(unpacker) != 2)
            {
                SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as 2 element array.");
            }

            using (var wholeUnpacker = unpacker.ReadSubtree())
            {
                if (!wholeUnpacker.Read())
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                MessagePackExtendedTypeObject metadata;
                try
                {
                    metadata = wholeUnpacker.LastReadData.AsMessagePackExtendedTypeObject();
                }
                catch (InvalidOperationException ex)
                {
                    SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as ext type.", ex);
                    metadata = default(MessagePackExtendedTypeObject);                        // never reaches
                }

                if (metadata.TypeCode != this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray])
                {
                    SerializationExceptions.ThrowSerializationException(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            "Multidimensional array must be encoded as ext type 0x{0:X2}.",
                            this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray]
                            )
                        );
                }

                int[] lengths, lowerBounds;

                using (var arrayMetadata = new MemoryStream(metadata.Body))
                    using (var metadataUnpacker = Unpacker.Create(arrayMetadata, false))
                    {
                        if (!metadataUnpacker.Read())
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        if (!metadataUnpacker.IsArrayHeader)
                        {
                            SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                        }

                        if (UnpackHelpers.GetItemsCount(metadataUnpacker) != 2)
                        {
                            SerializationExceptions.ThrowSerializationException("Multidimensional metadata array must be encoded as 2 element array.");
                        }

                        this.ReadArrayMetadata(metadataUnpacker, out lengths, out lowerBounds);
                    }

#if SILVERLIGHT
                // Simulate lowerbounds because Array.Initialize() in Silverlight does not support lowerbounds.
                var inflatedLengths = new int[lengths.Length];
                for (var i = 0; i < lowerBounds.Length; i++)
                {
                    inflatedLengths[i] = lengths[i] + lowerBounds[i];
                }
#endif // SILVERLIGHT
                if (!wholeUnpacker.Read())
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                if (!wholeUnpacker.IsArrayHeader)
                {
                    SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                }

                using (var arrayUnpacker = wholeUnpacker.ReadSubtree())
                {
                    var result =
                        Array.CreateInstance(
#if !UNITY
                            typeof(TItem),
#else
                            this._itemType,
#endif // !UNITY
#if !SILVERLIGHT
                            lengths,
                            lowerBounds
#else
                            inflatedLengths
#endif // !SILVERLIGHT
                            );

                    var totalLength = UnpackHelpers.GetItemsCount(arrayUnpacker);
                    if (totalLength > 0)
                    {
                        ForEach(
                            result,
                            totalLength,
                            lowerBounds,
                            lengths,
                            indices =>
                        {
                            // ReSharper disable AccessToDisposedClosure
                            if (!arrayUnpacker.Read())
                            {
                                SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                            }

                            result.SetValue(
                                this._itemSerializer.UnpackFrom(arrayUnpacker),
                                indices
                                );
                            // ReSharper restore AccessToDisposedClosure
                        }
                            );
                    }

#if !UNITY
                    return(( TArray )( object )result);
#else
                    return(result);
#endif // !UNITY
                }
            }
        }