public static bool TryReadFrom(byte[] data, ref int index, int byteCount, out OscBundle bundle) { // Check header size (prefix + timetag). if (data.Length - index < OscConst.bundleHeaderSize) { Debug.LogWarning("[OscParser] OscBundle with invalid header was ignored." + Environment.NewLine); // TODO make warnings optional bundle = null; return(false); } // Check prefix. if (!ReadAndValidatePrefix(data, ref index)) { Debug.LogWarning("[OscParser] OscBundle with invalid header was ignored." + Environment.NewLine); // TODO make warnings optional bundle = null; return(false); } // Try get recycled bundle from the pool, otherwise create new. bundle = OscPool.GetBundle(); // Get timetag osc ntp. EightByteOscData timeTagDataValue; EightByteOscData.TryReadFrom(data, ref index, out timeTagDataValue); bundle.timeTag = timeTagDataValue.timeTagValue; // Fill Bundle. while (index < byteCount) { FourByteOscData packetSizeDataValue; if (!FourByteOscData.TryReadFrom(data, ref index, out packetSizeDataValue)) { break; } if (index + packetSizeDataValue.intValue > data.Length) { Debug.LogWarning("[OscParser] Incomplete OscBundle was ignored.\nPerhaps your UDP buffer size is too small.\n"); // TODO make warnings optional bundle = null; return(false); } OscPacket subPacket; if (TryReadFrom(data, ref index, byteCount, out subPacket)) { bundle.Add(subPacket); } else { Debug.Log("Failed to read packet."); // TODO make warnings optional } } // Done. return(true); }
/// <summary> /// Send an OscMessage or OscBundle. Data is serialized and no reference is stored, so you can safely /// change values and send packet immediately again. /// Returns success status. /// </summary> public bool Send( OscPacket packet ) { if( !isOpen ) return false; // On any message. if( _onAnyMessage != null ) InvokeAnyMessageEventRecursively( packet ); // Individual messages are always send in bundles at end of frame. if( packet is OscMessage ){ _endOfFrameBuffer.Add( packet as OscMessage ); return true; // Assume success. } // Split bundle case. if( packet.Size() > _udpBufferSize ){ ExtractMessages( packet, _tempMessageQueue ); int bundleByteCount = OscConst.bundleHeaderSize; OscBundle splitBundle = OscPool.GetBundle(); while( _tempMessageQueue.Count > 0 ) { OscMessage message = _tempMessageQueue.Dequeue(); // Check if message is too big. int messageSize = message.Size() + FourByteOscData.byteCount; // Bundle stores size of each message in a 4 byte integer. if( messageSize > _udpBufferSize ){ StringBuilder sb = OscDebug.BuildText( this ); sb.Append( "Failed to send message. Message size at " ); sb.Append( messageSize ); sb.Append( " bytes exceeds udp buffer size at " ); sb.Append( _udpBufferSize ); sb.Append( " bytes. Try increasing the buffer size.'\n" ); Debug.LogWarning( sb.ToString() ); return false; } // If bundle is full, send it and prepare for new bundle. if( bundleByteCount + messageSize > _udpBufferSize ) { if( !Send( splitBundle ) ) return false; bundleByteCount = OscConst.bundleHeaderSize; splitBundle.Clear(); } splitBundle.packets.Add( message ); bundleByteCount += messageSize; } if( splitBundle.packets.Count > 0 && !Send( splitBundle ) ) return false; OscPool.Recycle( splitBundle ); return true; } // Try to pack the message. int index = 0; if( !packet.TryWriteTo( _cache, ref index ) ) return false; //Debug.Log( $"Sending byte count {index}" ); // Send data! return TrySendCache( index ); }
public static bool TryReadFrom(byte[] data, ref int index, int byteCount, out OscBundle bundle) { //Debug.Log( "OscBundle.TryReadFrom. index: " + index + ", expected byteCount: " + byteCount ); // Check header size (prefix + timetag). if (data.Length - index < OscConst.bundleHeaderSize) { if (OscGlobals.logWarnings) { Debug.LogWarning(logPrepend + "OscBundle with invalid header was ignored." + Environment.NewLine); } bundle = null; return(false); } // Check prefix. if (!ReadAndValidatePrefix(data, ref index)) { if (OscGlobals.logWarnings) { Debug.LogWarning(logPrepend + "OscBundle with invalid header was ignored." + Environment.NewLine); } bundle = null; return(false); } // Try get recycled bundle from the pool, otherwise create new. bundle = OscPool.GetBundle(); // Get (optional) timetag osc ntp. EightByteOscData timeTagDataValue; if (EightByteOscData.TryReadFrom(data, ref index, out timeTagDataValue)) { bundle.timeTag = timeTagDataValue.timeTagValue; //Debug.Log( "Time tag: " + bundle.timeTag ); } // Extract packets from buffer data. while (index < byteCount) { //Debug.Log( "Read index: " + index + " out of " + byteCount ); // Read packet size. FourByteOscData packetSizeDataValue; if (!FourByteOscData.TryReadFrom(data, ref index, out packetSizeDataValue) || packetSizeDataValue.intValue == 0) { //Debug.LogError( "No message size provided!" ); break; } //Debug.Log( "packetSizeData: " + packetSizeDataValue.intValue ); int endDataIndex = index + packetSizeDataValue.intValue; if (endDataIndex > data.Length) { if (OscGlobals.logWarnings) { //Debug.LogError( "packetSizeDataValue.intValue: " + packetSizeDataValue.intValue ); Debug.LogWarning(string.Format( "{0}Failed to read OscBundle at index {1} because a OscPacket is too large to fit in buffer (byte size {2}.\n" + "Your buffer may be too small to read the entire bundle. Try increasing the buffer size in OscIn.", logPrepend, index, packetSizeDataValue.intValue )); } bundle = null; return(false); } //if( index % 4 != 0 ) Debug.LogError( "NOT MULTIPLE OF 4" ); OscPacket subPacket; //Debug.Log( ( (char) data[ index ] ) + " " + data[ index ] ); if (TryReadFrom(data, ref index, endDataIndex, out subPacket)) { //Debug.Log( "Sub packet read: " + index + " == " + endDataIndex ); bundle.Add(subPacket); } else { if (OscGlobals.logWarnings) { Debug.LogWarning(logPrepend + "Failed to read packet.\nIndex: " + index + ", Packet size: " + packetSizeDataValue.intValue + ", Byte count: " + byteCount + ", Buffer size: " + data.Length); } return(false); } } // Done. return(true); }
/// <summary> /// Send an OscMessage or OscBundle. Data is serialized and no reference is stored, so you can safely /// change values and send packet immediately again. /// Returns success status. /// </summary> public bool Send(OscPacket packet) { if (!isOpen) { return(false); } int index = 0; // On any message. if (_onAnyMessage != null) { InvokeAnyMessageEventRecursively(packet); } // Adapt buffer size. if (_sendBuffer == null || _sendBuffer.Length != _udpBufferSize) { _sendBuffer = new byte[_udpBufferSize]; } // Handle user messages. if (packet is OscMessage) { if (_bundleMessagesAutomatically) { // Collect to be bundled and send by end of the Unity frame. _autoBundleMessageBuffer.Add(packet as OscMessage); return(true); // Assume success. } else { // Add to cache and send immediately. OscMessage message = packet as OscMessage; message.TryWriteTo(_sendBuffer, ref index); bool success = TrySendBuffer(index); if (success) { _messageCountThisFrame++; } return(success); } } // Handle user bundles. Bundles provided by the user are send immediately. If too big, they are split into more bundles. OscBundle bundle = packet as OscBundle; if (bundle.Size() > _udpBufferSize) { ExtractMessages(packet, _userBundleTempMessages); int bundleByteCount = OscConst.bundleHeaderSize; OscBundle splitBundle = OscPool.GetBundle(); while (_userBundleTempMessages.Count > 0) { OscMessage message = _userBundleTempMessages.Dequeue(); // Check if message is too big. int messageSize = message.Size() + FourByteOscData.byteCount; // Bundle stores size of each message in a 4 byte integer. if (messageSize > _udpBufferSize) { if (OscGlobals.logWarnings) { StringBuilder sb = OscDebug.BuildText(this); sb.Append("Failed to send message. Message size at "); sb.Append(messageSize); sb.Append(" bytes exceeds udp buffer size at "); sb.Append(_udpBufferSize); sb.Append(" bytes. Try increasing the buffer size.'\n"); Debug.LogWarning(sb.ToString()); } return(false); } // If bundle is full, send it and prepare for new bundle. if (bundleByteCount + messageSize > _udpBufferSize) { if (!Send(splitBundle)) { return(false); } bundleByteCount = OscConst.bundleHeaderSize; splitBundle.Clear(); } splitBundle.packets.Add(message); bundleByteCount += messageSize; } if (splitBundle.packets.Count > 0 && !Send(splitBundle)) { return(false); } OscPool.Recycle(splitBundle); return(true); } // Try to pack the message. if (!bundle.TryWriteTo(_sendBuffer, ref index)) { return(false); } _messageCountThisFrame += bundle.packets.Count; // Send data! return(TrySendBuffer(index)); }