예제 #1
0
        /// <summary>
        /// Registers a type definition with this dictionary. Additional .NET types can be passed that will be translated to the
        /// type referenced in the type definition. If a type with same numeric type identifier is already in the dictionary it
        /// will be replaced.
        /// </summary>
        /// <param name="type">type definition</param>
        /// <param name="alternativeTypes">alternative .NET types that map to this type</param>
        public void AddType(FudgeFieldType type, params Type[] alternativeTypes)
        {
            if (type == null)
            {
                throw new ArgumentNullException("Must not provide a null FudgeFieldType to add.");
            }

            rwLock.AcquireWriterLock(Timeout.Infinite);
            try
            {                
                if (!(type is ISecondaryFieldType))
                {
                    int newLength = Math.Max(type.TypeId + 1, typesById.Length);
                    var newArray = new FudgeFieldType[newLength];
                    typesById.CopyTo(newArray, 0);
                    newArray[type.TypeId] = type;
                    typesById = newArray;
                }

                // TODO 2009-12-14 Andrew -- the secondary type mechanism needs review; not sure how best to do it in Java and I would like to keep the APIs similar in spirit

                typesByCSharpType[type.CSharpType] = type;
                foreach (Type alternativeType in alternativeTypes)
                {
                    typesByCSharpType[alternativeType] = type;
                }
            }
            finally
            {
                rwLock.ReleaseWriterLock();
            }
        }
예제 #2
0
        /// <inheritdoc />
        public virtual void Add(string name, int?ordinal, FudgeFieldType type, object value)
        {
            if (ordinal.HasValue && (ordinal < short.MinValue || ordinal > short.MaxValue))
            {
                throw new ArgumentOutOfRangeException("ordinal", "Ordinal must be within signed 16-bit range");
            }
            if (type == null)
            {
                // See if we can derive it
                type = context.TypeHandler.DetermineTypeFromValue(value);
                if (type == null)
                {
                    throw new ArgumentException("Cannot determine a Fudge type for value " + value + " of type " + value.GetType());
                }
            }

            if (type == FudgeMsgFieldType.Instance && !(value is FudgeMsg))
            {
                // Copy the fields across to a new message
                value = CopyContainer((IFudgeFieldContainer)value);
            }

            // Adjust values to the lowest possible representation.
            value = type.Minimize(value, ref type);

            FudgeMsgField field = new FudgeMsgField(type, value, name, (short?)ordinal);

            fields.Add(field);
        }
예제 #3
0
        /// <inheritdoc/>
        public override object Minimize(object value, ref FudgeFieldType type)
        {
            type = wireType;
            object newValue = outputConverter((T)value);

            return(wireType.Minimize(newValue, ref type));       // Allow the wire type to minimise further if it wants
        }
예제 #4
0
 /// <summary>
 /// Gets the .NET name of a <c>FudgeFieldType</c> object.
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 protected string GetTypeName(FudgeFieldType type)
 {
     if (type == null)
     {
         throw new NullReferenceException("Must specify a type.");
     }
     return(type.CSharpType.Name);
 }
예제 #5
0
 /// <summary>
 /// Creates a new message field.
 /// </summary>
 /// <param name="type">field data type</param>
 /// <param name="value">field value</param>
 /// <param name="name">field name, or null for no field name</param>
 /// <param name="ordinal">ordinal index, or null for no ordinal index</param>
 public FudgeMsgField(FudgeFieldType type, object value, string name, short?ordinal)
 {
     if (type == null)
     {
         throw new ArgumentNullException("Must specify a type for this field.");
     }
     this.type    = type;
     this.value   = value;
     this.name    = name;
     this.ordinal = ordinal;
 }
예제 #6
0
 /// <summary>
 /// Creates a new message field.
 /// </summary>
 /// <param name="type">field data type</param>
 /// <param name="value">field value</param>
 /// <param name="name">field name, or null for no field name</param>
 /// <param name="ordinal">ordinal index, or null for no ordinal index</param>
 public FudgeMsgField(FudgeFieldType type, object value, string name, short? ordinal)
 {
     if (type == null)
     {
         throw new ArgumentNullException("Must specify a type for this field.");
     }
     this.type = type;
     this.value = value;
     this.name = name;
     this.ordinal = ordinal;
 }
예제 #7
0
        /// <summary>
        /// Returns the type definition most appropiate for a value type.
        /// </summary>
        /// <param name="csharpType">type of a value</param>
        /// <returns>type definition</returns>
        public FudgeFieldType GetByCSharpType(Type csharpType)
        {
            if (csharpType == null)
            {
                return null;
            }
            
            rwLock.AcquireReaderLock(Timeout.Infinite);

            FudgeFieldType result = null;
            typesByCSharpType.TryGetValue(csharpType, out result);
            
            rwLock.ReleaseReaderLock();
            return result;
        }
예제 #8
0
        /// <summary>
        /// Cosntructs a new <c>SeondaryFieldType</c> without conversion functions.
        /// </summary>
        /// <param name="wireType">Canonical type that values of this type will be represented as when encoded.</param>
        /// <remarks>
        /// Derived types can use this form if they wish to override <see cref="Minimize"/> and <see cref="ConvertValueFrom"/>
        /// directly rather than supplying conversion functions.
        /// </remarks>
        protected SecondaryFieldType(FudgeFieldType wireType)
            : base(wireType.TypeId, wireType.IsVariableSize, wireType.FixedSize)
        {
            if (wireType == null)
            {
                throw new ArgumentNullException("wireType");
            }
            if (wireType.CSharpType != typeof(RawType))
            {
                throw new ArgumentException("wireType does not match RawType for " + GetType().Name);
            }

            // Use overrides instead of delegates
            this.inputConverter  = (raw => ConvertFromWire(raw));
            this.outputConverter = (value => ConvertToWire(value));
        }
예제 #9
0
        /// <summary>
        /// Tests if this object is equal to another. Two <c>FudgeFieldType</c>s are equal iff they have the same numeric type identifier.
        /// </summary>
        /// <param name="obj">the object to compare to</param>
        /// <returns>true iff the objects are equal</returns>
        public override bool Equals(object obj)
        {
            if (obj == this)
            {
                return(true);
            }
            FudgeFieldType other = obj as FudgeFieldType;

            if (other == null)
            {
                return(false);
            }
            if (TypeId != other.TypeId)
            {
                return(false);
            }

            // Don't bother checking the rest of it.
            return(true);
        }
예제 #10
0
            /// <summary>
            /// Determines the <c>FudgeFieldType</c> of a C# value.
            /// </summary>
            /// <param name="value">value whose type is to be determined</param>
            /// <returns>the appropriate <c>FudgeFieldType</c> instance</returns>
            public FudgeFieldType DetermineTypeFromValue(object value)
            {
                if (value == null)
                {
                    throw new ArgumentNullException("Cannot determine type for null value.");
                }
                FudgeFieldType type = typeDictionary.GetByCSharpType(value.GetType());

                if (type == null)
                {
                    // Couple of special cases
                    if (value is UnknownFudgeFieldValue)
                    {
                        UnknownFudgeFieldValue unknownValue = (UnknownFudgeFieldValue)value;
                        type = unknownValue.Type;
                    }
                    else if (value is IFudgeFieldContainer)
                    {
                        type = FudgeMsgFieldType.Instance;
                    }
                }
                return(type);
            }
예제 #11
0
            /// <summary>
            /// Converts the supplied value to a base type using the corresponding FudgeFieldType definition. The supplied .NET type
            /// is resolved to a registered FudgeFieldType. The <c>ConvertValueFrom</c> method on the registered type is then used
            /// to convert the value.
            /// </summary>
            /// <param name="value">value to convert</param>
            /// <param name="type">.NET target type</param>
            /// <returns>the converted value</returns>
            public object ConvertType(object value, Type type)
            {
                if (value == null)
                {
                    return(null);
                }
                if (value.GetType() == type)
                {
                    return(value);
                }

                if (!type.IsAssignableFrom(value.GetType()))
                {
                    FudgeFieldType fieldType = typeDictionary.GetByCSharpType(type);
                    if (fieldType == null)
                    {
                        throw new InvalidCastException("No registered field type for " + type.Name);
                    }

                    value = fieldType.ConvertValueFrom(value);
                }
                return(value);
            }
예제 #12
0
        /// <summary>
        /// Cosntructs a new <c>SeondaryFieldType</c>.
        /// </summary>
        /// <param name="wireType">Canonical type that values of this type will be represented as when encoded.</param>
        /// <param name="inputConverter">Function to convert values from canonical type to this type.</param>
        /// <param name="outputConverter">Function to convert values from this type to the canonical type.</param>
        public SecondaryFieldType(FudgeFieldType wireType, Converter <RawType, T> inputConverter, Converter <T, RawType> outputConverter)
            : base(wireType.TypeId, wireType.IsVariableSize, wireType.FixedSize)
        {
            if (wireType == null)
            {
                throw new ArgumentNullException("wireType");
            }
            if (inputConverter == null)
            {
                throw new ArgumentNullException("inputConverter");
            }
            if (outputConverter == null)
            {
                throw new ArgumentNullException("outputConverter");
            }
            if (wireType.CSharpType != typeof(RawType))
            {
                throw new ArgumentException("wireType does not match RawType for " + GetType().Name);
            }

            this.wireType        = wireType;
            this.inputConverter  = inputConverter;
            this.outputConverter = outputConverter;
        }
예제 #13
0
 /// <summary>
 /// Override <c>Minimize</c> where you wish to be able to reduce to a lower type as fields are added to messages.
 /// </summary>
 /// <remarks>
 /// <c>Minimize</c> is used to reduce integers to their smallest form, but can also be used to convert
 /// non-primitive types (e.g. GUID) to primitive ones (e.g. byte[16]) as they are added.
 /// </remarks>
 /// <param name="value">Value to reduce.</param>
 /// <param name="type">Current field type - update this if you minimize to a different type.</param>
 /// <returns>Minimized value.</returns>
 public virtual object Minimize(object value, ref FudgeFieldType type)
 {
     return(value);
 }
예제 #14
0
 /// <summary>
 /// Gets the .NET name of a <c>FudgeFieldType</c> object.
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 protected string GetTypeName(FudgeFieldType type)
 {
     if (type == null)
     {
         throw new NullReferenceException("Must specify a type.");
     }
     return type.CSharpType.Name;
 }
예제 #15
0
        /// <summary>
        /// Registers a type definition with this dictionary. Additional .NET types can be passed that will be translated to the
        /// type referenced in the type definition. If a type with same numeric type identifier is already in the dictionary it
        /// will be replaced.
        /// </summary>
        /// <param name="type">type definition</param>
        /// <param name="alternativeTypes">alternative .NET types that map to this type</param>
        public void AddType(FudgeFieldType type, params Type[] alternativeTypes)
        {
            if (type == null)
            {
                throw new ArgumentNullException("Must not provide a null FudgeFieldType to add.");
            }

            rwLock.AcquireWriterLock(Timeout.Infinite);
            try
            {
                if (!(type is ISecondaryFieldType))
                {
                    int newLength = Math.Max(type.TypeId + 1, typesById.Length);
                    var newArray = new FudgeFieldType[newLength];
                    typesById.CopyTo(newArray, 0);
                    newArray[type.TypeId] = type;
                    typesById = newArray;
                }

                // TODO 2009-12-14 Andrew -- the secondary type mechanism needs review; not sure how best to do it in Java and I would like to keep the APIs similar in spirit

                typesByCSharpType[type.CSharpType] = type;
                foreach (Type alternativeType in alternativeTypes)
                {
                    typesByCSharpType[alternativeType] = type;
                }
            }
            finally
            {
                rwLock.ReleaseWriterLock();
            }
        }
예제 #16
0
 /// <summary>
 /// Override <c>Minimize</c> where you wish to be able to reduce to a lower type as fields are added to messages.
 /// </summary>
 /// <remarks>
 /// <c>Minimize</c> is used to reduce integers to their smallest form, but can also be used to convert
 /// non-primitive types (e.g. GUID) to primitive ones (e.g. byte[16]) as they are added.
 /// </remarks>
 /// <param name="value">Value to reduce.</param>
 /// <param name="type">Current field type - update this if you minimize to a different type.</param>
 /// <returns>Minimized value.</returns>
 public virtual object Minimize(object value, ref FudgeFieldType type)
 {
     return value;
 }