/// Retrieves the first Flattenable value in the given field. /// <param name="name"/> /// <param name="returnObject"> /// A Flattenable object that, on success, will be set to reflect /// the value held in this field. This object will not be referenced /// by this Message. /// </param> public void getFlat(string name, Flattenable returnObject) { MessageField field = getField(name); if (returnObject.allowsTypeCode(field.typeCode())) { object o = field.getData(); if (o is byte[][]) { unflattenFromArray(returnObject, ((byte[][])o)[0]); } else if (o is Message[]) { returnObject.setEqualTo(((Message[])o)[0]); } else if (o is Point[]) { returnObject.setEqualTo(((Point[])o)[0]); } else if (o is Rect[]) { returnObject.setEqualTo(((Rect[])o)[0]); } else { throw new FieldTypeMismatchException(name + " isn't a flattened-data field"); } } else { throw new FieldTypeMismatchException("Passed-in object doesn't like typeCode " + whatString(field.typeCode())); } }
public override void flatten(BinaryWriter writer) { // Format: 0. Protocol revision number // (4 bytes, always set to CURRENT_PROTOCOL_VERSION) // 1. 'what' code (4 bytes) // 2. Number of entries (4 bytes) // 3. Entry name length (4 bytes) // 4. Entry name string (flattened String) // 5. Entry type code (4 bytes) // 6. Entry data length (4 bytes) // 7. Entry data (n bytes) // 8. loop to 3 as necessary writer.Write((int)CURRENT_PROTOCOL_VERSION); writer.Write((int)what); writer.Write((int)countFields()); IEnumerator e = fieldNames(); while (e.MoveNext()) { string name = (string)e.Current; MessageField field = (MessageField)_fieldTable[name]; byte [] byteArray = Encoding.UTF8.GetBytes(name); writer.Write((int)(byteArray.Length + 1)); writer.Write(byteArray); writer.Write((byte)0); // terminating NUL byte writer.Write(field.typeCode()); writer.Write(field.flattenedSize()); field.flatten(writer); } }
/// Retrieves the contents of the given field as an array of /// Flattenable values. /// <param name="name">Name of the field to look for /// </param> Flattenable values in. /// <param name="returnObjects">Should be an array of pre-allocated /// Flattenable objects of the correct type. On success, this /// array's objects will be set to the proper states as determined by /// the held data in this Message. All the objects should be of the /// same type. This method will unflatten as many objects as exist or /// can fit in the array. These objects will not be referenced by /// this Message.</param> /// <returns>The number of objects in (returnObjects) that were /// actually unflattened. May be less than (returnObjects.length). /// </returns> /// <exception cref="FieldNotFoundException"/> /// <exception cref="FieldTypeMismatchException"/> /// <exception cref="UnflattenFormatException"/> /// <exception cref="InvalidCastException"/> /// public int getFlats(string name, Flattenable [] returnObjects) { MessageField field = getField(name); if (returnObjects[0].allowsTypeCode(field.typeCode())) { object objs = field.getData(); int num; if (objs is byte[][]) { byte [][] bufs = (byte[][])objs; num = (bufs.Length < returnObjects.Length) ? bufs.Length : returnObjects.Length; for (int i = 0; i < num; i++) { unflattenFromArray(returnObjects[i], bufs[i]); } } else if (objs is Message[]) { Message [] messages = (Message[])objs; num = (messages.Length < returnObjects.Length) ? messages.Length : returnObjects.Length; for (int i = 0; i < num; i++) { returnObjects[i].setEqualTo(messages[i]); } } else if (objs is Point[]) { Point [] points = (Point[])objs; num = (points.Length < returnObjects.Length) ? points.Length : returnObjects.Length; for (int i = 0; i < num; i++) { returnObjects[i].setEqualTo(points[i]); } } else if (objs is Rect[]) { Rect [] rects = (Rect[])objs; num = (rects.Length < returnObjects.Length) ? rects.Length : returnObjects.Length; for (int i = 0; i < num; i++) { returnObjects[i].setEqualTo(rects[i]); } } else { throw new FieldTypeMismatchException(name + " wasn't an unflattenable data field"); } return(num); } else { throw new FieldTypeMismatchException("Passed-in objects doen't like typeCode " + whatString(field.typeCode())); } }
/// Utility method to get a field (if it exists), create it if it /// doesn't, or replace it if it exists but is the wrong type. /// <param name="name"/> /// <param name="type">B_*_TYPE of the field to get or create. /// B_ANY_TYPE should not be used.</param> /// <returns>The (possibly new, possible pre-existing) /// MessageField object.</returns> private MessageField getCreateOrReplaceField(string name, int type) { ensureFieldTableAllocated(); MessageField field = (MessageField)_fieldTable[name]; if (field != null) { if (field.typeCode() != type) { _fieldTable.Remove(name); return(getCreateOrReplaceField(name, type)); } } else { field = new MessageField(type); _fieldTable.Add(name, field); } return(field); }
/// Returns the number of field names of the given type that /// are present in the Message. /// <param name="type"> /// The type of field to count, or B_ANY_TYPE to /// count all field types. /// </param> /// <returns>The number of matching fields, or zero if there are /// no fields of the appropriate type.</returns> /// public int countFields(int type) { if (_fieldTable == null) { return(0); } if (type == B_ANY_TYPE) { return(_fieldTable.Count); } int count = 0; IEnumerator e = _fieldTable.Values.GetEnumerator(); while (e.MoveNext()) { MessageField field = (MessageField)e.Current; if (field.typeCode() == type) { count++; } } return(count); }