handmade/include/SafeUDPpacket.h

100 lines
2.3 KiB
C
Raw Normal View History

#pragma once
#include <memory>
#include <string>
#include <vector>
#include <SDL_assert.h>
#include <SDL_net.h>
class SafeUDPpacket
{
struct SDLNet_PacketDeleter
{
void operator () (UDPpacket* p)
{
SDLNet_FreePacket (p);
p = NULL;
}
};
std::unique_ptr<UDPpacket, SDLNet_PacketDeleter> m_packet;
void Reset (UDPpacket* p)
{
m_packet.reset (p);
}
public:
SafeUDPpacket (int size)
{
UDPpacket* p;
if (NULL == (p = SDLNet_AllocPacket (size)))
{
throw "SDLNet_AllocPacket: " + std::string (SDLNet_GetError ());
}
Reset (p);
}
SafeUDPpacket (UDPpacket* p)
{
Reset (p);
}
UDPpacket* get (void) const
{
return m_packet.get ();
}
int channel (int channel) const { return get()->channel = channel; }
int channel (void) const { return get()->channel; }
int len (int len) const { return get()->len = len; }
int len (void) const { return get()->len; }
int maxlen (int maxlen) const { return get()->maxlen = maxlen; }
int maxlen (void) const { return get()->maxlen; }
int status (int status) const { return get()->status = status; }
int status (void) const { return get()->status; }
IPaddress address (IPaddress address) const { return get()->address = address; }
IPaddress address (void) const { return get()->address; }
Uint8 *data (Uint8* data) const { return get()->data = data; }
Uint8 *data (void) const { return get()->data; }
};
class SafeUDPpacketV
{
std::vector<SafeUDPpacket> m_packetV;
public:
SafeUDPpacketV (const void*, const int, const int mtu = 1450);
SafeUDPpacketV (int howmany, int size)
{
UDPpacket** p;
m_packetV.reserve (howmany);
if (NULL == (p = SDLNet_AllocPacketV (howmany, size)))
{
throw "SDLNet_AllocPacketV: " + std::string (SDLNet_GetError ());
}
else
{
for (; (p != NULL) && (*p != NULL); p++)
{
m_packetV.push_back (SafeUDPpacket (*p));
}
SDL_assert ((m_packetV.size () > 0) && (howmany == (int)m_packetV.size ()));
/*
* SDLNet_FreePacketV just calls SDLNet_FreePacket on each packet.
* The "packetV" itself is just something allocated on the heap.
* We don't need this any longer.
*/
SDL_free (p);
}
}
const SafeUDPpacket& get (size_t idx)
{
return m_packetV.at (idx);
}
size_t size (void) const
{
return m_packetV.size ();
}
std::string toString (void);
};