/// <summary> /// Parse a value /// </summary> /// <param name="data">Bytes array</param> /// <param name="offset">Zero-indexed offset.</param> /// <param name="size">Output the number of bytes parsed</param> /// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end.</param> /// <param name="dataType">DataType, in case the data is not prepended with DataType</param> /// <returns>Value</returns> public static (uint, AsyncReply) Parse(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, TransmissionType?dataType = null) { uint len = 0; if (dataType == null) { (var longLen, dataType) = TransmissionType.Parse(data, offset, (uint)data.Length); len = (uint)longLen; offset = dataType.Value.Offset; } else { len = (uint)dataType.Value.ContentLength; } var tt = dataType.Value; if (tt.Class == TransmissionTypeClass.Fixed) { return(len, FixedParsers[tt.Exponent][tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection, requestSequence));
public override long Parse(byte[] data, uint offset, uint ends) { originalOffset = offset; if (NotEnough(offset, ends, 1)) { return(-dataLengthNeeded); } PreviousCommand = Command; Command = (IIPPacketCommand)(data[offset] >> 6); if (Command == IIPPacketCommand.Event) { Event = (IIPPacketEvent)(data[offset++] & 0x3f); if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Command == IIPPacketCommand.Report) { Report = (IIPPacketReport)(data[offset++] & 0x3f); if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } CallbackId = data.GetUInt32(offset, Endian.Little); offset += 4; } else { PreviousAction = Action; Action = (IIPPacketAction)(data[offset++] & 0x3f); if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } CallbackId = data.GetUInt32(offset, Endian.Little); offset += 4; } if (Command == IIPPacketCommand.Event) { if (Event == IIPPacketEvent.ResourceReassigned) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } NewResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Event == IIPPacketEvent.ResourceDestroyed) { // nothing to parse } else if (Event == IIPPacketEvent.ChildAdded || Event == IIPPacketEvent.ChildRemoved) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } ChildId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Event == IIPPacketEvent.Renamed) { if (NotEnough(offset, ends, 2)) { return(-dataLengthNeeded); } var cl = data.GetUInt16(offset, Endian.Little); offset += 2; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } ResourceName = data.GetString(offset, cl); //Content = data.Clip(offset, cl); offset += cl; } else if (Event == IIPPacketEvent.PropertyUpdated || Event == IIPPacketEvent.EventOccurred) { if (NotEnough(offset, ends, 2)) { return(-dataLengthNeeded); } MethodIndex = data[offset++]; (var size, DataType) = TransmissionType.Parse(data, offset, ends); //var dt = (DataType)data[offset++]; //var size = dt.Size();// Codec.SizeOf(dt); if (DataType == null) { return(-(int)size); } //Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength); offset += (uint)size; } //else if (Event == IIPPacketEvent.EventOccurred) //{ // if (NotEnough(offset, ends, 5)) // return -dataLengthNeeded; // MethodIndex = data[offset++]; // var cl = data.GetUInt32(offset); // offset += 4; // if (NotEnough(offset, ends, cl)) // return -dataLengthNeeded; // Content = data.Clip(offset, cl); // offset += cl; //} // Attribute else if (Event == IIPPacketEvent.AttributesUpdated) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } var cl = data.GetUInt32(offset, Endian.Little); offset += 4; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } //@TODO: Fix this //Content = data.Clip(offset, cl); offset += cl; } } else if (Command == IIPPacketCommand.Request) { if (Action == IIPPacketAction.AttachResource) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Action == IIPPacketAction.ReattachResource) { if (NotEnough(offset, ends, 12)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; ResourceAge = data.GetUInt64(offset, Endian.Little); offset += 8; } else if (Action == IIPPacketAction.DetachResource) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Action == IIPPacketAction.CreateResource) { if (NotEnough(offset, ends, 12)) { return(-dataLengthNeeded); } StoreId = data.GetUInt32(offset, Endian.Little); offset += 4; ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; var cl = data.GetUInt32(offset, Endian.Little); offset += 4; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } // @TODO: fix this //this.Content = data.Clip(offset, cl); } else if (Action == IIPPacketAction.DeleteResource) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Action == IIPPacketAction.AddChild || Action == IIPPacketAction.RemoveChild) { if (NotEnough(offset, ends, 8)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; ChildId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Action == IIPPacketAction.RenameResource) { if (NotEnough(offset, ends, 6)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; var cl = data.GetUInt16(offset, Endian.Little); offset += 2; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } ResourceName = data.GetString(offset, cl); //Content = data.Clip(offset, cl); offset += cl; } else if (Action == IIPPacketAction.TemplateFromClassName) { if (NotEnough(offset, ends, 1)) { return(-dataLengthNeeded); } var cl = data[offset++]; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } ClassName = data.GetString(offset, cl); offset += cl; } else if (Action == IIPPacketAction.TemplateFromClassId) { if (NotEnough(offset, ends, 16)) { return(-dataLengthNeeded); } ClassId = data.GetGuid(offset); offset += 16; } else if (Action == IIPPacketAction.TemplateFromResourceId) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Action == IIPPacketAction.QueryLink || Action == IIPPacketAction.LinkTemplates) { if (NotEnough(offset, ends, 2)) { return(-dataLengthNeeded); } var cl = data.GetUInt16(offset, Endian.Little); offset += 2; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } ResourceLink = data.GetString(offset, cl); offset += cl; } else if (Action == IIPPacketAction.ResourceChildren || Action == IIPPacketAction.ResourceParents) { if (NotEnough(offset, ends, 4)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Action == IIPPacketAction.ResourceHistory) { if (NotEnough(offset, ends, 20)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; FromDate = data.GetDateTime(offset, Endian.Little); offset += 8; ToDate = data.GetDateTime(offset, Endian.Little); offset += 8; } else if (Action == IIPPacketAction.InvokeFunction) { if (NotEnough(offset, ends, 6)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; MethodIndex = data[offset++]; (var size, DataType) = TransmissionType.Parse(data, offset, ends); if (DataType == null) { return(-(int)size); } offset += (uint)size; //var cl = data.GetUInt32(offset); //offset += 4; //if (NotEnough(offset, ends, cl)) // return -dataLengthNeeded; //Content = data.Clip(offset, cl); //offset += cl; } else if (Action == IIPPacketAction.Listen || Action == IIPPacketAction.Unlisten)// .GetProperty) { if (NotEnough(offset, ends, 5)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; MethodIndex = data[offset++]; } //else if (Action == IIPPacketAction.GetPropertyIfModified) //{ // if (NotEnough(offset, ends, 9)) // return -dataLengthNeeded; // ResourceId = data.GetUInt32(offset); // offset += 4; // MethodIndex = data[offset++]; // ResourceAge = data.GetUInt64(offset); // offset += 8; //} else if (Action == IIPPacketAction.SetProperty) { if (NotEnough(offset, ends, 6)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; MethodIndex = data[offset++]; (var size, DataType) = TransmissionType.Parse(data, offset, ends); if (DataType == null) { return(-(int)size); } //Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength); offset += (uint)size; } // Attributes else if (Action == IIPPacketAction.UpdateAllAttributes || Action == IIPPacketAction.GetAttributes || Action == IIPPacketAction.UpdateAttributes || Action == IIPPacketAction.ClearAttributes) { if (NotEnough(offset, ends, 8)) { return(-dataLengthNeeded); } ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; var cl = data.GetUInt32(offset, Endian.Little); offset += 4; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } // @TODO: fix this //Content = data.Clip(offset, cl); offset += cl; } } else if (Command == IIPPacketCommand.Reply) { if (Action == IIPPacketAction.AttachResource || Action == IIPPacketAction.ReattachResource) { if (NotEnough(offset, ends, 26)) { return(-dataLengthNeeded); } ClassId = data.GetGuid(offset); offset += 16; ResourceAge = data.GetUInt64(offset, Endian.Little); offset += 8; uint cl = data.GetUInt16(offset, Endian.Little); offset += 2; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } ResourceLink = data.GetString(offset, cl); offset += cl; //if (NotEnough(offset, ends, 4)) // return -dataLengthNeeded; (var size, DataType) = TransmissionType.Parse(data, offset, ends); if (DataType == null) { return(-(int)size); } offset += (uint)size; //Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength); } else if (Action == IIPPacketAction.DetachResource) { // nothing to do } else if (Action == IIPPacketAction.CreateResource) { if (NotEnough(offset, ends, 20)) { return(-dataLengthNeeded); } //ClassId = data.GetGuid(offset); //offset += 16; ResourceId = data.GetUInt32(offset, Endian.Little); offset += 4; } else if (Action == IIPPacketAction.DetachResource) { // nothing to do } // Inquire else if (Action == IIPPacketAction.TemplateFromClassName || Action == IIPPacketAction.TemplateFromClassId || Action == IIPPacketAction.TemplateFromResourceId || Action == IIPPacketAction.QueryLink || Action == IIPPacketAction.ResourceChildren || Action == IIPPacketAction.ResourceParents || Action == IIPPacketAction.ResourceHistory || Action == IIPPacketAction.LinkTemplates // Attribute || Action == IIPPacketAction.GetAllAttributes || Action == IIPPacketAction.GetAttributes) { if (NotEnough(offset, ends, 1)) { return(-dataLengthNeeded); } (var size, DataType) = TransmissionType.Parse(data, offset, ends); if (DataType == null) { return(-(int)size); } offset += (uint)size; //var cl = data.GetUInt32(offset); //offset += 4; //if (NotEnough(offset, ends, cl)) // return -dataLengthNeeded; //Content = data.Clip(offset, cl); //offset += cl; } else if (Action == IIPPacketAction.InvokeFunction) //|| Action == IIPPacketAction.GetProperty //|| Action == IIPPacketAction.GetPropertyIfModified) { if (NotEnough(offset, ends, 1)) { return(-dataLengthNeeded); } (var size, DataType) = TransmissionType.Parse(data, offset, ends); if (DataType == null) { return(-(int)size); } offset += (uint)size; //Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength); } else if (Action == IIPPacketAction.SetProperty || Action == IIPPacketAction.Listen || Action == IIPPacketAction.Unlisten) { // nothing to do } } else if (Command == IIPPacketCommand.Report) { if (Report == IIPPacketReport.ManagementError) { if (NotEnough(offset, ends, 2)) { return(-dataLengthNeeded); } ErrorCode = data.GetUInt16(offset, Endian.Little); offset += 2; } else if (Report == IIPPacketReport.ExecutionError) { if (NotEnough(offset, ends, 2)) { return(-dataLengthNeeded); } ErrorCode = data.GetUInt16(offset, Endian.Little); offset += 2; if (NotEnough(offset, ends, 2)) { return(-dataLengthNeeded); } var cl = data.GetUInt16(offset, Endian.Little); offset += 2; if (NotEnough(offset, ends, cl)) { return(-dataLengthNeeded); } ErrorMessage = data.GetString(offset, cl); offset += cl; } else if (Report == IIPPacketReport.ProgressReport) { if (NotEnough(offset, ends, 8)) { return(-dataLengthNeeded); } ProgressValue = data.GetInt32(offset, Endian.Little); offset += 4; ProgressMax = data.GetInt32(offset, Endian.Little); offset += 4; } else if (Report == IIPPacketReport.ChunkStream) { if (NotEnough(offset, ends, 1)) { return(-dataLengthNeeded); } (var size, DataType) = TransmissionType.Parse(Data, offset, ends); if (DataType == null) { return(-(int)size); } offset += (uint)size; //Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength); } } return(offset - originalOffset); }