Ejemplo n.º 1
0
        public static MemoryStreamAdapter GetMemoryStreamAdapter(MemoryStream memoryStream)
        {
            MemoryStreamAdapter adapter = new MemoryStreamAdapter();

            // If the MemoryStream's inner buffer is visible, mark it as such in the proxy object.
            // We'll also try to avoid the copy of the MemoryStream's inner buffer, but we can
            // only do this if there's no leading or trailing data surrounding the real to-be-serialized
            // segment.

            if (memoryStream.TryGetBuffer(out ArraySegment <byte> innerBuffer))
            {
                adapter.Exposable = true;
                if (innerBuffer.Count == innerBuffer.Array !.Length)
                {
                    adapter.Buffer = innerBuffer.Array;
                }
            }

            adapter.Buffer ??= memoryStream.ToArray(); // couldn't get the inner buffer; clone it now

            // Copy additional information to the proxy object

            adapter.Length   = checked ((int)memoryStream.Length);
            adapter.Capacity = memoryStream.Capacity;
            adapter.Position = checked ((int)memoryStream.Position);
            adapter.Writable = memoryStream.CanWrite;
            adapter.Origin   = 0; // Length, Capacity, and Position are already offset appropriately

            // Properties below are needed for Full Framework back-compat.

            adapter.Expandable = false; // we have no way of knowing this, so default it to false
            adapter.IsOpen     = true;  // we know this is true because the earlier prop accessors didn't throw

            return(adapter);
        }
Ejemplo n.º 2
0
        public static MemoryStream GetMemoryStream(MemoryStreamAdapter value)
        {
            // The input may be coming from an untrusted payload, so we perform a few extra
            // checks. We'll slice the buffer ourselves to validate that origin and length are
            // accurate, creating a new buffer that doesn't have any leading or trailing data.
            // The AsSpan method performs argument validation on our behalf. We'll also validate
            // that the desired Position is not beyond the end of the buffer, otherwise subsequent
            // accesses to the buffer may cause unintended allocations. Some properties (Capacity,
            // IsOpen, etc.) are ignored since we allow the MemoryStream ctor to set them itself.

            byte[]      buffer       = value.Buffer !; // we don't expect this to be null, but if it is we'll throw NRE below
            Span <byte> slicedBuffer = value.Buffer.AsSpan(value.Origin, value.Length - value.Origin);

            if (slicedBuffer.Length < buffer.Length)
            {
                buffer = slicedBuffer.ToArray(); // trim leading and trailing data
            }

            MemoryStream memoryStream = new MemoryStream(
                buffer: buffer,
                index: 0,
                count: buffer.Length,
                writable: value.Writable,
                publiclyVisible: value.Exposable);

            int desiredPosition = value.Position - value.Origin;

            if (desiredPosition < 0 || desiredPosition > memoryStream.Length)
            {
                throw new InvalidOperationException();
            }
            memoryStream.Position = desiredPosition;

            return(memoryStream);
        }
Ejemplo n.º 3
0
        private static object ResolveAdapterType(object obj, ClassDataContract classContract)
        {
            Type type = obj.GetType();

            if (type == Globals.TypeOfDateTimeOffset)
            {
                obj = DateTimeOffsetAdapter.GetDateTimeOffsetAdapter((DateTimeOffset)obj);
            }
            else if (type == Globals.TypeOfMemoryStream)
            {
                obj = MemoryStreamAdapter.GetMemoryStreamAdapter((MemoryStream)obj);
            }
            return(obj);
        }
Ejemplo n.º 4
0
        private static object ResolveAdapterType(object obj, ClassDataContract classContract)
        {
            Type type = obj.GetType();

            if (type == Globals.TypeOfDateTimeOffset)
            {
                obj = DateTimeOffsetAdapter.GetDateTimeOffsetAdapter((DateTimeOffset)obj);
            }
            else if (type == Globals.TypeOfMemoryStream)
            {
                obj = MemoryStreamAdapter.GetMemoryStreamAdapter((MemoryStream)obj);
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfKeyValuePair)
            {
                obj = classContract.KeyValuePairAdapterConstructorInfo !.Invoke(new object[] { obj });
            }

            return(obj);
        }