Represents a writer that provides a fast, non-cached, forward-only way of generating Edi data.
Inheritance: IDisposable
Example #1
0
        internal virtual void SerializeInternal(EdiWriter writer, object value, Type objectType)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            if (value == null)
            {
                writer.WriteNull();
                return;
            }
            objectType = objectType ?? value.GetType();
            var stack = new Stack <EdiStructure>();

            // If this is not a collection type asume this type is the interchange.
            if (!objectType.IsCollectionType())
            {
                stack.Push(new EdiStructure(EdiStructureType.Interchange, value));
                if (writer.WriteState == WriteState.Start)
                {
                    writer.WriteServiceStringAdvice();
                }
                SerializeStructure(writer, stack);
            }
            // else if this is indeed a collection type this must be a collection of messages.
            else
            {
                throw new NotImplementedException("Collection types are not supported as the root Type. Try to wrap List of Messages inside a container type.");
            }
        }
Example #2
0
        private static void SerializeStructure(EdiWriter writer, Stack <EdiStructure> stack, EdiPathComparer structuralComparer = null)
        {
            structuralComparer = structuralComparer ?? new EdiPathComparer(writer.Grammar);
            var structure = stack.Peek();
            var properies = structure.GetOrderedProperties(structuralComparer);

            foreach (var property in properies)
            {
                var value = property.Info.GetValue(structure.Instance);
                if (property.ValueInfo != null)
                {
                    var path         = (EdiPath)writer.Path;
                    var propertyPath = property.PathInfo.PathInternal;
                    var container    = stack.Skip(1).FirstOrDefault();
                    if (propertyPath.Segment.IsWildcard)
                    {
                        if (container.Descriptor.Path.HasValue && !container.Descriptor.Path.Value.Segment.IsWildcard)
                        {
                            propertyPath = new EdiPath(container.Descriptor.Path.Value.Segment, propertyPath.Element, propertyPath.Component);
                        }
                    }
                    if (propertyPath.Element.IsWildcard)
                    {
                        propertyPath = new EdiPath(propertyPath.Segment, new EdiPathFragment(structure.Index.ToString()), propertyPath.Component);
                    }
                    if (path.Segment != propertyPath.Segment ||
                        structuralComparer.Compare(path, propertyPath) > 0)
                    {
                        writer.WriteSegmentName(propertyPath.Segment);
                        path = (EdiPath)writer.Path;
                    }
                    // the following loop handles the write of unmapped preceding elements/components to the one being writen
                    // so that path progression stays intact even though we do not have all properties present on the model.

                    while (structuralComparer.Compare(path, propertyPath) < 0)
                    {
                        if (!path.Element.Equals(propertyPath.Element))
                        {
                            if (path.ElementIndex == 0 && writer.WriteState != WriteState.Component && writer.WriteState != WriteState.Element)
                            {
                                writer.WriteToken(EdiToken.Null);
                            }
                            else
                            {
                                writer.WriteToken(EdiToken.ElementStart);
                            }
                        }
                        else if (!path.Component.Equals(propertyPath.Component))
                        {
                            if (path.ComponentIndex == 0 && writer.WriteState != WriteState.Component)
                            {
                                writer.WriteToken(EdiToken.Null);
                            }
                            else
                            {
                                writer.WriteToken(EdiToken.ComponentStart);
                            }
                        }
                        path = (EdiPath)writer.Path;
                    }
                    // handle auto generated values.
                    if (property.AutoGenerationInfo != null)
                    {
                        // do stuff.
                        // there should be plenty of things to work with inside the EdiWriter itself.
                        // We are already keeping keeping track of current position with an index.
                        // But it may need to track more stuff in order for this to happen.
                    }
                    writer.WriteValue(value, property.ValueInfo.Picture, property.ValueInfo.Format);
                }
                else
                {
                    // this is somekind of structure. Group/Message/Segment/SegmentGroup/Element
                    // is it a collection of some kind?
                    var container = property.Attributes.InferStructure();
                    if (property.Info.PropertyType.IsCollectionType())
                    {
                        var itemType   = default(Type);
                        var collection = (value ?? new object[0]) as IList;
                        if (property.Info.PropertyType.IsArray)
                        {
                            itemType = property.Info.PropertyType.GetElementType();
                        }
                        else
                        {
                            itemType = property.Info.PropertyType.GetGenericArguments().First();
                        }
                        for (var i = 0; i < collection.Count; i++)
                        {
                            var item = collection[i];
                            if (stack.Count == 0)
                            {
                                throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {itemType.Name}");
                            }
                            while (stack.Peek().StructureType >= container)
                            {
                                var previous = stack.Pop();
                            }
                            stack.Push(new EdiStructure(container, stack.Peek(), property, item, i, null));
                            SerializeStructure(writer, stack, structuralComparer);
                        }
                    }
                    else
                    {
                        // or a simple Container.
                        if (stack.Count == 0)
                        {
                            throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {property.Info.PropertyType.Name}");
                        }
                        while (stack.Peek().StructureType >= container)
                        {
                            var previous = stack.Pop();
                        }
                        if (value == null)
                        {
                            continue;
                        }
                        stack.Push(new EdiStructure(container, stack.Peek(), property, value));
                        SerializeStructure(writer, stack, structuralComparer);
                    }
                }
            }
        }
Example #3
0
 /// <summary>
 /// Serializes the specified <see cref="object"/> and writes the EDI structure
 /// to a <c>Stream</c> using the specified <see cref="EdiWriter"/>.
 /// </summary>
 /// <param name="ediWriter">The <see cref="EdiWriter"/> used to write the EDI structure.</param>
 /// <param name="value">The <see cref="object"/> to serialize.</param>
 /// <param name="objectType">
 /// The type of the value being serialized.
 /// Specifing the type is optional.
 /// </param>
 public void Serialize(EdiWriter ediWriter, object value, Type objectType)
 {
     ediWriter.EnableCompression = EnableCompression;
     SerializeInternal(ediWriter, value, objectType);
     ediWriter.Close();
 }
Example #4
0
 /// <summary>
 /// Serializes the specified <see cref="Object"/> and writes the EDI structure
 /// to a <c>Stream</c> using the specified <see cref="EdiWriter"/>.
 /// </summary>
 /// <param name="ediWriter">The <see cref="EdiWriter"/> used to write the EDI structure.</param>
 /// <param name="value">The <see cref="Object"/> to serialize.</param>
 /// <param name="objectType">
 /// The type of the value being serialized.
 /// Specifing the type is optional.
 /// </param>
 public void Serialize(EdiWriter ediWriter, object value, Type objectType)
 {
     SerializeInternal(ediWriter, value, objectType);
 }
Example #5
0
        /// <summary>
        /// Serializes the structure.
        /// </summary>
        /// <param name="writer">Writer.</param>
        /// <param name="stack">Stack.</param>
        /// <param name="structuralComparer">Structural comparer.</param>
        private static void SerializeStructure(EdiWriter writer, Stack <EdiStructure> stack, EdiPathComparer structuralComparer = null)
        {
            structuralComparer = structuralComparer ?? new EdiPathComparer(writer.Grammar);
            var structure = stack.Peek();
            var properies = structure.GetOrderedProperties(structuralComparer);

            foreach (var property in properies)
            {
                var value = property.Info.GetValue(structure.Instance);
                if (property.ValueInfo != null)
                {
                    var path = (EdiPath)writer.Path;
                    if (path.Segment != property.PathInfo.Segment ||
                        structuralComparer.Compare(path, property.PathInfo.PathInternal) > 0)
                    {
                        writer.WriteSegmentName(property.PathInfo.Segment);
                    }

                    while (structuralComparer.Compare(path, property.PathInfo.PathInternal) < 0)
                    {
                        path = (EdiPath)writer.Path;
                        if (path.ElementIndex != property.PathInfo.ElementIndex)
                        {
                            writer.WriteToken(EdiToken.ElementStart);
                        }
                        else if (path.ComponentIndex != property.PathInfo.ComponentIndex)
                        {
                            writer.WriteToken(EdiToken.ComponentStart);
                        }
                    }
                    writer.WriteValue(value, property.ValueInfo.Picture, property.ValueInfo.Format);
                }
                else
                {
                    // this is somekind of structure. Group/Message/Segment/SegmentGroup/Element
                    // is it a collection of some kind?
                    var container = property.Attributes.InferStructure();
                    if (property.Info.PropertyType.IsCollectionType())
                    {
                        var itemType   = default(Type);
                        var collection = (value ?? new object[0]) as IList;
                        if (property.Info.PropertyType.IsArray)
                        {
                            itemType = property.Info.PropertyType.GetElementType();
                        }
                        else
                        {
                            itemType = property.Info.PropertyType.GetGenericArguments().First();
                        }
                        for (var i = 0; i < collection.Count; i++)
                        {
                            var item = collection[i];
                            if (stack.Count == 0)
                            {
                                throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {itemType.Name}");
                            }
                            while (stack.Peek().Container >= container)
                            {
                                var previous = stack.Pop();
                            }
                            stack.Push(new EdiStructure(container, item, i, null));
                            SerializeStructure(writer, stack, structuralComparer);
                        }
                    }
                    else
                    {
                        // or a simple Container.
                        if (stack.Count == 0)
                        {
                            throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {property.Info.PropertyType.Name}");
                        }
                        while (stack.Peek().Container >= container)
                        {
                            var previous = stack.Pop();
                        }
                        if (value == null)
                        {
                            continue;
                        }
                        stack.Push(new EdiStructure(container, value));
                        SerializeStructure(writer, stack, structuralComparer);
                    }
                }
            }
        }
Example #6
0
 /// <summary>
 /// Serializes the specified <see cref="object"/> and writes the EDI structure
 /// to a <c>Stream</c> using the specified <see cref="EdiWriter"/>.
 /// </summary>
 /// <param name="ediWriter">The <see cref="EdiWriter"/> used to write the EDI structure.</param>
 /// <param name="value">The <see cref="object"/> to serialize.</param>
 public void Serialize(EdiWriter ediWriter, object value)
 {
     ediWriter.EnableCompression = EnableCompression;
     SerializeInternal(ediWriter, value, null);
 }
Example #7
0
 /// <summary>
 /// Serializes the specified <see cref="Object"/> and writes the EDI structure
 /// to a <c>Stream</c> using the specified <see cref="EdiWriter"/>.
 /// </summary>
 /// <param name="ediWriter">The <see cref="EdiWriter"/> used to write the EDI structure.</param>
 /// <param name="value">The <see cref="Object"/> to serialize.</param>
 public void Serialize(EdiWriter ediWriter, object value)
 {
     SerializeInternal(ediWriter, value, null);
 }
Example #8
0
        internal static void WriteValue(EdiWriter writer, PrimitiveTypeCode typeCode, object value, Picture? picture, string format) {
            switch (typeCode) {
                case PrimitiveTypeCode.Char:
                    writer.WriteValue((char)value);
                    break;
                case PrimitiveTypeCode.CharNullable:
                    writer.WriteValue((value == null) ? (char?)null : (char)value);
                    break;
                case PrimitiveTypeCode.Boolean:
                    writer.WriteValue((bool)value);
                    break;
                case PrimitiveTypeCode.BooleanNullable:
                    writer.WriteValue((value == null) ? (bool?)null : (bool)value);
                    break;
                case PrimitiveTypeCode.SByte:
                    writer.WriteValue((sbyte)value, picture);
                    break;
                case PrimitiveTypeCode.SByteNullable:
                    writer.WriteValue((value == null) ? (sbyte?)null : (sbyte)value, picture);
                    break;
                case PrimitiveTypeCode.Int16:
                    writer.WriteValue((short)value, picture);
                    break;
                case PrimitiveTypeCode.Int16Nullable:
                    writer.WriteValue((value == null) ? (short?)null : (short)value, picture);
                    break;
                case PrimitiveTypeCode.UInt16:
                    writer.WriteValue((ushort)value, picture);
                    break;
                case PrimitiveTypeCode.UInt16Nullable:
                    writer.WriteValue((value == null) ? (ushort?)null : (ushort)value, picture);
                    break;
                case PrimitiveTypeCode.Int32:
                    writer.WriteValue((int)value, picture);
                    break;
                case PrimitiveTypeCode.Int32Nullable:
                    writer.WriteValue((value == null) ? (int?)null : (int)value, picture);
                    break;
                case PrimitiveTypeCode.Byte:
                    writer.WriteValue((byte)value, picture);
                    break;
                case PrimitiveTypeCode.ByteNullable:
                    writer.WriteValue((value == null) ? (byte?)null : (byte)value, picture);
                    break;
                case PrimitiveTypeCode.UInt32:
                    writer.WriteValue((uint)value, picture);
                    break;
                case PrimitiveTypeCode.UInt32Nullable:
                    writer.WriteValue((value == null) ? (uint?)null : (uint)value);
                    break;
                case PrimitiveTypeCode.Int64:
                    writer.WriteValue((long)value, picture);
                    break;
                case PrimitiveTypeCode.Int64Nullable:
                    writer.WriteValue((value == null) ? (long?)null : (long)value, picture);
                    break;
                case PrimitiveTypeCode.UInt64:
                    writer.WriteValue((ulong)value, picture);
                    break;
                case PrimitiveTypeCode.UInt64Nullable:
                    writer.WriteValue((value == null) ? (ulong?)null : (ulong)value, picture);
                    break;
                case PrimitiveTypeCode.Single:
                    writer.WriteValue((float)value, picture);
                    break;
                case PrimitiveTypeCode.SingleNullable:
                    writer.WriteValue((value == null) ? (float?)null : (float)value);
                    break;
                case PrimitiveTypeCode.Double:
                    writer.WriteValue((double)value, picture);
                    break;
                case PrimitiveTypeCode.DoubleNullable:
                    writer.WriteValue((value == null) ? (double?)null : (double)value, picture);
                    break;
                case PrimitiveTypeCode.DateTime:
                    writer.WriteValue((DateTime)value, format);
                    break;
                case PrimitiveTypeCode.DateTimeNullable:
                    writer.WriteValue((value == null) ? (DateTime?)null : (DateTime)value, format);
                    break;
                case PrimitiveTypeCode.DateTimeOffset:
                    writer.WriteValue((DateTimeOffset)value, format);
                    break;
                case PrimitiveTypeCode.DateTimeOffsetNullable:
                    writer.WriteValue((value == null) ? (DateTimeOffset?)null : (DateTimeOffset)value, format);
                    break;
                case PrimitiveTypeCode.Decimal:
                    writer.WriteValue((decimal)value, picture);
                    break;
                case PrimitiveTypeCode.DecimalNullable:
                    writer.WriteValue((value == null) ? (decimal?)null : (decimal)value, picture);
                    break;
                case PrimitiveTypeCode.Guid:
                    writer.WriteValue((Guid)value);
                    break;
                case PrimitiveTypeCode.GuidNullable:
                    writer.WriteValue((value == null) ? (Guid?)null : (Guid)value);
                    break;
                case PrimitiveTypeCode.TimeSpan:
                    writer.WriteValue((TimeSpan)value);
                    break;
                case PrimitiveTypeCode.TimeSpanNullable:
                    writer.WriteValue((value == null) ? (TimeSpan?)null : (TimeSpan)value);
                    break;
#if !PORTABLE
                case PrimitiveTypeCode.BigInteger:
                    // this will call to WriteValue(object)
                    writer.WriteValue((BigInteger)value);
                    break;
                case PrimitiveTypeCode.BigIntegerNullable:
                    // this will call to WriteValue(object)
                    writer.WriteValue((value == null) ? (BigInteger?)null : (BigInteger)value);
                    break;
#endif
                case PrimitiveTypeCode.Uri:
                    writer.WriteValue((Uri)value);
                    break;
                case PrimitiveTypeCode.String:
                    writer.WriteValue((string)value, picture);
                    break;
                case PrimitiveTypeCode.Bytes:
                    writer.WriteValue((byte[])value);
                    break;
#if !(PORTABLE || DOTNET)
                case PrimitiveTypeCode.DBNull:
                    writer.WriteNull();
                    break;
#endif
                default:
#if !PORTABLE
                    if (value is IConvertible) {
                        // the value is a non-standard IConvertible
                        // convert to the underlying value and retry
                        IConvertible convertable = (IConvertible)value;

                        TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertable);

                        // if convertable has an underlying typecode of Object then attempt to convert it to a string
                        PrimitiveTypeCode resolvedTypeCode = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? PrimitiveTypeCode.String : typeInformation.TypeCode;
                        Type resolvedType = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? typeof(string) : typeInformation.Type;

                        object convertedValue = convertable.ToType(resolvedType, CultureInfo.InvariantCulture);

                        WriteValue(writer, resolvedTypeCode, convertedValue, picture, format);
                        break;
                    } else
#endif
                    {
                        WriteValue(writer, PrimitiveTypeCode.String, $"{value}", picture, format);
                        break;
                        // consider throwing some times...
                        //throw CreateUnsupportedTypeException(writer, value);
                    }
            }
        }
Example #9
0
 internal static EdiWriterException Create(EdiWriter writer, string message, Exception ex)
 {
     return Create(writer.ContainerPath, message, ex);
 }
Example #10
0
 private static EdiWriterException CreateUnsupportedTypeException(EdiWriter writer, object value) {
     return EdiWriterException.Create(writer, "Unsupported type: {0}. Use the EdiSerializer class to get the object's EDI representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
 }
Example #11
0
 /// <summary>
 /// Create the specified writer, message and ex.
 /// </summary>
 /// <param name="writer">Writer.</param>
 /// <param name="message">Message.</param>
 /// <param name="ex">Ex.</param>
 internal static EdiWriterException Create(EdiWriter writer, string message, Exception ex)
 {
     return(Create(writer.ContainerPath, message, ex));
 }
Example #12
0
        private static void SerializeStructure(EdiWriter writer, Stack <EdiStructure> stack, EdiPathComparer structuralComparer = null)
        {
            structuralComparer = structuralComparer ?? new EdiPathComparer(writer.Grammar);
            var structure = stack.Peek();
            var properies = structure.GetOrderedProperties(structuralComparer);

            foreach (var property in properies)
            {
                var value = property.Info.GetValue(structure.Instance);
                if (property.ValueInfo != null)
                {
                    var path = (EdiPath)writer.Path;
                    if (path.Segment != property.PathInfo.Segment ||
                        structuralComparer.Compare(path, property.PathInfo.PathInternal) > 0)
                    {
                        writer.WriteSegmentName(property.PathInfo.Segment);
                        path = (EdiPath)writer.Path;
                    }
                    // the following loop handles the write of unmapped preceding elements/components to the one being writen
                    // so that path progression stays intact even though we do not have all properties present on the model.
                    // TODO: Potentialy this is related to compression.

                    while (structuralComparer.Compare(path, property.PathInfo.PathInternal) < 0)
                    {
                        path = (EdiPath)writer.Path;
                        if (path.ElementIndex == 0 && writer.WriteState != WriteState.Component && writer.WriteState != WriteState.Element)
                        {
                            writer.WriteToken(EdiToken.Null);
                        }
                        else if (path.ElementIndex != property.PathInfo.ElementIndex)
                        {
                            writer.WriteToken(EdiToken.ElementStart);
                        }
                        else if (path.ComponentIndex == 0 && writer.WriteState != WriteState.Component && writer.WriteState != WriteState.Element)
                        {
                            writer.WriteToken(EdiToken.Null);
                        }
                        else if (path.ComponentIndex != property.PathInfo.ComponentIndex)
                        {
                            writer.WriteToken(EdiToken.ComponentStart);
                        }
                    }
                    writer.WriteValue(value, property.ValueInfo.Picture, property.ValueInfo.Format);
                }
                else
                {
                    // this is somekind of structure. Group/Message/Segment/SegmentGroup/Element
                    // is it a collection of some kind?
                    var container = property.Attributes.InferStructure();
                    if (property.Info.PropertyType.IsCollectionType())
                    {
                        var itemType   = default(Type);
                        var collection = (value ?? new object[0]) as IList;
                        if (property.Info.PropertyType.IsArray)
                        {
                            itemType = property.Info.PropertyType.GetElementType();
                        }
                        else
                        {
                            itemType = property.Info.PropertyType.GetGenericArguments().First();
                        }
                        for (var i = 0; i < collection.Count; i++)
                        {
                            var item = collection[i];
                            if (stack.Count == 0)
                            {
                                throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {itemType.Name}");
                            }
                            while (stack.Peek().StructureType >= container)
                            {
                                var previous = stack.Pop();
                            }
                            stack.Push(new EdiStructure(container, stack.Peek(), property, item, i, null));
                            SerializeStructure(writer, stack, structuralComparer);
                        }
                    }
                    else
                    {
                        // or a simple Container.
                        if (stack.Count == 0)
                        {
                            throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {property.Info.PropertyType.Name}");
                        }
                        while (stack.Peek().StructureType >= container)
                        {
                            var previous = stack.Pop();
                        }
                        if (value == null)
                        {
                            continue;
                        }
                        stack.Push(new EdiStructure(container, stack.Peek(), property, value));
                        SerializeStructure(writer, stack, structuralComparer);
                    }
                }
            }
        }
Example #13
0
 private static EdiWriterException CreateUnsupportedTypeException(EdiWriter writer, object value)
 {
     return(EdiWriterException.Create(writer, "Unsupported type: {0}. Use the EdiSerializer class to get the object's EDI representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null));
 }
Example #14
0
        internal static void WriteValue(EdiWriter writer, PrimitiveTypeCode typeCode, object value, Picture?picture, string format)
        {
            switch (typeCode)
            {
            case PrimitiveTypeCode.Char:
                writer.WriteValue((char)value);
                break;

            case PrimitiveTypeCode.CharNullable:
                writer.WriteValue((value == null) ? (char?)null : (char)value);
                break;

            case PrimitiveTypeCode.Boolean:
                writer.WriteValue((bool)value);
                break;

            case PrimitiveTypeCode.BooleanNullable:
                writer.WriteValue((value == null) ? (bool?)null : (bool)value);
                break;

            case PrimitiveTypeCode.SByte:
                writer.WriteValue((sbyte)value, picture);
                break;

            case PrimitiveTypeCode.SByteNullable:
                writer.WriteValue((value == null) ? (sbyte?)null : (sbyte)value, picture);
                break;

            case PrimitiveTypeCode.Int16:
                writer.WriteValue((short)value, picture);
                break;

            case PrimitiveTypeCode.Int16Nullable:
                writer.WriteValue((value == null) ? (short?)null : (short)value, picture);
                break;

            case PrimitiveTypeCode.UInt16:
                writer.WriteValue((ushort)value, picture);
                break;

            case PrimitiveTypeCode.UInt16Nullable:
                writer.WriteValue((value == null) ? (ushort?)null : (ushort)value, picture);
                break;

            case PrimitiveTypeCode.Int32:
                writer.WriteValue((int)value, picture);
                break;

            case PrimitiveTypeCode.Int32Nullable:
                writer.WriteValue((value == null) ? (int?)null : (int)value, picture);
                break;

            case PrimitiveTypeCode.Byte:
                writer.WriteValue((byte)value, picture);
                break;

            case PrimitiveTypeCode.ByteNullable:
                writer.WriteValue((value == null) ? (byte?)null : (byte)value, picture);
                break;

            case PrimitiveTypeCode.UInt32:
                writer.WriteValue((uint)value, picture);
                break;

            case PrimitiveTypeCode.UInt32Nullable:
                writer.WriteValue((value == null) ? (uint?)null : (uint)value);
                break;

            case PrimitiveTypeCode.Int64:
                writer.WriteValue((long)value, picture);
                break;

            case PrimitiveTypeCode.Int64Nullable:
                writer.WriteValue((value == null) ? (long?)null : (long)value, picture);
                break;

            case PrimitiveTypeCode.UInt64:
                writer.WriteValue((ulong)value, picture);
                break;

            case PrimitiveTypeCode.UInt64Nullable:
                writer.WriteValue((value == null) ? (ulong?)null : (ulong)value, picture);
                break;

            case PrimitiveTypeCode.Single:
                writer.WriteValue((float)value, picture);
                break;

            case PrimitiveTypeCode.SingleNullable:
                writer.WriteValue((value == null) ? (float?)null : (float)value);
                break;

            case PrimitiveTypeCode.Double:
                writer.WriteValue((double)value, picture);
                break;

            case PrimitiveTypeCode.DoubleNullable:
                writer.WriteValue((value == null) ? (double?)null : (double)value, picture);
                break;

            case PrimitiveTypeCode.DateTime:
                writer.WriteValue((DateTime)value, format);
                break;

            case PrimitiveTypeCode.DateTimeNullable:
                writer.WriteValue((value == null) ? (DateTime?)null : (DateTime)value, format);
                break;

            case PrimitiveTypeCode.DateTimeOffset:
                writer.WriteValue((DateTimeOffset)value, format);
                break;

            case PrimitiveTypeCode.DateTimeOffsetNullable:
                writer.WriteValue((value == null) ? (DateTimeOffset?)null : (DateTimeOffset)value, format);
                break;

            case PrimitiveTypeCode.Decimal:
                writer.WriteValue((decimal)value, picture);
                break;

            case PrimitiveTypeCode.DecimalNullable:
                writer.WriteValue((value == null) ? (decimal?)null : (decimal)value, picture);
                break;

            case PrimitiveTypeCode.Guid:
                writer.WriteValue((Guid)value);
                break;

            case PrimitiveTypeCode.GuidNullable:
                writer.WriteValue((value == null) ? (Guid?)null : (Guid)value);
                break;

            case PrimitiveTypeCode.TimeSpan:
                writer.WriteValue((TimeSpan)value);
                break;

            case PrimitiveTypeCode.TimeSpanNullable:
                writer.WriteValue((value == null) ? (TimeSpan?)null : (TimeSpan)value);
                break;

#if !PORTABLE
            case PrimitiveTypeCode.BigInteger:
                // this will call to WriteValue(object)
                writer.WriteValue((BigInteger)value);
                break;

            case PrimitiveTypeCode.BigIntegerNullable:
                // this will call to WriteValue(object)
                writer.WriteValue((value == null) ? (BigInteger?)null : (BigInteger)value);
                break;
#endif
            case PrimitiveTypeCode.Uri:
                writer.WriteValue((Uri)value);
                break;

            case PrimitiveTypeCode.String:
                writer.WriteValue((string)value, picture);
                break;

            case PrimitiveTypeCode.Bytes:
                writer.WriteValue((byte[])value);
                break;

#if !(PORTABLE || DOTNET)
            case PrimitiveTypeCode.DBNull:
                writer.WriteNull();
                break;
#endif
            default:
#if !PORTABLE
                if (value is IConvertible)
                {
                    // the value is a non-standard IConvertible
                    // convert to the underlying value and retry
                    IConvertible convertable = (IConvertible)value;

                    TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertable);

                    // if convertable has an underlying typecode of Object then attempt to convert it to a string
                    PrimitiveTypeCode resolvedTypeCode = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? PrimitiveTypeCode.String : typeInformation.TypeCode;
                    Type resolvedType = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? typeof(string) : typeInformation.Type;

                    object convertedValue = convertable.ToType(resolvedType, CultureInfo.InvariantCulture);

                    WriteValue(writer, resolvedTypeCode, convertedValue, picture, format);
                    break;
                }
                else
#endif
                {
                    WriteValue(writer, PrimitiveTypeCode.String, $"{value}", picture, format);
                    break;
                    // consider throwing some times...
                    //throw CreateUnsupportedTypeException(writer, value);
                }
            }
        }