private void ParseAddress(byte[] data, MessageBuilder builder, ref int byteCount) { var addressBuilder = new StringBuilder(); while (byteCount < data.Length) { bool hasNull = false; for (int i = 0; i < 4; i++) { byte val = data[byteCount]; if (val > byte.MinValue) { if (hasNull) { throw new MalformedMessageException("Invalid address: address data appearing after null padding at byte position " + byteCount.ToString() + ".", data); } else { if (val == (byte)',') { throw new MalformedMessageException("Invalid address: no null padding before typetags begin at byte position " + byteCount.ToString() + ".", data); } } addressBuilder.Append((char)val); } else { hasNull = true; } byteCount++; } if (hasNull) break; } builder.SetAddress(addressBuilder.ToString()); // throws if address is invalid }
public Message Parse(byte[] data) { var builder = new MessageBuilder(); var byteCount = 0; ParseAddress(data, builder, ref byteCount); ParseTypeTags(data, builder, ref byteCount); ParseMessageData(data, builder, ref byteCount); return builder.ToMessage(); }
private void ParseTypeTags(byte[] data, MessageBuilder builder, ref int byteCount) { while (byteCount < data.Length && data[byteCount] != ',') { byteCount++; } while (byteCount < data.Length) { bool hasNull = false; for (int i = 0; i < 4; i++) { byte val = data[byteCount]; if (data[byteCount] != ',') { if (val > byte.MinValue) { if (hasNull) { throw new MalformedMessageException("Invalid type tags: type tag data appearing after null padding at byte pos + " + byteCount.ToString() + ".", data); } var typeTag = (TypeTag)val; switch (typeTag) { case TypeTag.OscInt32: case TypeTag.OscFloat32: case TypeTag.OscString: case TypeTag.OscBlob: builder.PushAtom(new Atom(typeTag)); break; default: throw new MalformedMessageException("Unknown/invalid type tag " + typeTag.ToString() + " at byte pos " + byteCount.ToString() + ".", data); } } else { hasNull = true; } } byteCount++; } if (hasNull) break; } }
private void ParseMessageData(byte[] data, MessageBuilder builder, ref int byteCount) { for (int currentAtom = 0; currentAtom < builder.AtomCount; currentAtom++) { int incrementBy = 4; switch (builder.GetAtom(currentAtom).TypeTag) { case TypeTag.OscInt32: int intVal = ParseInt32(data, byteCount); builder.SetAtom(currentAtom, intVal); break; case TypeTag.OscFloat32: float floatVal = ParseFloat32(data, byteCount); builder.SetAtom(currentAtom, floatVal); break; case TypeTag.OscString: string stringVal = ParseString(data, byteCount, ref incrementBy); builder.SetAtom(currentAtom, stringVal); break; case TypeTag.OscBlob: byte[] blobVal = ParseBlob(data, byteCount, ref incrementBy); builder.SetAtom(currentAtom, blobVal); break; } byteCount += incrementBy; } }