Exemple #1
0
        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);
        }