/// <summary> /// Updates any fields which have an ordinal index only to include a field name if one is available in the taxonomy. The /// same taxonomy is passed to any submessages. /// </summary> /// <param name="taxonomy">taxonomy to set field names from</param> public void SetNamesFromTaxonomy(IFudgeTaxonomy taxonomy) { if (taxonomy == null) { return; } for (int i = 0; i < fields.Count; i++) { FudgeMsgField field = fields[i]; if ((field.Ordinal != null) && (field.Name == null)) { string nameFromTaxonomy = taxonomy.GetFieldName(field.Ordinal.Value); if (nameFromTaxonomy == null) { continue; } FudgeMsgField replacementField = new FudgeMsgField(field.Type, field.Value, nameFromTaxonomy, field.Ordinal); fields[i] = replacementField; } if (field.Value is FudgeMsg) { FudgeMsg subMsg = (FudgeMsg)field.Value; subMsg.SetNamesFromTaxonomy(taxonomy); } } }
private static int WriteField(BinaryWriter bw, FudgeFieldType type, object value, short?ordinal, string name, IFudgeTaxonomy taxonomy)// throws IOException { CheckOutputStream(bw); if (type == null) { throw new ArgumentNullException("Must provide the type of data encoded."); } if (value == null) { throw new ArgumentNullException("Must provide the value to encode."); } // First, normalize the name/ordinal bit NormalizeNameAndOrdinal(ref name, ref ordinal, taxonomy); // Reduce the value to minimal form value = type.Minimize(value, ref type); // Now do the field header int valueSize = type.IsVariableSize ? type.GetVariableSize(value, taxonomy) : type.FixedSize; int nWritten = WriteFieldHeader(bw, valueSize, type.IsVariableSize, type.TypeId, ordinal, name); // Finally the value if (value != null) { Debug.Assert(type != null); nWritten += WriteFieldValue(bw, type, value, valueSize, taxonomy); } return(nWritten); }
/// <summary> /// Returns the size, in bytes, of the the object if encoded with a given taxonomy. The size is calculated by <c>ComputeSize</c> and cached by this method. /// </summary> /// <param name="taxonomy">the taxonomy to use for encoding, or null to calculate the size without a taxonomy</param> /// <returns>the size of the encoded object in bytes</returns> public int GetSize(IFudgeTaxonomy taxonomy) { if (taxonomy == null) { if (noTaxonomySize == -1) { noTaxonomySize = ComputeSize(null); } return noTaxonomySize; } lock (this) { if (sizesByTaxonomy == null) { sizesByTaxonomy = new Dictionary<IFudgeTaxonomy, int>(); } int result; if (!sizesByTaxonomy.TryGetValue(taxonomy, out result)) { result = ComputeSize(taxonomy); sizesByTaxonomy.Add(taxonomy, result); } return result; } }
/// <summary> /// Returns the size, in bytes, of the the object if encoded with a given taxonomy. The size is calculated by <c>ComputeSize</c> and cached by this method. /// </summary> /// <param name="taxonomy">the taxonomy to use for encoding, or null to calculate the size without a taxonomy</param> /// <returns>the size of the encoded object in bytes</returns> public int GetSize(IFudgeTaxonomy taxonomy) { if (taxonomy == null) { if (noTaxonomySize == -1) { noTaxonomySize = ComputeSize(null); } return(noTaxonomySize); } lock (this) { if (sizesByTaxonomy == null) { sizesByTaxonomy = new Dictionary <IFudgeTaxonomy, int>(); } int result; if (!sizesByTaxonomy.TryGetValue(taxonomy, out result)) { result = ComputeSize(taxonomy); sizesByTaxonomy.Add(taxonomy, result); } return(result); } }
/// <summary> /// Calculates the total size of the envelope. This is the encoded size of the message within the envelope plus the 8 byte envelope header. /// </summary> /// <param name="taxonomy">optional taxonomy to encode the message with</param> /// <returns>total size in bytes</returns> public override int ComputeSize(IFudgeTaxonomy taxonomy) { int size = 0; // Message envelope header size += 8; size += message.GetSize(taxonomy); return(size); }
// TODO 2009-12-14 Andrew -- should we have a ToByteArray that accepts a taxonomy ? /// <inheritdoc /> public override int ComputeSize(IFudgeTaxonomy taxonomy) { int size = 0; foreach (FudgeMsgField field in fields) { size += field.GetSize(taxonomy); } return(size); }
/// <summary> /// Calculates the encoded size of this field in bytes. This is the encoded size of the /// underlying value as defined by the corresponding <c>FudgeFieldType</c>, the 2 byte /// field prefix, plus the ordinal index and field name if specified. If a taxonomy is /// specified and defines the field name, only the corresponding ordinal index would be /// written so the field name is not counted. /// </summary> /// <param name="taxonomy">taxonomy used to resolve field names, or null</param> /// <returns>the encoded size of this field in bytes</returns> public override int ComputeSize(IFudgeTaxonomy taxonomy) { int size = 0; // Field prefix size += 2; bool hasOrdinal = ordinal != null; bool hasName = name != null; if ((name != null) && (taxonomy != null)) { if (taxonomy.GetFieldOrdinal(name) != null) { hasOrdinal = true; hasName = false; } } if (hasOrdinal) { size += 2; } if (hasName) { // One for the size prefix size++; // Then for the UTF Encoding size += StringFieldType.Encoding.GetByteCount(name); } if (type.IsVariableSize) { int valueSize = type.GetVariableSize(value, taxonomy); if (valueSize <= 255) { size += valueSize + 1; } else if (valueSize <= short.MaxValue) { size += valueSize + 2; } else { size += valueSize + 4; } } else { size += type.FixedSize; } return(size); }
/// <inheritdoc/> public void StartMessage() { if (stack.Count > 0) { throw new InvalidOperationException("Attempting to start message when already started."); } memStream = new MemoryStream(); memWriter = new FudgeBinaryWriter(memStream); taxonomy = null; if (TaxonomyId.HasValue && context.TaxonomyResolver != null) { taxonomy = context.TaxonomyResolver.ResolveTaxonomy(TaxonomyId.Value); } stack.Push(new State(0, 0, false, false, 0)); }
/** * */ protected void ConsumeMessageEnvelope() //throws IOException { Debug.Assert(!eof); CurrentElement = FudgeStreamElement.MessageStart; if (bufferedByte.HasValue) { processingDirectives = bufferedByte.Value; bufferedByte = null; } else { byte?nextByte = SafelyReadOneByte(); if (nextByte.HasValue) { processingDirectives = nextByte.Value; } else { // Hit the end of the stream CurrentElement = FudgeStreamElement.NoElement; eof = true; return; } } schemaVersion = Reader.ReadByte(); taxonomyId = Reader.ReadInt16(); envelopeSize = Reader.ReadInt32(); if (FudgeContext.TaxonomyResolver != null) { IFudgeTaxonomy taxonomy = FudgeContext.TaxonomyResolver.ResolveTaxonomy(taxonomyId); this.taxonomy = taxonomy; } MessageProcessingState processingState = new MessageProcessingState(); processingState.Consumed = 8; processingState.MessageSize = envelopeSize; processingStack.Push(processingState); }
/// <inheritdoc cref="Fudge.FudgeFieldType.GetVariableSize(System.Object,Fudge.Taxon.IFudgeTaxonomy)" /> public override int GetVariableSize(string value, IFudgeTaxonomy taxonomy) { return(Encoding.GetByteCount(value)); }
/// <summary> /// Calculates the total size of the envelope. This is the encoded size of the message within the envelope plus the 8 byte envelope header. /// </summary> /// <param name="taxonomy">optional taxonomy to encode the message with</param> /// <returns>total size in bytes</returns> public override int ComputeSize(IFudgeTaxonomy taxonomy) { int size = 0; // Message envelope header size += 8; size += message.GetSize(taxonomy); return size; }
/// <summary> /// Calculates the encoded size of this field in bytes. This is the encoded size of the /// underlying value as defined by the corresponding <c>FudgeFieldType</c>, the 2 byte /// field prefix, plus the ordinal index and field name if specified. If a taxonomy is /// specified and defines the field name, only the corresponding ordinal index would be /// written so the field name is not counted. /// </summary> /// <param name="taxonomy">taxonomy used to resolve field names, or null</param> /// <returns>the encoded size of this field in bytes</returns> public override int ComputeSize(IFudgeTaxonomy taxonomy) { int size = 0; // Field prefix size += 2; bool hasOrdinal = ordinal != null; bool hasName = name != null; if ((name != null) && (taxonomy != null)) { if (taxonomy.GetFieldOrdinal(name) != null) { hasOrdinal = true; hasName = false; } } if (hasOrdinal) { size += 2; } if (hasName) { // One for the size prefix size++; // Then for the UTF Encoding size += StringFieldType.Encoding.GetByteCount(name); } if (type.IsVariableSize) { int valueSize = type.GetVariableSize(value, taxonomy); if (valueSize <= 255) { size += valueSize + 1; } else if (valueSize <= short.MaxValue) { size += valueSize + 2; } else { size += valueSize + 4; } } else { size += type.FixedSize; } return size; }
//throws IOException /** * */ protected void ConsumeMessageEnvelope() { Debug.Assert(!eof); CurrentElement = FudgeStreamElement.MessageStart; if (bufferedByte.HasValue) { processingDirectives = bufferedByte.Value; bufferedByte = null; } else { byte? nextByte = SafelyReadOneByte(); if (nextByte.HasValue) processingDirectives = nextByte.Value; else { // Hit the end of the stream CurrentElement = FudgeStreamElement.NoElement; eof = true; return; } } schemaVersion = Reader.ReadByte(); taxonomyId = Reader.ReadInt16(); envelopeSize = Reader.ReadInt32(); if (FudgeContext.TaxonomyResolver != null) { IFudgeTaxonomy taxonomy = FudgeContext.TaxonomyResolver.ResolveTaxonomy(taxonomyId); this.taxonomy = taxonomy; } MessageProcessingState processingState = new MessageProcessingState(); processingState.Consumed = 8; processingState.MessageSize = envelopeSize; processingStack.Push(processingState); }
/// <inheritdoc cref="Fudge.FudgeFieldType.GetVariableSize(System.Object,Fudge.Taxon.IFudgeTaxonomy)" /> public override int GetVariableSize(T[] value, IFudgeTaxonomy taxonomy) { return(value.Length * elementSize); }
private static int WriteFieldValue(BinaryWriter bw, FudgeFieldType type, object value, int valueSize, IFudgeTaxonomy taxonomy) //throws IOException { // Note that we fast-path types for which at compile time we know how to handle // in an optimized way. This is because this particular method is known to // be a massive hot-spot for performance. int nWritten = 0; switch (type.TypeId) { case FudgeTypeDictionary.BOOLEAN_TYPE_ID: bw.Write((bool)value); nWritten = 1; break; case FudgeTypeDictionary.SBYTE_TYPE_ID: bw.Write((sbyte)value); nWritten = 1; break; case FudgeTypeDictionary.SHORT_TYPE_ID: bw.Write((short)value); nWritten = 2; break; case FudgeTypeDictionary.INT_TYPE_ID: bw.Write((int)value); nWritten = 4; break; case FudgeTypeDictionary.LONG_TYPE_ID: bw.Write((long)value); nWritten = 8; break; case FudgeTypeDictionary.FLOAT_TYPE_ID: bw.Write((float)value); nWritten = 4; break; case FudgeTypeDictionary.DOUBLE_TYPE_ID: bw.Write((double)value); nWritten = 8; break; } if (nWritten == 0) { if (type.IsVariableSize) { nWritten = WriteVariableSize(bw, valueSize); } else { nWritten = type.FixedSize; } if (value is IFudgeFieldContainer) { IFudgeFieldContainer subMsg = (IFudgeFieldContainer)value; WriteMsgFields(bw, subMsg, taxonomy); } else { type.WriteValue(bw, value); } } return(nWritten); }
/// <summary> /// Calculates the size of an encoded value. This method must be provided for any variable size types. /// </summary> /// <param name="value">the value to calculate the size for</param> /// <param name="taxonomy">the taxonomy to encode against</param> /// <returns>the size in bytes of the encoded value</returns> public abstract int GetVariableSize(object value, IFudgeTaxonomy taxonomy);
//throws IOException private static int WriteMsgFields(BinaryWriter bw, IFudgeFieldContainer container, IFudgeTaxonomy taxonomy) { int nWritten = 0; foreach (IFudgeField field in container.GetAllFields()) { nWritten += WriteField(bw, field.Type, field.Value, field.Ordinal, field.Name, taxonomy); } return nWritten; }
//throws IOException private static int WriteFieldValue(BinaryWriter bw, FudgeFieldType type, object value, int valueSize, IFudgeTaxonomy taxonomy) { // Note that we fast-path types for which at compile time we know how to handle // in an optimized way. This is because this particular method is known to // be a massive hot-spot for performance. int nWritten = 0; switch (type.TypeId) { case FudgeTypeDictionary.BOOLEAN_TYPE_ID: bw.Write((bool)value); nWritten = 1; break; case FudgeTypeDictionary.SBYTE_TYPE_ID: bw.Write((sbyte)value); nWritten = 1; break; case FudgeTypeDictionary.SHORT_TYPE_ID: bw.Write((short)value); nWritten = 2; break; case FudgeTypeDictionary.INT_TYPE_ID: bw.Write((int)value); nWritten = 4; break; case FudgeTypeDictionary.LONG_TYPE_ID: bw.Write((long)value); nWritten = 8; break; case FudgeTypeDictionary.FLOAT_TYPE_ID: bw.Write((float)value); nWritten = 4; break; case FudgeTypeDictionary.DOUBLE_TYPE_ID: bw.Write((double)value); nWritten = 8; break; } if (nWritten == 0) { if (type.IsVariableSize) { nWritten = WriteVariableSize(bw, valueSize); } else { nWritten = type.FixedSize; } if (value is IFudgeFieldContainer) { IFudgeFieldContainer subMsg = (IFudgeFieldContainer)value; WriteMsgFields(bw, subMsg, taxonomy); } else { type.WriteValue(bw, value); } } return nWritten; }
// throws IOException private static int WriteField(BinaryWriter bw, FudgeFieldType type, object value, short? ordinal, string name, IFudgeTaxonomy taxonomy) { CheckOutputStream(bw); if (type == null) { throw new ArgumentNullException("Must provide the type of data encoded."); } if (value == null) { throw new ArgumentNullException("Must provide the value to encode."); } // First, normalize the name/ordinal bit NormalizeNameAndOrdinal(ref name, ref ordinal, taxonomy); // Reduce the value to minimal form value = type.Minimize(value, ref type); // Now do the field header int valueSize = type.IsVariableSize ? type.GetVariableSize(value, taxonomy) : type.FixedSize; int nWritten = WriteFieldHeader(bw, valueSize, type.IsVariableSize, type.TypeId, ordinal, name); // Finally the value if (value != null) { Debug.Assert(type != null); nWritten += WriteFieldValue(bw, type, value, valueSize, taxonomy); } return nWritten; }
private static void NormalizeNameAndOrdinal(ref string name, ref short? ordinal, IFudgeTaxonomy taxonomy) { if ((taxonomy != null) && (name != null)) { short? ordinalFromTaxonomy = taxonomy.GetFieldOrdinal(name); if (ordinalFromTaxonomy != null) { if ((ordinal != null) && !object.Equals(ordinalFromTaxonomy, ordinal)) { // In this case, we've been provided an ordinal, but it doesn't match the // one from the taxonomy. We have to assume the user meant what they were doing, // and not do anything. } else { ordinal = ordinalFromTaxonomy; name = null; } } } }
/// <inheritdoc/> public void StartMessage() { if (stack.Count > 0) throw new InvalidOperationException("Attempting to start message when already started."); memStream = new MemoryStream(); memWriter = new FudgeBinaryWriter(memStream); taxonomy = null; if (TaxonomyId.HasValue && context.TaxonomyResolver != null) { taxonomy = context.TaxonomyResolver.ResolveTaxonomy(TaxonomyId.Value); } stack.Push(new State(0, 0, false, false, 0)); }
private static int WriteMsgFields(BinaryWriter bw, IFudgeFieldContainer container, IFudgeTaxonomy taxonomy) //throws IOException { int nWritten = 0; foreach (IFudgeField field in container.GetAllFields()) { nWritten += WriteField(bw, field.Type, field.Value, field.Ordinal, field.Name, taxonomy); } return(nWritten); }
/// <inheritdoc cref="Fudge.FudgeFieldType.GetVariableSize(System.Object,Fudge.Taxon.IFudgeTaxonomy)" /> public override int GetVariableSize(T value, IFudgeTaxonomy taxonomy) { throw new NotSupportedException("Secondary type should never have to get a value size, the wire type should handle this"); }
private static void NormalizeNameAndOrdinal(ref string name, ref short?ordinal, IFudgeTaxonomy taxonomy) { if ((taxonomy != null) && (name != null)) { short?ordinalFromTaxonomy = taxonomy.GetFieldOrdinal(name); if (ordinalFromTaxonomy != null) { if ((ordinal != null) && !object.Equals(ordinalFromTaxonomy, ordinal)) { // In this case, we've been provided an ordinal, but it doesn't match the // one from the taxonomy. We have to assume the user meant what they were doing, // and not do anything. } else { ordinal = ordinalFromTaxonomy; name = null; } } } }
/// <inheritdoc cref="Fudge.FudgeFieldType.GetVariableSize(System.Object,Fudge.Taxon.IFudgeTaxonomy)" /> public override int GetVariableSize(UnknownFudgeFieldValue value, IFudgeTaxonomy taxonomy) { return(value.Contents.Length); }
/// <inheritdoc cref="Fudge.FudgeFieldType.GetVariableSize(System.Object,Fudge.Taxon.IFudgeTaxonomy)" /> public override int GetVariableSize(FudgeMsg value, IFudgeTaxonomy taxonomy) { return(value.GetSize(taxonomy)); }
/// <summary> /// Calculates the size, in bytes, of the object if encoded with a given taxonomy. Do not call this directly to get the object size - use <c>GetSize</c> instead. /// </summary> /// <param name="taxonomy">the taxonomy to use for encoding, or null to calculate the size without a taxonomy</param> /// <returns>the size of the encoded object in bytes</returns> public abstract int ComputeSize(IFudgeTaxonomy taxonomy);
/// <inheritdoc /> public override int GetVariableSize(byte[] value, IFudgeTaxonomy taxonomy) { return(value.Length); }