/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: IIOPipeProcessor.hpp Date: 2022-6-6 Author: Reece ***/ #pragma once namespace Aurora::IO { struct IIOPipeInterceptor; struct IPipeFrames { /** * @brief pipe starting hook */ virtual void OnStart() = 0; /** * @brief This function is called once the stream reader returns zero * You should use this opportunity to schedule the next waitable item state (eg, initiate async read, set event high, etc) * You can return false to soft-fail the pipe to indicate EoS * You should otherwise return true in order to continue yield until the next waitable item state change * Note, an EoS event may also occur during the next alert state change should the stream reader return an error */ virtual void OnEndPump() = 0; /** * @brief pipe shutdown hook */ virtual void OnEnd(bool fatal) = 0; }; struct IOPipeData { /** * @brief IO events */ AuSPtr watchItem; /** * @brief Input source */ AuSPtr reader; /** * @brief Output drain */ AuSPtr writer; /** * @brief Callbacks */ AuSPtr frames; /** * @brief Enables aggressive stream consumption, allowing for bias towards clients if they were to send a lot of data (including dos) * Instead of reading the input stream once, so long as the output stream written paremeter yields a non-zero number, bytes * will continue to pump through the writer. Breakdown of the pipe is expected on reader oversaturation as defined by the * IOPipeRequest */ bool bShouldReadUntilZero {}; bool bFlush {true}; }; struct IOPipeRequest { /** * @brief Amount of bytes to transfer or zero if stream */ AuUInt32 lengthOrZero {}; /** * @brief internal frame size or zero if fallback */ AuUInt32 pageLengthOrZero {}; /** * @brief event listener */ AuSPtr listener; /** * @brief Used as the buffer size for streams of page length 0 */ AuUInt32 fallbackPageSize {4096 * 50}; AuSPtr processor; }; struct IOPipeRequestBasic : IOPipeRequest { /** * @brief The two streams to join and an invokable object */ IOPipeData data; }; struct IOPipeRequestAIO : IOPipeRequest { AuSPtr asyncTransaction; AuSPtr writer; bool shouldReadUntilZero {}; }; struct IIOPipeWork { /** * @brief * @return false should no IIOPipeEventListener event ever be fired. you should generally expect callback based failure. */ virtual bool Start() = 0; virtual bool End() = 0; }; /** * @brief Different operating systems implement high level stream copy abstraction between network, file, and/or file descriptors. * This interface connects arbitrary stream objects to one another by piping data under an iprocessor tick; or delegates * such task to the operating system, if possible. */ struct IIOPipeProcessor { /** * @brief * @param request * @return */ virtual AuSPtr NewBasicPipe(const IOPipeRequestBasic &request) = 0; /** * @brief */ virtual AuSPtr NewAIOPipe(const IOPipeRequestAIO &request) = 0; }; }