namespace axl::io

namespace io {

// namespaces

namespace axl::io::psx;
namespace axl::io::win;

// typedefs

typedef void SslInfoCallbackFunc(
    const SSL *ssl,
    int where,
    int ret
    );

typedef int SslVerifyCallbackFunc(
    int isPreVerifyOk,
    X509_STORE_CTX *ctx
    );

typedef DH* SslTmpDhCallbackFunc(
    SSL *ssl,
    int isExport,
    int keyLength
    );

typedef sl::Handle<libusb_config_descriptor*, FreeUsbConfigDescriptor> UsbConfigDescriptor;

// enums

enum FileFlag;
enum NetworkAdapterFlag;
enum NetworkAdapterType;
enum PcapLoopResult;
enum SerialFlowControl;
enum SerialParity;
enum SerialSettingId;
enum SerialStatusLine;
enum SerialStopBits;
enum SharedMemoryTransportConst;
enum SharedMemoryTransportFlag;
enum SharedMemoryTransportState;
enum SocketShutdownKind;

// structs

struct NetworkAdapterAddress;
struct SerialSettings;
struct SharedMemoryTransportHdr;
struct SharedMemoryTransportMessageHdr;
struct SockAddr;

// classes

class AutoDeleteFile;
class ClosePcap;
class CloseUsbContext;
class File;
class FileEnumerator;
class FileTransport;
class FreeSsl;
class FreeSslCtx;
class FreeUsbConfigDescriptor;
class FreeUsbDeviceList;
class FreeUsbTransfer;
class MappedFile;
class MappedViewMgr;
class Mapping;
class NetworkAdapterDesc;
class Pcap;
class PcapFilter;
class Serial;
class SerialPortDesc;
class SharedMemoryReader;
class SharedMemoryTransportBase;
class SharedMemoryWriter;
class SimpleMappedFile;
class Socket;
class Socketransport;
class Ssl;
class SslCtx;
class Transport;
class UsbContext;
class UsbDevice;
class UsbDeviceList;
class UsbError;
class UsbErrorProvider;
class UsbEventThread;
class UsbTransfer;

// global functions

uint64_t
copyFile(
    const sl::StringRef& srcFileName,
    const sl::StringRef& dstFileName,
    uint64_t size = -1
    );

uint64_t
copyFile(
    const io::File* srcFile,
    const sl::StringRef& dstFileName,
    uint64_t size = -1
    );

uint64_t
copyFile(
    const io::File* srcFile,
    io::File* dstFile,
    uint64_t size = -1
    );

sl::String
getTempDir();

sl::String
getHomeDir();

sl::String
getCurrentDir();

bool
setCurrentDir(const sl::StringRef& dir);

sl::String
getExeFilePath();

sl::String
getExeDir();

bool
doesFileExist(const sl::StringRef& fileName);

bool
ensureDirExists(const sl::StringRef& fileName);

bool
isDir(const sl::StringRef& fileName);

sl::String
getFullFilePath(const sl::StringRef& fileName);

sl::String
getDir(const sl::StringRef& filePath);

sl::String
getFileName(const sl::StringRef& filePath);

sl::String
getExtension(const sl::StringRef& filePath);

sl::String
concatFilePath(
    sl::String* filePath,
    const sl::StringRef& fileName
    );

sl::String
concatFilePath(
    const sl::StringRef& dir,
    const sl::StringRef& fileName
    );

sl::String
findFilePath(
    const sl::StringRef& fileName,
    const sl::StringRef& firstDir,
    const sl::BoxList<sl::String>* dirList,
    bool doFindInCurrentDir = true
    );

sl::String
findFilePath(
    const sl::StringRef& fileName,
    const sl::BoxList<sl::String>* dirList,
    bool doFindInCurrentDir = true
    );

bool
isSymbolicLink(const sl::StringRef& fileName);

bool
getSymbolicLinkTarget(
    sl::String* targetName,
    const sl::StringRef& linkName
    );

sl::String
getSymbolicLinkTarget(const sl::StringRef& linkName);

bool
matchWildcard(
    const sl::StringRef& string0,
    const sl::StringRef& wildcard
    );

const char*
getNetworkAdapterTypeString(NetworkAdapterType adapterKind);

NetworkAdapterFlag
getFirstNetworkAdapterFlag(uint_t flags);

const char*
getNetworkAdapterFlagString(NetworkAdapterFlag flag);

sl::String
getNetworkAdapterFlagString(uint_t flags);

size_t
getMacAddressString(
    sl::String* string,
    const uchar_t* macAddress,
    uint_t flags = 0
    );

sl::String
getMacAddressString(
    const uchar_t* macAddress,
    uint_t flags = 0
    );

size_t
createNetworkAdapterDescList(sl::List<NetworkAdapterDesc>* adapterList);

size_t
createSerialPortDescList(sl::List<SerialPortDesc>* portList);

const char*
getSockAddrFamilyString(uint_t family);

size_t
getSockAddrFamilySize(uint_t family);

size_t
getSockAddrSize(const sockaddr* addr);

const char*
getSockProtoString(uint_t proto);

size_t
getSockAddrNetMaskBitCount_ip4(const sockaddr_in* addr);

size_t
getSockAddrNetMaskBitCount_ip6(const sockaddr_in6* addr);

size_t
getSockAddrNetMaskBitCount(const sockaddr* addr);

void
createSockAddrNetMask_ip4(
    sockaddr_in* addr,
    size_t bitCount
    );

void
createSockAddrNetMask_ip6(
    sockaddr_in6* addr,
    size_t bitCount
    );

bool
isSockAddrEqual_ip4(
    const sockaddr_in* addr1,
    const sockaddr_in* addr2
    );

bool
isSockAddrEqual_ip6(
    const sockaddr_in6* addr1,
    const sockaddr_in6* addr2
    );

bool
isSockAddrEqual(
    const sockaddr* addr1,
    const sockaddr* addr2
    );

bool
isSockAddrMatch_ip4(
    const sockaddr_in* addr,
    const sockaddr_in* filterAddr
    );

bool
isSockAddrMatch_ip6(
    const sockaddr_in6* addr,
    const sockaddr_in6* filterAddr
    );

bool
isSockAddrMatch(
    const sockaddr* addr,
    const sockaddr* filterAddr
    );

bool
parseAddr_ip4(
    in_addr* addr,
    const sl::StringRef& string
    );

bool
parseAddr_ip6(
    in6_addr* addr,
    const sl::StringRef& string
    );

bool
parseSockAddr_ip4(
    sockaddr_in* addr,
    const sl::StringRef& string
    );

bool
parseSockAddr_ip6(
    sockaddr_in6* addr,
    const sl::StringRef& string
    );

bool
parseSockAddr(
    sockaddr* addr,
    size_t size,
    const sl::StringRef& string
    );

size_t
getAddrString_ip4(
    sl::String* string,
    const in_addr* addr
    );

sl::String
getAddrString_ip4(const in_addr* addr);

size_t
getAddrString_ip6(
    sl::String* string,
    const in6_addr* addr
    );

sl::String
getAddrString_ip6(const in6_addr* addr);

size_t
getSockAddrString_ip4(
    sl::String* string,
    const sockaddr_in* addr
    );

sl::String
getSockAddrString_ip4(const sockaddr_in* addr);

size_t
getSockAddrString_ip6(
    sl::String* string,
    const sockaddr_in6* addr
    );

sl::String
getSockAddrString_ip6(const sockaddr_in6* addr);

size_t
getSockAddrString(
    sl::String* string,
    const sockaddr* addr
    );

sl::String
getSockAddrString(const sockaddr* addr);

bool
resolveHostName(
    sl::Array<SockAddr>* addrArray,
    const sl::StringRef& name,
    uint_t family = AF_UNSPEC
    );

sl::Array<SockAddr>
resolveHostName(
    const sl::StringRef& name,
    uint_t family = AF_UNSPEC
    );

void
registerSslErrorProvider();

UsbContext*
getUsbDefaultContext();

bool
hasUsbCapability(uint32_t capability);

const char*
getUsbSpeedString(libusb_speed speed);

const char*
getUsbClassCodeString(libusb_class_code classCode);

const char*
getUsbTransferTypeString(libusb_transfer_type transferType);

const libusb_interface_descriptor*
findUsbInterfaceDescriptor(
    const libusb_config_descriptor* configDesc,
    uint_t interfaceId,
    uint_t altSettingId
    );

const libusb_endpoint_descriptor*
findUsbEndpointDescriptor(
    const libusb_interface_descriptor* ifaceDesc,
    uint_t endpointId
    );

const libusb_endpoint_descriptor*
findUsbEndpointDescriptor(
    const libusb_config_descriptor* configDesc,
    uint_t endpointId,
    uint_t interfaceId = 0,
    uint_t altSettingId = 0
    );

AXL_SL_DEFINE_GUID(
    g_usbErrorGuid,
    0x87ea0738,
    0x52e9,
    0x4769,
    0xb7,
    0x27,
    0x7a,
    0x17,
    0x37,
    0x7b,
    0x92,
    0x1e
    );

void
registerUsbErrorProvider();

UsbEventThread*
getUsbDefaultContextEventThread();

const char*
getUsbTransferStatusString(libusb_transfer_status status);

} // namespace io