
/*---------------------------------------------------------------------------*/
/* elfbinary.h	    													     */
/* copyright (c) innovaphone 2024                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

static constexpr uint16_t USER_DATA_FLAG_COMPRESSED = 0x0001;

typedef enum class elf_architecture {
    ELF_UNKOWN,
    ELF_ARM,
    ELF_X86_64,
    ELF_ARM64
} elf_architecture_t;

class IElfBinary {
public:
    enum class UserDataID {
        NONE        = 0x0000,
        HTTP_FILES  = 0x0001,
        MANIFEST    = 0x0002,
        SIGNATURE   = 0x0003,
        USER        = 0x7FFF
    };

    UserDataID MakeUserID(word userDefinedValue) { return static_cast<UserDataID>(static_cast<int>(UserDataID::USER) + userDefinedValue); }

    static class IElfBinary * Open(const char * bin, class IInstanceLog * log);
    static const char * UserDataIDToStr(IElfBinary::UserDataID id);

    virtual ~IElfBinary() {}
    virtual bool IsOpen() = 0;
    virtual bool IsElfBinary() = 0;
    virtual bool IsExecutable() = 0;
    virtual elf_architecture_t GetArchitecture() = 0;
    virtual bool Close() = 0;
    virtual class IElfUserData * GetUserData(UserDataID userDataID) = 0;
    virtual bool HasUserData(UserDataID userDataID) = 0;
    virtual size_t GetSharedLibrariesCount() = 0;
    virtual const char * GetSharedLibrary(size_t index) = 0;
    virtual bool HasUserDataBlock() = 0;
};

class IElfUserDataBuffer {
public:
    IElfUserDataBuffer() {}
    virtual ~IElfUserDataBuffer() {}
    virtual size_t Size() = 0;
    virtual byte * Data() = 0;
};

class IElfUserData {
public:
    enum Origin {
        START,
        CURRENT,
        END
    };

    virtual ~IElfUserData() {}

    virtual IElfBinary::UserDataID ID() = 0;
    virtual size_t Size() = 0;
    virtual size_t Pos() = 0;
    virtual bool EoF() = 0;
    virtual bool Seek(size_t offset, Origin origin = Origin::START) = 0;
    virtual size_t Read(void * buffer, size_t bufferLen) = 0;
    virtual IElfUserDataBuffer * ReadData() = 0;
    virtual word Flags() = 0;
};
