Exemplo n.º 1
0
        /// <summary>
        /// Deserializes the GuidList from the memory stream
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public uint Load(Stream strm, uint size)
        {
            uint cbsize = 0;

            _CustomGuids.Clear();

            uint count = size / Native.SizeOfGuid;

            byte[] guids = new byte[Native.SizeOfGuid];

            for (uint i = 0; i < count; i++)
            {
                // NTRAID:WINDOWSOS#1622775-2006/04/26-WAYNEZEN,
                // Stream.Read could read less number of bytes than the request. We call ReliableRead that
                // reads the bytes in a loop until all requested bytes are received or reach the end of the stream.
                uint bytesRead = StrokeCollectionSerializer.ReliableRead(strm, guids, Native.SizeOfGuid);

                cbsize += bytesRead;
                if (bytesRead == Native.SizeOfGuid)
                {
                    _CustomGuids.Add(new Guid(guids));
                }
                else
                {
                    // If Stream.Read cannot return the expected number of bytes, we should break here.
                    // The caller - StrokeCollectionSerializer.DecodeRawISF will check our return value.
                    // An exception might be thrown if reading is failed.
                    break;
                }
            }

            return(cbsize);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Loads packets from the input stream.  For example, packets are all of the x's in a stroke
        /// </summary>
#else
        /// <summary>
        /// Loads packets from the input stream.  For example, packets are all of the x's in a stroke
        /// </summary>
#endif
        static uint LoadPackets(Stream inputStream,
                                uint totalBytesInStrokeBlockOfIsfStream,
#if OLD_ISF
                                Compressor compressor,
#endif
                                StylusPointDescription stylusPointDescription,
                                Matrix transform,
                                out StylusPointCollection stylusPoints)
        {
            stylusPoints = null;

            if (0 == totalBytesInStrokeBlockOfIsfStream)
            {
                return(0);
            }

            uint locallyDecodedBytesRemaining = totalBytesInStrokeBlockOfIsfStream;
            uint localBytesRead;

            // First read the no of packets
            uint pointCount;

            localBytesRead = SerializationHelper.Decode(inputStream, out pointCount);
            if (locallyDecodedBytesRemaining < localBytesRead)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
            }

            locallyDecodedBytesRemaining -= localBytesRead;
            if (0 == locallyDecodedBytesRemaining)
            {
                return(localBytesRead);
            }

            // Allocate packet properties
            int intsPerPoint       = 0; //修复构建的代码 stylusPointDescription.GetInputArrayLengthPerPoint();
            int buttonCount        = 0; //修复构建的代码 stylusPointDescription.ButtonCount;
            int buttonIntsPerPoint = (buttonCount > 0 ? 1 : 0);
            int valueIntsPerPoint  = intsPerPoint - buttonIntsPerPoint;

            //add one int per point for button data if it exists
            int[] rawPointData  = new int[pointCount * intsPerPoint];
            int[] packetDataSet = new int[pointCount];


            // copy the rest of the data from the stroke data
            byte[] inputBuffer = new byte[locallyDecodedBytesRemaining];

            // Read the input data into the byte array
            uint bytesRead = StrokeCollectionSerializer.ReliableRead(inputStream, inputBuffer, locallyDecodedBytesRemaining);

            if (bytesRead != locallyDecodedBytesRemaining)
            {
                // Make sure the bytes read are expected. If not, we should bail out.
                // An exception will be thrown.
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
            }

            // at this point, we have read all of the bytes remaining in the input
            //      stream's packet block, and while we will keep the bytes remaining
            //      variable for positioning within the local byte buffer, we should
            //      not read from the stream again, or we risk reading into another
            //      ISF tag's block.
            int originalPressureIndex = 0; //修复构建的代码 stylusPointDescription.OriginalPressureIndex;

            for (int i = 0; i < valueIntsPerPoint && locallyDecodedBytesRemaining > 0; i++)
            {
                localBytesRead = locallyDecodedBytesRemaining;
                Compressor.DecompressPacketData(
#if OLD_ISF
                    compressor,
#endif
                    inputBuffer,
                    ref localBytesRead,
                    packetDataSet);

                if (localBytesRead > locallyDecodedBytesRemaining)
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                }

                //
                // packetDataSet is like this:
                // -------------
                // |X|X|X|X|X|X|
                // -------------
                //
                // we need to copy into rawPointData at
                //
                // -------------
                // |X| |X| |X| |
                // -------------
                //
                // additionally, for NormalPressure, if it exists and was
                // reordered in the StylusPointDescription, we need to account for that here
                //
                int tempi = i;
                if (tempi > 1 &&
                    originalPressureIndex != -1 &&
                    originalPressureIndex != /* //修复构建的代码StylusPointDescription.RequiredPressureIndex*/ 2)
                {
                    //
                    // NormalPressure exists in the packet stream and was not at index 2
                    // StylusPointDescription enforces that NormalPressure is at index 2
                    // so we need to copy packet data beyond X and Y into a different location
                    //
                    // take the example of the original StylusPointDescription
                    //  |X|Y|XTilt|YTilt|NormalPressure|Rotation|
                    //
                    // originalPressureIndex is 4, and we know it is now 2
                    // which means that everything before index 4 has been shifted one
                    // and everything after index 4 is still good.  Index 4 should be copied to index 2
                    if (tempi == originalPressureIndex)
                    {
                        tempi = 2;
                    }
                    else if (tempi < originalPressureIndex)
                    {
                        tempi++;
                    }
                }

                locallyDecodedBytesRemaining -= localBytesRead;
                for (int j = 0, x = 0; j < pointCount; j++, x += intsPerPoint)
                {
                    rawPointData[x + tempi] = packetDataSet[j];
                }

                // Move the array elements to point to next set of compressed data
                for (uint u = 0; u < locallyDecodedBytesRemaining; u++)
                {
                    inputBuffer[u] = inputBuffer[u + (int)localBytesRead];
                }
            }

            // Now that we've read packet data, we must read button data if it is there
            byte[] buttonData = null;
            // since the button state is a simple bit value (either down or up), the button state
            // for a series of packets is packed into an array of bits rather than integers
            // For example, if there are 16 packets, and 2 buttons, then 32 bits can be used (e.g. 1 32-bit integer)
            if (0 != locallyDecodedBytesRemaining && buttonCount > 0)
            {
                // calculate the number of full bytes used for buttons per packet
                //   Example: 10 buttons would require 1 full byte
                int fullBytesForButtonsPerPacket = buttonCount / Native.BitsPerByte;
                // calculate the number of bits that spill beyond the full byte boundary
                //   Example: 10 buttons would require 2 extra bits (8 fit in a full byte)
                int partialBitsForButtonsPerPacket = buttonCount % Native.BitsPerByte;

                // Now figure out how many bytes we need to read for the button data
                localBytesRead = (uint)((buttonCount * pointCount + 7) / Native.BitsPerByte);
                if (localBytesRead > locallyDecodedBytesRemaining)
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Buffer range is smaller than expected expected size"));
                }
                locallyDecodedBytesRemaining -= localBytesRead;

                int buttonSizeInBytes = (buttonCount + 7) / Native.BitsPerByte;
                buttonData = new byte[pointCount * buttonSizeInBytes];

                // Create a bit reader to unpack the bits from the ISF stream into
                //    loosely packed byte buffer (e.g. button data aligned on full byte
                //    boundaries only)
                BitStreamReader bitReader =
                    new BitStreamReader(inputBuffer, (uint)buttonCount * pointCount);

                // unpack the button data into each packet
                int byteCounter = 0;
                while (!bitReader.EndOfStream)
                {
                    // unpack the fully bytes first
                    for (int fullBytes = 0; fullBytes < fullBytesForButtonsPerPacket; fullBytes++)
                    {
                        buttonData[byteCounter++] = bitReader.ReadByte(Native.BitsPerByte);
                    }
                    // then unpack a single partial byte if necessary
                    if (partialBitsForButtonsPerPacket > 0)
                    {
                        buttonData[byteCounter++] = bitReader.ReadByte((int)partialBitsForButtonsPerPacket);
                    }
                }

                // if the number of bytes allocated != necessary byte amount then an error occurred
                if (byteCounter != buttonData.Length)
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Button data length not equal to expected length"));
                }

                //
                // set the point data in the raw array
                //
                FillButtonData((int)pointCount,
                               buttonCount,
                               valueIntsPerPoint,  //gives the first button index
                               rawPointData,
                               buttonData);
            }


            stylusPoints = new StylusPointCollection(stylusPointDescription /*//修复构建的代码, rawPointData, null, transform*/);

            // if we read too far into the stream (e.g. the packets were compressed)
            //      then move the stream pointer back to the end of the actual packet
            //      data before returning. This keeps the return value on the function
            //      (representing bytes read) honest and consistent with the stream
            //      position movement in this function.
            if (0 != locallyDecodedBytesRemaining)
            {
                inputStream.Seek(0 - (long)locallyDecodedBytesRemaining, SeekOrigin.Current);
            }

            return(totalBytesInStrokeBlockOfIsfStream - locallyDecodedBytesRemaining);
        }
Exemplo n.º 3
0
        /// <summary>
        /// This functions loads a stroke from a memory stream based on the descriptor and GuidList. It returns
        /// the no of bytes it has read from the stream to correctly load the stream, which should be same as
        /// the value of the size parameter. If they are unequal throws ArgumentException. Stroke descriptor is
        /// used to load the packetproperty as well as ExtendedPropertyCollection on this stroke. Compressor is used
        /// to decompress the data.
        /// </summary>
        /// <param name="compressor"></param>
        /// <param name="stream"></param>
        /// <param name="totalBytesInStrokeBlockOfIsfStream"></param>
        /// <param name="guidList"></param>
        /// <param name="strokeDescriptor"></param>
        /// <param name="stylusPointDescription"></param>
        /// <param name="transform"></param>
        /// <param name="stylusPoints"></param>
        /// <param name="extendedProperties"></param>
        /// <returns></returns>
#else
        /// <summary>
        /// This functions loads a stroke from a memory stream based on the descriptor and GuidList. It returns
        /// the no of bytes it has read from the stream to correctly load the stream, which should be same as
        /// the value of the size parameter. If they are unequal throws ArgumentException. Stroke descriptor is
        /// used to load the packetproperty as well as ExtendedPropertyCollection on this stroke. Compressor is used
        /// to decompress the data.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="totalBytesInStrokeBlockOfIsfStream"></param>
        /// <param name="guidList"></param>
        /// <param name="strokeDescriptor"></param>
        /// <param name="stylusPointDescription"></param>
        /// <param name="transform"></param>
        /// <param name="stylusPoints"></param>
        /// <param name="extendedProperties"></param>
#endif
        static uint DecodeISFIntoStroke(
#if OLD_ISF
            Compressor compressor,
#endif
            Stream stream,
            uint totalBytesInStrokeBlockOfIsfStream,
            GuidList guidList,
            StrokeDescriptor strokeDescriptor,
            StylusPointDescription stylusPointDescription,
            Matrix transform,
            out StylusPointCollection stylusPoints,
            out ExtendedPropertyCollection extendedProperties)
        {
            stylusPoints       = null;
            extendedProperties = null;

            // We do allow a stroke with no packet data
            if (0 == totalBytesInStrokeBlockOfIsfStream)
            {
                return(0);
            }

            uint locallyDecodedBytes;
            uint remainingBytesInStrokeBlock = totalBytesInStrokeBlockOfIsfStream;

            // First try to load any packet data
            locallyDecodedBytes = LoadPackets(stream,
                                              remainingBytesInStrokeBlock,
#if OLD_ISF
                                              compressor,
#endif
                                              stylusPointDescription,
                                              transform,
                                              out stylusPoints);

            if (locallyDecodedBytes > remainingBytesInStrokeBlock)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Packet buffer overflowed the ISF stream"));
            }

            remainingBytesInStrokeBlock -= locallyDecodedBytes;
            if (0 == remainingBytesInStrokeBlock)
            {
                return(locallyDecodedBytes);
            }

            // Now read the extended propertes
            for (int iTag = 1; iTag < strokeDescriptor.Template.Count && remainingBytesInStrokeBlock > 0; iTag++)
            {
                KnownTagCache.KnownTagIndex tag = strokeDescriptor.Template[iTag - 1];

                switch (tag)
                {
                case MS.Internal.Ink.InkSerializedFormat.KnownTagCache.KnownTagIndex.StrokePropertyList:
                {
                    // we've found the stroke extended properties. Load them now.
                    while (iTag < strokeDescriptor.Template.Count && remainingBytesInStrokeBlock > 0)
                    {
                        tag = strokeDescriptor.Template[iTag];

                        object data;
                        Guid   guid = guidList.FindGuid(tag);
                        if (guid == Guid.Empty)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Stroke Custom Attribute tag embedded in ISF stream does not match guid table"));
                        }

                        // load the extended property data from the stream (and decode the type)
                        locallyDecodedBytes = ExtendedPropertySerializer.DecodeAsISF(stream, remainingBytesInStrokeBlock, guidList, tag, ref guid, out data);

                        // add the guid/data pair into the property collection (don't redecode the type)
                        if (extendedProperties == null)
                        {
                            extendedProperties = new ExtendedPropertyCollection();
                        }
                        extendedProperties[guid] = data;
                        if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                        }

                        remainingBytesInStrokeBlock -= locallyDecodedBytes;
                        iTag++;
                    }
                }
                break;

                case MS.Internal.Ink.InkSerializedFormat.KnownTagCache.KnownTagIndex.Buttons:
                {
                    // Next tag is count of buttons and the tags for the button guids
                    iTag += (int)((uint)strokeDescriptor.Template[iTag]) + 1;
                }
                break;

                // ignore any tags embedded in the Stroke block that this
                //      version of the ISF decoder doesn't understand
                default:
                {
                    System.Diagnostics.Trace.WriteLine("Ignoring unhandled stroke tag in ISF stroke descriptor");
                }
                break;
                }
            }

            // Now try to load any tagged property data or point property data
            while (remainingBytesInStrokeBlock > 0)
            {
                // Read the tag first
                KnownTagCache.KnownTagIndex tag;
                uint uiTag;

                locallyDecodedBytes = SerializationHelper.Decode(stream, out uiTag);
                tag = (KnownTagCache.KnownTagIndex)uiTag;
                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                }

                remainingBytesInStrokeBlock -= locallyDecodedBytes;

                // if it is a point property block
                switch (tag)
                {
                case MS.Internal.Ink.InkSerializedFormat.KnownTagCache.KnownTagIndex.PointProperty:
                {
                    // First load the totalBytesInStrokeBlockOfIsfStream of the point property block
                    uint cbsize;

                    locallyDecodedBytes = SerializationHelper.Decode(stream, out cbsize);
                    if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                    {
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                    }

                    remainingBytesInStrokeBlock -= locallyDecodedBytes;
                    while (remainingBytesInStrokeBlock > 0)
                    {
                        // First read the tag corresponding to the property
                        locallyDecodedBytes = SerializationHelper.Decode(stream, out uiTag);
                        tag = (KnownTagCache.KnownTagIndex)uiTag;
                        if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                        }

                        remainingBytesInStrokeBlock -= locallyDecodedBytes;

                        // Now read the packet index for which the property will apply
                        uint propindex;

                        locallyDecodedBytes = SerializationHelper.Decode(stream, out propindex);
                        if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                        }

                        remainingBytesInStrokeBlock -= locallyDecodedBytes;

                        uint propsize;

                        locallyDecodedBytes = SerializationHelper.Decode(stream, out propsize);
                        if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                        }

                        remainingBytesInStrokeBlock -= locallyDecodedBytes;

                        // Compressed data totalBytesInStrokeBlockOfIsfStream
                        propsize += 1;

                        // Make sure we have enough data to read
                        if (propsize > remainingBytesInStrokeBlock)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
                        }

                        byte[] in_buffer = new byte[propsize];

                        uint bytesRead = StrokeCollectionSerializer.ReliableRead(stream, in_buffer, propsize);
                        if (propsize != bytesRead)
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Read different size from stream then expected"));
                        }

                        byte[] out_buffer = Compressor.DecompressPropertyData(in_buffer);

                        System.Diagnostics.Debug.Assert(false, "ExtendedProperties for points are not supported");

                        // skip the bytes in both success & failure cases
                        // Note: Point ExtendedProperties are discarded
                        remainingBytesInStrokeBlock -= propsize;
                    }
                }
                break;

                default:
                {
                    object data;
                    Guid   guid = guidList.FindGuid(tag);
                    if (guid == Guid.Empty)
                    {
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Stroke Custom Attribute tag embedded in ISF stream does not match guid table"));
                    }

                    // load the extended property data from the stream (and decode the type)
                    locallyDecodedBytes = ExtendedPropertySerializer.DecodeAsISF(stream, remainingBytesInStrokeBlock, guidList, tag, ref guid, out data);

                    // add the guid/data pair into the property collection (don't redecode the type)
                    if (extendedProperties == null)
                    {
                        extendedProperties = new ExtendedPropertyCollection();
                    }
                    extendedProperties[guid] = data;
                    if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                    {
                        throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream exceeded ISF stream totalBytesInStrokeBlockOfIsfStream"));
                    }

                    remainingBytesInStrokeBlock -= locallyDecodedBytes;
                }
                break;
                }
            }

            if (0 != remainingBytesInStrokeBlock)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));
            }

            return(totalBytesInStrokeBlockOfIsfStream);
        }