/// <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); } } }
/// <summary> /// Returns the Fudge encoded form of a <c>FudgeMsg</c> as a <c>byte</c> array without a taxonomy reference. /// </summary> /// <param name="msg">the <c>FudgeMsg</c> to encode</param> /// <returns>an array containing the encoded message</returns> public byte[] ToByteArray(FudgeMsg msg) { MemoryStream stream = new MemoryStream(); Serialize(msg, stream); return(stream.ToArray()); }
/// <summary> /// Creates a new <c>FudgeMsg</c> object as a copy of another. /// </summary> /// <param name="other">an existing <c>FudgeMsg</c> object to copy</param> public FudgeMsg(FudgeMsg other) { if (other == null) { throw new ArgumentNullException("Cannot initialize from a null other FudgeMsg"); } this.context = other.context; InitializeFromByteArray(other.ToByteArray()); }
/// <summary> /// Creates a new <c>FudgeMsgEnvelope</c> around an existing <c>FudgeMsg</c> with a specific encoding schema version. The default /// schema version is 0. /// </summary> /// <param name="message">message contained within the envelope</param> /// <param name="version">schema version, 0 to 255</param> public FudgeMsgEnvelope(FudgeMsg message, int version) { if (message == null) { throw new ArgumentNullException("message", "Must specify a message to wrap."); } if ((version < 0) || (version > 255)) { throw new ArgumentOutOfRangeException("version", "Provided version " + version + " which doesn't fit within one byte."); } this.message = message; this.version = version; }
/// <summary> /// Encodes a <c>FudgeMsg</c> object to a <c>Stream</c> with an optional taxonomy reference. /// If a taxonomy is supplied it may be used to optimize the output by writing ordinals instead /// of field names. /// </summary> /// <param name="msg">the <c>FudgeMessage</c> to write</param> /// <param name="taxonomyId">the identifier of the taxonomy to use. Specify <c>null</c> for no taxonomy</param> /// <param name="bw">The <see cref="BinaryWriter"/> to serialise to</param> public void Serialize(FudgeMsg msg, short?taxonomyId, BinaryWriter bw) { try { var writer = new FudgeEncodedStreamWriter(this); writer.TaxonomyId = taxonomyId; writer.Reset(bw); writer.StartMessage(); writer.WriteFields(msg.GetAllFields()); writer.EndMessage(); } catch (IOException e) { throw new FudgeRuntimeException("Unable to write Fudge message to OutputStream", e); } }
/// <summary> /// Parses data from a given <see cref="BinaryReader"/>. /// </summary> /// <param name="binaryReader"></param> /// <returns></returns> public FudgeMsgEnvelope Parse(BinaryReader binaryReader) { FudgeEncodedStreamReader reader = new FudgeEncodedStreamReader(FudgeContext); reader.Reset(binaryReader); FudgeStreamElement element = reader.MoveNext(); if (element == FudgeStreamElement.NoElement) { return(null); } if (element != FudgeStreamElement.MessageStart) { throw new ArgumentException("First element in encoding stream wasn't a message element."); } int version = reader.SchemaVersion; FudgeMsg msg = FudgeContext.NewMessage(); FudgeMsgEnvelope envelope = new FudgeMsgEnvelope(msg, version); ProcessFields(reader, msg); return(envelope); }
/// <summary> /// Writes a line describing a field and its value. If the field is a submessage, that message is output at a deeper indentation level. /// </summary> /// <param name="field">field to output</param> /// <param name="index">physical index within containing message</param> /// <param name="depth">indentation level</param> /// <param name="fieldSpec">field description text (includes indent)</param> /// <param name="maxFieldSpecWidth">length of longest field description text (for layout)</param> /// <param name="maxTypeNameWidth">length of longest type name (for layout)</param> protected void Format(IFudgeField field, int index, int depth, string fieldSpec, int maxFieldSpecWidth, int maxTypeNameWidth) { if (field == null) { throw new ArgumentNullException("Cannot format a null field"); } Writer.Write(fieldSpec); int nWritten = fieldSpec.Length; int requiredSize = maxFieldSpecWidth + 1; for (int i = nWritten; i <= requiredSize; i++) { Writer.Write(' '); nWritten++; } string typeName = GetTypeName(field.Type); Writer.Write(typeName); nWritten += typeName.Length; requiredSize = requiredSize + maxTypeNameWidth + 1; for (int i = nWritten; i <= requiredSize; i++) { Writer.Write(' '); nWritten++; } if (field.Value is FudgeMsg) { Writer.WriteLine(); FudgeMsg msgValue = (FudgeMsg)field.Value; Format(msgValue, depth + 1); } else { Writer.Write(field.Value); Writer.WriteLine(); } Writer.Flush(); }
/** * @param reader * @param msg */ protected void ProcessFields(IFudgeStreamReader reader, FudgeMsg msg) { while (reader.HasNext) { FudgeStreamElement element = reader.MoveNext(); switch (element) { case FudgeStreamElement.SimpleField: msg.Add(reader.FieldName, reader.FieldOrdinal, reader.FieldType, reader.FieldValue); break; case FudgeStreamElement.SubmessageFieldStart: FudgeMsg subMsg = FudgeContext.NewMessage(); msg.Add(reader.FieldName, reader.FieldOrdinal, subMsg); ProcessFields(reader, subMsg); break; case FudgeStreamElement.SubmessageFieldEnd: case FudgeStreamElement.MessageEnd: return; } } }
// TODO 2009-12-14 Andrew -- lose the constructor above; we should at least pass the context and use that to construct the inner message /// <summary> /// Creates a new <c>FudgeMsgEnvelope</c> around an existing <c>FudgeMsg</c>. /// </summary> /// <param name="msg">message contained within the envelope</param> public FudgeMsgEnvelope(FudgeMsg msg) : this(msg, 0) { }
/// <summary> /// Encodes a <c>FudgeMsg</c> object to a <c>Stream</c> with an optional taxonomy reference. /// If a taxonomy is supplied it may be used to optimize the output by writing ordinals instead /// of field names. /// </summary> /// <param name="msg">the <c>FudgeMessage</c> to write</param> /// <param name="taxonomyId">the identifier of the taxonomy to use. Specify <c>null</c> for no taxonomy</param> /// <param name="s">the <c>Stream</c> to write to</param> public void Serialize(FudgeMsg msg, short?taxonomyId, Stream s) { Serialize(msg, taxonomyId, new FudgeBinaryWriter(s)); }
/// <summary> /// Encodes a <c>FudgeMsg</c> object to a <see cref="BinaryWriter"/> without any taxonomy reference. /// </summary> /// <param name="msg">The message to serialise</param> /// <param name="bw">The <see cref="BinaryWriter"/> to serialise to</param> public void Serialize(FudgeMsg msg, BinaryWriter bw) { Serialize(msg, null, bw); }
/// <summary> /// Encodes a <c>FudgeMsg</c> object to a <c>Stream</c> without any taxonomy reference. /// </summary> /// <param name="msg">The message to serialise</param> /// <param name="s">The stream to serialise to</param> public void Serialize(FudgeMsg msg, Stream s) { Serialize(msg, null, s); }