public static byte[][] SerializeFrame(FrameWithoutDelta frame, int maxSizePerPackage) { int bytesNeeded = HEADER_BYTES_NEEDED + frame.Items.Length * PixelInstructionProtocol.BYTES_NEEDED; byte[][] packages; if (bytesNeeded <= maxSizePerPackage) { // The frame is small enough to fit in a single packet. // No FrameSectionPackage is needed. packages = new byte[1][]; packages[0] = new byte[bytesNeeded]; BitConverter.GetBytes(frame.Index).CopyTo(packages[0], 0); // Sequence index BitConverter.GetBytes(frame.TimeStampRelative).CopyTo(packages[0], 4); // TimeStamp (relative) BitConverter.GetBytes(frame.Count).CopyTo(packages[0], 8); // Number of PixelInstructions BitConverter.GetBytes(false).CopyTo(packages[0], 12); // Has FrameSections for (int i = 0; i < frame.Count; i++) { int bufferStartIndex = HEADER_BYTES_NEEDED + i * PixelInstructionProtocol.BYTES_NEEDED; PixelInstructionProtocol.Serialize(frame[i], packages[0], bufferStartIndex); } return(packages); } // This frame is too big to send as one packet. // Create multiple packages with the help of FrameSectionPackage // First, calculate the inital package int headerBytesNeeded = HEADER_BYTES_NEEDED + FrameSectionProtocol.HEADER_BYTES_NEEDED; int instructionsInFirstSection = (maxSizePerPackage - headerBytesNeeded) / PixelInstructionProtocol.BYTES_NEEDED; // Second, calculate how many FrameSections are needed int instructionsThatFitInOtherSections = (maxSizePerPackage - FrameSectionProtocol.HEADER_BYTES_NEEDED) / PixelInstructionProtocol.BYTES_NEEDED; int frameSectionsNeeded = (int)Math.Ceiling((double)(frame.Count - instructionsInFirstSection) / instructionsThatFitInOtherSections) + 1; // +1 for the first section packages = new byte[frameSectionsNeeded][]; // Third, create the Frame header and its first section packages[0] = new byte[headerBytesNeeded + instructionsInFirstSection * PixelInstructionProtocol.BYTES_NEEDED]; BitConverter.GetBytes(frame.Index).CopyTo(packages[0], 0); // Sequence index BitConverter.GetBytes(frame.TimeStampRelative).CopyTo(packages[0], 4); // TimeStamp (relative) BitConverter.GetBytes(frameSectionsNeeded).CopyTo(packages[0], 8); // Number of FrameSets BitConverter.GetBytes(true).CopyTo(packages[0], 12); // Has FrameSections CreateFrameSection(packages[0], 13, frame, frame.Index, 0, 0, instructionsInFirstSection); // Lastely, create the other frame sections. A new byte array (package) for each FrameSection. for (int i = 0; i < frameSectionsNeeded - 1; i++) { int instructionStartIndex = instructionsInFirstSection + i * instructionsThatFitInOtherSections; int instructionsInThisSection = Math.Min(instructionsThatFitInOtherSections, frame.Count - instructionStartIndex); packages[i + 1] = new byte[FrameSectionProtocol.HEADER_BYTES_NEEDED + PixelInstructionProtocol.BYTES_NEEDED * instructionsInThisSection]; CreateFrameSection(packages[i + 1], 0, frame, frame.Index, i + 1, instructionStartIndex, instructionsInThisSection); } return(packages); }
public const int HEADER_BYTES_NEEDED = sizeof(int) + sizeof(int) + sizeof(int); // frameSequenceIndex + Index + number of pixelinstructions; public static byte[] Serialize(FrameSectionPackage package, byte[] buffer, int startIndex) { BitConverter.GetBytes(package.FrameSequenceIndex).CopyTo(buffer, startIndex); BitConverter.GetBytes(package.Index).CopyTo(buffer, startIndex + 4); BitConverter.GetBytes(package.pixelInstructions.Count).CopyTo(buffer, startIndex + 8); int pixelInstructionsStartIndex = startIndex + 12; for (int i = 0; i < package.pixelInstructions.Count; i++) { PixelInstructionProtocol.Serialize(package.pixelInstructions[i], buffer, pixelInstructionsStartIndex + i * PixelInstructionProtocol.BYTES_NEEDED); } return(buffer); }