Example #1
0
        protected SerializationInfo(Type objType, IFormatterConverter converter)
        {
            Type      = objType;
            Converter = converter;

            // create an instance of the object to get missing values from the field initializers.
            object instance = STDFFormatterServices.GetUninitializedObject(Type);

            FieldInfo[] fields = STDFFormatterServices.GetSerializeableFields(Type);

            Info = new SerializationInfoEntry[fields.Length];
            for (int i = 0; i < fields.Length; i++)
            {
                var    field          = fields[i];
                object value          = field.GetValue(instance);
                string itemCountField = (field.GetCustomAttribute <STDFAttribute>() ??
                                         field.GetCustomAttribute <STDFOptionalAttribute>())?.ItemCountProperty;
                var entry = new SerializationInfoEntry()
                {
                    Index          = i,
                    Name           = field.Name,
                    Type           = field.FieldType,
                    IsOptional     = field.GetCustomAttribute <STDFOptionalAttribute>() != null,
                    IsSet          = false,
                    ItemCountIndex = Array.FindIndex(fields, x => x.Name == itemCountField),
                    Value          = value,
                    MissingValue   = value
                };
                Info[i] = entry;
            }
        }
Example #2
0
        protected virtual void SerializeValue(int index, object currentValue, object originalValue = null)
        {
            SerializationInfoEntry entry = CurrentInfo.GetEntry(index);
            object missingValue          = entry.MissingValue;
            object defaultValue          = CurrentDefaults?.GetValue(index);

            // if field is not an optional field, then no further checking required,
            // just return the value as is
            if (entry.IsOptional)
            {
                // logic to determine what value to serialize
                //
                // Truth table:
                //
                // OM = Original = missing value
                // DV = Current = default value
                // MV = Current = missing value
                //
                // O D M
                // M V V   Action
                // - - -   -----------------------------------
                // 0 0 0   Write current value
                // 0 0 1   Write missing value
                // 0 1 0   Write current value
                // 0 1 1   Write missing value
                // 1 0 0   Write current value
                // 1 0 1   Write missing value
                // 1 1 0   Write missing value
                // 1 1 1   Write missing value

                int writeFlag = 0b000;
                writeFlag |= IsEqual(originalValue, missingValue) ? 0b100 : 0b000;
                writeFlag |= IsEqual(currentValue, defaultValue) ? 0b010 : 0b000;
                writeFlag |= IsEqual(currentValue, missingValue) ? 0b001 : 0b000;

                switch (writeFlag)
                {
                case 0b000:      // original value != missing && current value (!= default && != missing)
                case 0b010:      // original value != missing && current value (== default && != missing)
                case 0b100:      // original value == missing) && current value (!= default && != missing)
                    entry.Value          = currentValue;
                    entry.IsMissingValue = false;
                    break;

                default:          // all other combinations, return the missing value.
                    entry.Value          = missingValue;
                    entry.IsMissingValue = true;
                    break;
                }
            }
            else
            {
                entry.Value          = currentValue;
                entry.IsMissingValue = IsEqual(currentValue, missingValue);
            }
        }
Example #3
0
        protected virtual object DeserializeValue(int index)
        {
            SerializationInfoEntry entry = CurrentInfo.GetEntry(index);

            object currentValue = entry.Value;
            object missingValue = entry.MissingValue;
            object defaultValue = CurrentDefaults?.GetValue(index);

            // if field is not an optional field, then no further checking required,
            // just return the value as read from the instream (or initialized with missing value)
            if (entry.IsOptional)
            {
                // logic to determine which value to deserialize to (as read, missing, or default value)
                //
                // Truth table:
                //
                // NV = Value is null
                // MV = Value is missing value
                // DV = Value is default value
                //
                // N M D
                // V V V   Action
                // - - -   -----------------------------------
                // 0 0 0   Return value as read
                // 0 0 1   Return value as read
                // 0 1 0   Return default value
                // 0 1 1   Return default value
                // 1 0 0   Return value as read
                // 1 0 1   Return value as read
                // 1 1 0   Return default value
                // 1 1 1   Return default value

                int writeFlag = currentValue == null ? 0b100 : 0b000;
                writeFlag |= IsEqual(currentValue, missingValue) ? 0b010 : 0b000;
                writeFlag |= IsEqual(currentValue, defaultValue) ? 0b001 : 0b000;

                switch (writeFlag)
                {
                case 0b000:      // as read value (!= null && != missing && != default)
                case 0b001:      // as read value (!= null && != missing && == default)
                case 0b100:      // as read value (== null && != missing && != default)
                case 0b101:      // as read value (== null && != missing && == default)
                    return(currentValue);

                default:          // all other combinations, return the default value.
                    return(defaultValue);
                }
            }
            return(currentValue);
        }