first commit
This commit is contained in:
65
src/Streams/BufferedStream.cpp
Normal file
65
src/Streams/BufferedStream.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include "TessesFramework/Streams/BufferedStream.hpp"
|
||||
namespace Tesses::Framework::Streams {
|
||||
BufferedStream::BufferedStream(Stream* strm, bool owns, size_t bufferSize)
|
||||
{
|
||||
this->strm = strm;
|
||||
this->owns = owns;
|
||||
this->bufferSize = bufferSize;
|
||||
this->buffer = new uint8_t[bufferSize];
|
||||
this->read = 0;
|
||||
this->offset = 0;
|
||||
}
|
||||
BufferedStream::BufferedStream(Stream& strm, size_t bufferSize) : BufferedStream(&strm,false, bufferSize)
|
||||
{
|
||||
|
||||
}
|
||||
bool BufferedStream::EndOfStream()
|
||||
{
|
||||
if(this->offset < this->read) return false;
|
||||
return this->strm->EndOfStream();
|
||||
}
|
||||
bool BufferedStream::CanRead()
|
||||
{
|
||||
if(this->offset < this->read) return true;
|
||||
return this->strm->CanRead();
|
||||
}
|
||||
bool BufferedStream::CanWrite()
|
||||
{
|
||||
return this->strm->CanWrite();
|
||||
}
|
||||
size_t BufferedStream::Read(uint8_t* buff, size_t sz)
|
||||
{
|
||||
if(this->offset < this->read)
|
||||
{
|
||||
sz = std::min(sz,this->read-this->offset);
|
||||
memcpy(buff, this->buffer+this->offset, sz);
|
||||
this->offset+=sz;
|
||||
return sz;
|
||||
}
|
||||
if(sz < this->bufferSize)
|
||||
{
|
||||
this->read = this->strm->Read(this->buffer, this->bufferSize);
|
||||
this->offset=0;
|
||||
|
||||
sz = std::min(sz,this->read-this->offset);
|
||||
memcpy(buff, this->buffer+this->offset, sz);
|
||||
this->offset+=sz;
|
||||
return sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->strm->Read(buff, sz);
|
||||
}
|
||||
}
|
||||
size_t BufferedStream::Write(const uint8_t* buff, size_t sz)
|
||||
{
|
||||
return this->strm->Write(buff,sz);
|
||||
}
|
||||
|
||||
BufferedStream::~BufferedStream()
|
||||
{
|
||||
if(this->owns)
|
||||
delete this->strm;
|
||||
delete buffer;
|
||||
}
|
||||
}
|
||||
84
src/Streams/FileStream.cpp
Normal file
84
src/Streams/FileStream.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include "TessesFramework/Streams/FileStream.hpp"
|
||||
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
void FileStream::SetMode(std::string mode)
|
||||
{
|
||||
this->canRead = false;
|
||||
this->canWrite = false;
|
||||
this->canSeek = true;
|
||||
if(mode.size() >= 1)
|
||||
{
|
||||
if(mode[0] == 'r')
|
||||
{
|
||||
this->canRead = true;
|
||||
}
|
||||
else if(mode[0] == 'w')
|
||||
{
|
||||
this->canWrite = true;
|
||||
}
|
||||
else if(mode[0] == 'a')
|
||||
{
|
||||
this->canSeek = false;
|
||||
this->canWrite = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(((mode.size() >= 2 && mode[1] == '+') || (mode.size() >= 2 && mode[1] == 'b' && mode[2] == '+')))
|
||||
{
|
||||
this->canRead = true;
|
||||
this->canWrite = true;
|
||||
}
|
||||
}
|
||||
FileStream::FileStream(std::filesystem::path p, std::string mode)
|
||||
{
|
||||
this->f = fopen(p.c_str(),mode.c_str());
|
||||
this->canSeek = true;
|
||||
this->owns=true;
|
||||
this->SetMode(mode);
|
||||
}
|
||||
FileStream::FileStream(FILE* f, bool owns, std::string mode , bool canSeek)
|
||||
{
|
||||
this->f = f;
|
||||
this->owns = owns;
|
||||
this->SetMode(mode);
|
||||
this->canSeek = canSeek;
|
||||
}
|
||||
size_t FileStream::Read(uint8_t* buff, size_t sz)
|
||||
{
|
||||
return fread(buff,1, sz, this->f);
|
||||
}
|
||||
size_t FileStream::Write(const uint8_t* buff, size_t sz)
|
||||
{
|
||||
return fwrite(buff,1, sz, f);
|
||||
}
|
||||
bool FileStream::CanRead()
|
||||
{
|
||||
return this->canRead;
|
||||
}
|
||||
bool FileStream::CanWrite()
|
||||
{
|
||||
return this->canWrite;
|
||||
}
|
||||
bool FileStream::CanSeek()
|
||||
{
|
||||
return this->canSeek;
|
||||
}
|
||||
int64_t FileStream::GetPosition()
|
||||
{
|
||||
return (int64_t)ftello(this->f);
|
||||
}
|
||||
void FileStream::Flush()
|
||||
{
|
||||
fflush(this->f);
|
||||
}
|
||||
void FileStream::Seek(int64_t pos, SeekOrigin whence)
|
||||
{
|
||||
fseeko(this->f,(off_t)pos,whence == SeekOrigin::Begin ? SEEK_SET : whence == SeekOrigin::Current ? SEEK_CUR : SEEK_END);
|
||||
}
|
||||
FileStream::~FileStream()
|
||||
{
|
||||
if(this->owns)
|
||||
fclose(this->f);
|
||||
}
|
||||
}
|
||||
68
src/Streams/MemoryStream.cpp
Normal file
68
src/Streams/MemoryStream.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "TessesFramework/Streams/MemoryStream.hpp"
|
||||
|
||||
namespace Tesses::Framework::Streams
|
||||
{
|
||||
MemoryStream::MemoryStream(bool isWritable)
|
||||
{
|
||||
this->offset=0;
|
||||
this->writable = isWritable;
|
||||
}
|
||||
std::vector<uint8_t>& MemoryStream::GetBuffer()
|
||||
{
|
||||
return this->buffer;
|
||||
}
|
||||
size_t MemoryStream::Read(uint8_t* buff, size_t sz)
|
||||
{
|
||||
if(this->offset >= this->buffer.size()) return 0;
|
||||
size_t toRead = std::min(sz, this->buffer.size()-this->offset);
|
||||
memcpy(buff, this->buffer.data() + this->offset, sz);
|
||||
this->offset += toRead;
|
||||
return toRead;
|
||||
}
|
||||
size_t MemoryStream::Write(const uint8_t* buff, size_t sz)
|
||||
{
|
||||
if(!this->writable) return 0;
|
||||
if(this->offset > this->buffer.size())
|
||||
{
|
||||
this->buffer.resize(this->offset+sz);
|
||||
}
|
||||
this->buffer.insert(this->buffer.begin()+this->offset, buff, buff+sz);
|
||||
this->offset+=sz;
|
||||
return sz;
|
||||
}
|
||||
bool MemoryStream::CanRead()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool MemoryStream::CanWrite()
|
||||
{
|
||||
return this->writable;
|
||||
}
|
||||
bool MemoryStream::CanSeek()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int64_t MemoryStream::GetLength()
|
||||
{
|
||||
return this->buffer.size();
|
||||
}
|
||||
int64_t MemoryStream::GetPosition()
|
||||
{
|
||||
return (int64_t)this->offset;
|
||||
}
|
||||
void MemoryStream::Seek(int64_t pos, SeekOrigin whence)
|
||||
{
|
||||
switch(whence)
|
||||
{
|
||||
case SeekOrigin::Begin:
|
||||
this->offset = (size_t)pos;
|
||||
break;
|
||||
case SeekOrigin::Current:
|
||||
this->offset += (size_t)pos;
|
||||
break;
|
||||
case SeekOrigin::End:
|
||||
this->offset = (size_t)(this->buffer.size() + pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
528
src/Streams/NetworkStream.cpp
Normal file
528
src/Streams/NetworkStream.cpp
Normal file
@ -0,0 +1,528 @@
|
||||
#include "TessesFramework/Streams/NetworkStream.hpp"
|
||||
#include "TessesFramework/Http/HttpUtils.hpp"
|
||||
|
||||
using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
||||
#if defined(GEKKO)
|
||||
|
||||
#define ss_family sin_family
|
||||
#endif
|
||||
#if defined(GEKKO) && !(defined(TESSESFRAMEWORK_USE_WII_SOCKET) && defined(HW_RVL))
|
||||
#include <network.h>
|
||||
#define NETWORK_RECV net_recv
|
||||
#define sockaddr_storage sockaddr_in
|
||||
#error "Not supported yet"
|
||||
#else
|
||||
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
}
|
||||
#if defined(GEKKO)
|
||||
|
||||
extern "C" uint32_t if_config( char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries);
|
||||
#else
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#define NETWORK_SEND send
|
||||
#define NETWORK_RECV recv
|
||||
#define NETWORK_SENDTO sendto
|
||||
#define NETWORK_RECVFROM recvfrom
|
||||
#define NETWORK_SOCKET socket
|
||||
#define NETWORK_SETSOCKOPT setsockopt
|
||||
#define NETWORK_CONNECT connect
|
||||
#define NETWORK_BIND bind
|
||||
#define NETWORK_LISTEN listen
|
||||
#define NETWORK_ACCEPT accept
|
||||
#define NETWORK_GETADDRINFO getaddrinfo
|
||||
#define NETWORK_FREEADDRINFO freeaddrinfo
|
||||
#define NETWORK_CLOSE close
|
||||
#endif
|
||||
|
||||
#undef AF_INET6
|
||||
|
||||
|
||||
namespace Tesses::Framework::Streams {
|
||||
std::string StringifyIP(struct sockaddr* addr);
|
||||
std::vector<std::pair<std::string,std::string>> NetworkStream::GetIPs(bool ipV6)
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> ipConfig;
|
||||
|
||||
#if defined(GEKKO)
|
||||
//if_config( char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries);
|
||||
char localIp[16];
|
||||
char netmask[16];
|
||||
char gateway[16];
|
||||
if_config(localIp,netmask, gateway, true, 1);
|
||||
ipConfig.push_back(std::pair<std::string,std::string>("net",localIp));
|
||||
#else
|
||||
struct ifaddrs *ifAddrStruct = NULL;
|
||||
getifaddrs(&ifAddrStruct);
|
||||
|
||||
for (struct ifaddrs *ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) { // IPv4
|
||||
|
||||
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
||||
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
if (ifa->ifa_addr->sa_family == AF_INET6 && ipV6) { // IPv6
|
||||
|
||||
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
freeifaddrs(ifAddrStruct);
|
||||
#endif
|
||||
return ipConfig;
|
||||
|
||||
}
|
||||
void SetPort(struct sockaddr* addr, uint16_t port)
|
||||
{
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in* a = (struct sockaddr_in*)addr;\
|
||||
a->sin_port = htons(port);
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
if(addr->sa_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
||||
a->sin6_port = htons(port);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
uint16_t GetPort(struct sockaddr* addr)
|
||||
{
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in* a = (struct sockaddr_in*)addr;\
|
||||
return ntohs(a->sin_port);
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
if(addr->sa_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
||||
return ntohs(a->sin6_port);
|
||||
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
bool IPParse(std::string str,struct sockaddr_storage* addr)
|
||||
{
|
||||
memset(addr,0,sizeof(struct sockaddr_storage));
|
||||
uint8_t ip[16];
|
||||
if(inet_pton(AF_INET,str.c_str(),ip)==1)
|
||||
{
|
||||
struct sockaddr_in* inAddr = (struct sockaddr_in*)addr;
|
||||
inAddr->sin_family = AF_INET;
|
||||
memcpy(&inAddr->sin_addr,ip,4);
|
||||
return true;
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
if(inet_pton(AF_INET6,str.c_str(),ip)==1)
|
||||
{
|
||||
|
||||
struct sockaddr_in6* inAddr = (struct sockaddr_in6*)addr;
|
||||
|
||||
inAddr->sin6_family = AF_INET6;
|
||||
memcpy(&inAddr->sin6_addr,ip,16);
|
||||
return 6;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string StringifyIP(struct sockaddr* addr)
|
||||
{
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
uint8_t* ip = (uint8_t*)&(((struct sockaddr_in*)addr)->sin_addr);
|
||||
return std::to_string((uint32_t)ip[0]) + "." + std::to_string((uint32_t)ip[1]) + "." + std::to_string((uint32_t)ip[2]) + "." + std::to_string((uint32_t)ip[3]);
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
if(addr->sa_family == AF_INET6)
|
||||
{
|
||||
uint8_t* ip = (uint8_t*)&(((struct sockaddr_in6*)addr)->sin6_addr);
|
||||
|
||||
return std::string({
|
||||
HttpUtils::NibbleToHex((ip[0] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[0] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[1] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[1] & 0x0F),
|
||||
':',
|
||||
HttpUtils::NibbleToHex((ip[2] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[2] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[3] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[3] & 0x0F),
|
||||
':',
|
||||
HttpUtils::NibbleToHex((ip[4] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[4] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[5] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[5] & 0x0F),
|
||||
':',
|
||||
HttpUtils::NibbleToHex((ip[6] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[6] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[7] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[7] & 0x0F),
|
||||
':',
|
||||
HttpUtils::NibbleToHex((ip[8] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[8] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[9] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[9] & 0x0F),
|
||||
':',
|
||||
HttpUtils::NibbleToHex((ip[10] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[10] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[11] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[11] & 0x0F),
|
||||
':',
|
||||
HttpUtils::NibbleToHex((ip[12] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[12] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[13] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[13] & 0x0F),
|
||||
':',
|
||||
HttpUtils::NibbleToHex((ip[14] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[14] & 0x0F),
|
||||
HttpUtils::NibbleToHex((ip[15] >> 4) & 0x0F),
|
||||
HttpUtils::NibbleToHex(ip[15] & 0x0F),
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
TcpServer::TcpServer(uint16_t port, int32_t backlog)
|
||||
{
|
||||
this->owns=true;
|
||||
this->sock = NETWORK_SOCKET(AF_INET, SOCK_STREAM, 0);
|
||||
if(this->sock < 0)
|
||||
{
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
||||
{
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
{
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
this->valid = true;
|
||||
}
|
||||
TcpServer::TcpServer(std::string ip, uint16_t port, int32_t backlog)
|
||||
{
|
||||
this->owns=true;
|
||||
struct sockaddr_storage addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
uint8_t ipBytes[16];
|
||||
bool success = IPParse(ip, &addr);
|
||||
if(!success)
|
||||
{
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
SetPort((struct sockaddr*)&addr, port);
|
||||
|
||||
this->sock = NETWORK_SOCKET((int)addr.ss_family, SOCK_STREAM, 0);
|
||||
if(this->sock < 0)
|
||||
{
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
||||
{
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
{
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
this->valid = true;
|
||||
}
|
||||
TcpServer::TcpServer(int32_t sock, bool owns)
|
||||
{
|
||||
this->valid = sock >= 0;
|
||||
this->sock = sock;
|
||||
this->owns = owns;
|
||||
}
|
||||
TcpServer::~TcpServer()
|
||||
{
|
||||
if(this->valid && this->owns)
|
||||
Close();
|
||||
}
|
||||
void TcpServer::Close()
|
||||
{
|
||||
if(this->valid)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
this->valid=false;
|
||||
}
|
||||
NetworkStream* TcpServer::GetStream(std::string& ip, uint16_t& port)
|
||||
{
|
||||
struct sockaddr_storage storage;
|
||||
memset(&storage,0, sizeof(storage));
|
||||
socklen_t addrlen=(socklen_t)sizeof(storage);
|
||||
|
||||
int s = NETWORK_ACCEPT(this->sock, (struct sockaddr*)&storage, &addrlen);
|
||||
if(s < 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ip = StringifyIP((struct sockaddr*)&storage);
|
||||
port = GetPort((struct sockaddr*)&storage);
|
||||
|
||||
return new NetworkStream(s,true);
|
||||
}
|
||||
bool NetworkStream::CanRead()
|
||||
{
|
||||
return this->success;
|
||||
}
|
||||
bool NetworkStream::CanWrite()
|
||||
{
|
||||
return this->success;
|
||||
}
|
||||
NetworkStream::NetworkStream(bool ipV6,bool datagram)
|
||||
{
|
||||
this->endOfStream=false;
|
||||
this->owns = true;
|
||||
this->success=false;
|
||||
if(ipV6)
|
||||
{
|
||||
#if defined(AF_INET6)
|
||||
this->sock = socket(AF_INET6, datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
if(this->sock >= 0) this->success=true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
this->sock = socket(AF_INET, datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
if(this->sock >= 0) this->success=true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
NetworkStream::NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram, bool broadcast, bool supportIPv6)
|
||||
{
|
||||
this->endOfStream = false;
|
||||
this->owns=true;
|
||||
this->success=false;
|
||||
std::string portStr = std::to_string((uint32_t)port);
|
||||
struct addrinfo hint;
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
#if defined(AF_INET6)
|
||||
hint.ai_family = supportIPv6 ? AF_UNSPEC : AF_INET;
|
||||
#else
|
||||
hint.ai_family = AF_INET;
|
||||
#endif
|
||||
hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM;
|
||||
|
||||
struct addrinfo* result;
|
||||
|
||||
|
||||
int status = NETWORK_GETADDRINFO(ipOrFqdn.c_str(),portStr.c_str(), &hint, &result);
|
||||
if(status != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct addrinfo* tmp=result;
|
||||
|
||||
|
||||
while(tmp != nullptr)
|
||||
{
|
||||
sock = NETWORK_SOCKET(tmp->ai_family,tmp->ai_socktype,tmp->ai_protocol);
|
||||
if(broadcast)
|
||||
{
|
||||
int broadcast = 1;
|
||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) != 0) {
|
||||
this->success=false;
|
||||
NETWORK_CLOSE(this->sock);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(sock != -1)
|
||||
{
|
||||
this->success=true;
|
||||
if(NETWORK_CONNECT(this->sock,(const sockaddr*)tmp->ai_addr,tmp->ai_addrlen) == 0) break;
|
||||
this->success=false;
|
||||
NETWORK_CLOSE(this->sock);
|
||||
}
|
||||
tmp = tmp->ai_next;
|
||||
}
|
||||
NETWORK_FREEADDRINFO(result);
|
||||
|
||||
}
|
||||
NetworkStream::NetworkStream(int32_t sock, bool owns)
|
||||
{
|
||||
this->endOfStream = false;
|
||||
this->success = sock >= 0;
|
||||
this->sock = sock;
|
||||
this->owns = owns;
|
||||
}
|
||||
bool NetworkStream::EndOfStream()
|
||||
{
|
||||
return this->endOfStream;
|
||||
}
|
||||
void NetworkStream::Listen(int32_t backlog)
|
||||
{
|
||||
if(this->success)
|
||||
NETWORK_LISTEN(this->sock, backlog);
|
||||
}
|
||||
|
||||
void NetworkStream::Bind(std::string ip, uint16_t port)
|
||||
{
|
||||
if(!this->success) return;
|
||||
struct sockaddr_storage addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
uint8_t ipBytes[16];
|
||||
bool success = IPParse(ip, &addr);
|
||||
if(!success)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
return;
|
||||
}
|
||||
|
||||
SetPort((struct sockaddr*)&addr, port);
|
||||
|
||||
int r = NETWORK_BIND(this->sock, (struct sockaddr*)&addr, sizeof(addr));
|
||||
if(r != 0)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
void NetworkStream::SetBroadcast(bool bC)
|
||||
{
|
||||
if(!this->success) return;
|
||||
int broadcast = 1;
|
||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) != 0)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
|
||||
}
|
||||
}
|
||||
NetworkStream* NetworkStream::Accept(std::string& ip, uint16_t& port)
|
||||
{
|
||||
if(!this->success) return nullptr;
|
||||
struct sockaddr_storage storage;
|
||||
socklen_t addrlen=(socklen_t)sizeof(storage);
|
||||
int s = NETWORK_ACCEPT(this->sock, (struct sockaddr*)&storage, (socklen_t*)&addrlen);
|
||||
if(s < 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ip = StringifyIP((struct sockaddr*)&storage);
|
||||
port = GetPort((struct sockaddr*)&storage);
|
||||
|
||||
return new NetworkStream(s,true);
|
||||
}
|
||||
size_t NetworkStream::Read(uint8_t* buff, size_t sz)
|
||||
{
|
||||
|
||||
if(!this->success) return 0;
|
||||
ssize_t r = NETWORK_RECV(this->sock,buff,sz,0);
|
||||
|
||||
if(r <= 0)
|
||||
{
|
||||
this->endOfStream=true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (size_t)r;
|
||||
}
|
||||
size_t NetworkStream::Write(const uint8_t* buff, size_t sz)
|
||||
{
|
||||
|
||||
if(!this->success) return 0;
|
||||
|
||||
ssize_t sz2 = NETWORK_SEND(this->sock,buff,sz, 0);
|
||||
if(sz2 < 0) return 0;
|
||||
|
||||
return (size_t)sz;
|
||||
}
|
||||
size_t NetworkStream::ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port)
|
||||
{
|
||||
if(!this->success) return 0;
|
||||
struct sockaddr_storage storage;
|
||||
socklen_t addrlen=(socklen_t)sizeof(storage);
|
||||
ssize_t r = NETWORK_RECVFROM(this->sock,buff,sz,0, (struct sockaddr*)&storage, (socklen_t*)&addrlen);
|
||||
ip = StringifyIP((struct sockaddr*)&storage);
|
||||
port = GetPort((struct sockaddr*)&storage);
|
||||
if(r < 0) return 0;
|
||||
return (size_t)r;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
size_t NetworkStream::WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port)
|
||||
{
|
||||
|
||||
if(!this->success) return 0;
|
||||
struct sockaddr_storage addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
uint8_t ipBytes[16];
|
||||
bool success = IPParse(ip, &addr);
|
||||
if(!success)
|
||||
{
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetPort((struct sockaddr*)&addr, port);
|
||||
ssize_t sz2 = NETWORK_SENDTO(this->sock,buff,sz, 0, (const sockaddr*)&addr, (socklen_t)sizeof(addr));
|
||||
if(sz2 < 0) return 0;
|
||||
return (size_t)sz2;
|
||||
}
|
||||
NetworkStream::~NetworkStream()
|
||||
{
|
||||
if(this->owns && this->success)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
}
|
||||
}
|
||||
115
src/Streams/Stream.cpp
Normal file
115
src/Streams/Stream.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include "TessesFramework/Streams/Stream.hpp"
|
||||
|
||||
namespace Tesses::Framework::Streams {
|
||||
int32_t Stream::ReadByte()
|
||||
{
|
||||
uint8_t b;
|
||||
if(Read(&b, 1) == 0) return -1;
|
||||
return b;
|
||||
}
|
||||
void Stream::WriteByte(uint8_t b)
|
||||
{
|
||||
Write(&b, 1);
|
||||
}
|
||||
size_t Stream::Read(uint8_t* buffer, size_t count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
size_t Stream::Write(const uint8_t* buffer, size_t count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
size_t Stream::ReadBlock(uint8_t* buffer,size_t len)
|
||||
{
|
||||
size_t read;
|
||||
size_t readTotal = 0;
|
||||
do{
|
||||
read = 1024;
|
||||
if(len < 1024)
|
||||
read = len;
|
||||
if(read > 0)
|
||||
read=this->Read(buffer,read);
|
||||
|
||||
|
||||
|
||||
buffer += read;
|
||||
len -= read;
|
||||
readTotal += read;
|
||||
} while(read > 0);
|
||||
return readTotal;
|
||||
}
|
||||
|
||||
void Stream::WriteBlock(const uint8_t* buffer,size_t len)
|
||||
{
|
||||
size_t read;
|
||||
do{
|
||||
read = 1024;
|
||||
if(len < 1024)
|
||||
read = len;
|
||||
if(read > 0)
|
||||
read=this->Write(buffer,read);
|
||||
|
||||
|
||||
|
||||
buffer += read;
|
||||
len -= read;
|
||||
} while(read > 0);
|
||||
}
|
||||
bool Stream::CanRead()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool Stream::CanWrite()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool Stream::CanSeek()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool Stream::EndOfStream()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int64_t Stream::GetPosition()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int64_t Stream::GetLength()
|
||||
{
|
||||
if(!CanSeek()) return 0;
|
||||
int64_t curPos = GetPosition();
|
||||
Seek(0, SeekOrigin::End);
|
||||
int64_t len = GetPosition();
|
||||
Seek(curPos, SeekOrigin::Begin);
|
||||
return len;
|
||||
}
|
||||
void Stream::Flush()
|
||||
{
|
||||
|
||||
}
|
||||
void Stream::Seek(int64_t pos, SeekOrigin whence)
|
||||
{
|
||||
|
||||
}
|
||||
void Stream::CopyTo(Stream* strm, size_t buffSize)
|
||||
{
|
||||
if(strm == nullptr)
|
||||
strm->CopyTo(strm, buffSize);
|
||||
}
|
||||
void Stream::CopyTo(Stream& strm, size_t buffSize)
|
||||
{
|
||||
size_t read;
|
||||
uint8_t buffer[buffSize];
|
||||
do {
|
||||
read = this->Read(buffer,buffSize);
|
||||
strm.WriteBlock(buffer, read);
|
||||
|
||||
} while(read > 0);
|
||||
strm.Flush();
|
||||
}
|
||||
Stream::~Stream()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user