Exemplo n.º 1
0
            public void Dispose()
            {
                writer.Dispose();

                long position = destination.Position;
                uint length   = (uint)(position - (headerPosition) - 16);

                destination.Seek(headerPosition + 8, SeekOrigin.Begin);
                DataStream.WriteUInt32(destination, length);

                destination.Seek(position, SeekOrigin.Begin);
            }
        public static void Serialize(Stream destination, Type type, ICollection objects, CriTableWriterSettings settings)
        {
            ArrayList arrayList = null;

            if (objects != null)
            {
                arrayList = new ArrayList(objects);
            }

            CriTableWriter tableWriter = CriTableWriter.Create(destination, settings);

            string tableName = type.Name;
            CriSerializableAttribute serAttribute = type.GetCustomAttribute <CriSerializableAttribute>();

            if (serAttribute != null && !string.IsNullOrEmpty(serAttribute.TableName))
            {
                tableName = serAttribute.TableName;
            }

            tableWriter.WriteStartTable(tableName);

            SortedList <int, PropertyInfo> sortedProperties = new SortedList <int, PropertyInfo>();

            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                // Add the properties in order
                CriIgnoreAttribute ignoreAttribute = propertyInfo.GetCustomAttribute <CriIgnoreAttribute>();
                if (ignoreAttribute != null)
                {
                    continue;
                }

                // Ignore the properties that are not supportable
                if (propertyInfo.PropertyType != typeof(FileInfo) &&
                    propertyInfo.PropertyType != typeof(Stream) &&
                    propertyInfo.PropertyType != typeof(bool) &&
                    !propertyInfo.PropertyType.IsEnum &&
                    !CriField.FieldTypes.Contains(propertyInfo.PropertyType))
                {
                    continue;
                }

                CriFieldAttribute fieldAttribute = propertyInfo.GetCustomAttribute <CriFieldAttribute>();

                int order = ushort.MaxValue;
                if (fieldAttribute != null)
                {
                    order = fieldAttribute.Order;
                }

                while (sortedProperties.ContainsKey(order))
                {
                    order++;
                }

                sortedProperties.Add(order, propertyInfo);
            }

            tableWriter.WriteStartFieldCollection();
            foreach (var keyValuePair in sortedProperties)
            {
                PropertyInfo      propertyInfo   = keyValuePair.Value;
                CriFieldAttribute fieldAttribute = propertyInfo.GetCustomAttribute <CriFieldAttribute>();

                string fieldName    = propertyInfo.Name;
                Type   fieldType    = propertyInfo.PropertyType;
                object defaultValue = null;

                if (fieldType == typeof(FileInfo) || fieldType == typeof(Stream))
                {
                    fieldType = typeof(byte[]);
                }

                else if (fieldType == typeof(bool))
                {
                    fieldType = typeof(byte);
                }

                else if (fieldType.IsEnum)
                {
                    fieldType = Enum.GetUnderlyingType(propertyInfo.PropertyType);
                }

                if (fieldAttribute != null)
                {
                    if (!string.IsNullOrEmpty(fieldAttribute.FieldName))
                    {
                        fieldName = fieldAttribute.FieldName;
                    }
                }

                bool useDefaultValue = false;

                if (arrayList != null && arrayList.Count > 1)
                {
                    useDefaultValue = true;

                    defaultValue = propertyInfo.GetValue(arrayList[0]);

                    for (int i = 1; i < arrayList.Count; i++)
                    {
                        object objectValue = propertyInfo.GetValue(arrayList[i]);
                        if (defaultValue != null)
                        {
                            if (!defaultValue.Equals(objectValue))
                            {
                                useDefaultValue = false;
                                defaultValue    = null;
                                break;
                            }
                        }
                        else if (objectValue != null)
                        {
                            useDefaultValue = false;
                            defaultValue    = null;
                            break;
                        }
                    }
                }

                else if (arrayList == null || (arrayList != null && (arrayList.Count == 0 || (arrayList.Count == 1 && propertyInfo.GetValue(arrayList[0]) is null))))
                {
                    useDefaultValue = true;
                    defaultValue    = null;
                }

                if (defaultValue is bool boolean)
                {
                    defaultValue = (byte)(boolean ? 1 : 0);
                }

                else if (defaultValue is Enum)
                {
                    defaultValue = Convert.ChangeType(defaultValue, fieldType);
                }

                if (useDefaultValue)
                {
                    tableWriter.WriteField(fieldName, fieldType, defaultValue);
                }

                else
                {
                    tableWriter.WriteField(fieldName, fieldType);
                }
            }

            tableWriter.WriteEndFieldCollection();

            // Time for objects.
            if (arrayList != null)
            {
                foreach (object obj in arrayList)
                {
                    tableWriter.WriteStartRow();

                    int index = 0;
                    foreach (PropertyInfo propertyInfo in sortedProperties.Values)
                    {
                        object value        = propertyInfo.GetValue(obj);
                        Type   propertyType = propertyInfo.PropertyType;

                        if (value is bool boolean)
                        {
                            value = (byte)(boolean ? 1 : 0);
                        }

                        else if (value is Enum)
                        {
                            value = Convert.ChangeType(value, Enum.GetUnderlyingType(propertyType));
                        }

                        tableWriter.WriteValue(index, value);
                        index++;
                    }

                    tableWriter.WriteEndRow();
                }
            }

            tableWriter.WriteEndTable();
            tableWriter.Dispose();
        }