/*
 * Copyright 2021 Jactry Zeng for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifdef __WIDL__
#pragma winrt ns_prefix
#endif

import "inspectable.idl";
import "eventtoken.idl";
import "windows.foundation.idl";

namespace Windows.Storage.Streams {
    interface IBuffer;
    interface IBufferFactory;
    interface IBufferStatics;
    interface IContentTypeProvider;
    interface IInputStream;
    interface IOutputStream;
    interface IRandomAccessStream;
    interface IRandomAccessStreamWithContentType;
    runtimeclass Buffer;

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        uuid(905a0fe0-bc53-11df-8c49-001e4fc686da)
    ]
    interface IBuffer : IInspectable
    {
        [propget] HRESULT Capacity([out, retval] UINT32 *value);
        [propget] HRESULT Length([out, retval] UINT32 *value);
        [propput] HRESULT Length([in] UINT32 value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Storage.Streams.Buffer),
        uuid(71af914d-c10f-484b-bc50-14bc623b3a27)
    ]
    interface IBufferFactory : IInspectable
    {
        HRESULT Create([in, range(0x00000000, 0x7fffffff)] UINT32 capacity,
                       [out, retval] Windows.Storage.Streams.Buffer **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Storage.Streams.Buffer),
        uuid(e901e65b-d716-475a-a90a-af7229b1e741)
    ]
    interface IBufferStatics : IInspectable
    {
        HRESULT CreateCopyFromMemoryBuffer([in] Windows.Foundation.IMemoryBuffer *input,
                                           [out, retval] Windows.Storage.Streams.Buffer **value);
        HRESULT CreateMemoryBufferOverIBuffer([in] Windows.Storage.Streams.IBuffer *input,
                                              [out, retval] Windows.Foundation.MemoryBuffer **value);
    }

    [
        uuid(cc254827-4b3d-438f-9232-10c76bc7e038),
    ]
    interface IRandomAccessStreamWithContentType : IInspectable
        requires
            Windows.Storage.Streams.IRandomAccessStream,
            Windows.Foundation.IClosable,
            Windows.Storage.Streams.IInputStream,
            Windows.Storage.Streams.IOutputStream,
            Windows.Storage.Streams.IContentTypeProvider
    {
    }

    [
        activatable(Windows.Storage.Streams.IBufferFactory, Windows.Foundation.UniversalApiContract, 1.0),
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(agile),
        static(Windows.Storage.Streams.IBufferStatics, Windows.Foundation.UniversalApiContract, 1.0),
        threading(both)
    ]
    runtimeclass Buffer
    {
        [default] interface Windows.Storage.Streams.IBuffer;
    }
}
