mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 02:03:27 -08:00
127 lines
3.8 KiB
C
127 lines
3.8 KiB
C
// Copyright (c) Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Helpers
|
|
|
|
internal SOCK_Endpoint
|
|
sock_endpoint_from_string_port(String8 address, U16 port)
|
|
{
|
|
//- rjf: detect kind
|
|
SOCK_EndpointKind kind = SOCK_EndpointKind_IPv4;
|
|
{
|
|
if(str8_find_needle(address, 0, s(":"), 0) < address.size)
|
|
{
|
|
kind = SOCK_EndpointKind_IPv6;
|
|
}
|
|
}
|
|
|
|
//- rjf: fill based on format
|
|
SOCK_Endpoint ep = {0};
|
|
ep.port = port;
|
|
ep.kind = kind;
|
|
switch(kind)
|
|
{
|
|
default:
|
|
case SOCK_EndpointKind_IPv4:
|
|
{
|
|
U64 off = 0;
|
|
U64 part_start_off = 0;
|
|
for(;off < 4;)
|
|
{
|
|
U64 part_end_off = str8_find_needle(address, part_start_off+1, s("."), 0);
|
|
String8 part = str8_substr(address, r1u64(part_start_off, part_end_off));
|
|
U64 part_val = u64_from_str8(part, 10);
|
|
ep.address_u8[off] = (U8)part_val;
|
|
part_start_off = part_end_off+1;
|
|
off += 1;
|
|
if(part_end_off >= address.size)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}break;
|
|
case SOCK_EndpointKind_IPv6:
|
|
{
|
|
U64 off = 0;
|
|
U64 part_start_off = 0;
|
|
U64 double_colon_off = 0;
|
|
for(;off < 8;)
|
|
{
|
|
U64 part_end_off = str8_find_needle(address, part_start_off+1, s(":"), 0);
|
|
String8 part = str8_substr(address, r1u64(part_start_off, part_end_off));
|
|
U64 part_val = u64_from_str8(part, 16);
|
|
ep.address_u16[off] = (U16)part_val;
|
|
part_start_off = part_end_off+1;
|
|
if(part_end_off+1 < address.size && address.str[part_end_off+1] == ':')
|
|
{
|
|
double_colon_off = off;
|
|
}
|
|
off += 1;
|
|
if(part_end_off >= address.size)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if(off < 8 && double_colon_off < 8)
|
|
{
|
|
U64 shift_amt = 8 - off;
|
|
MemoryCopy(&ep.address_u16[0] + double_colon_off + shift_amt, &ep.address_u16[0] + double_colon_off, sizeof(U16) * (off - double_colon_off));
|
|
}
|
|
}break;
|
|
}
|
|
|
|
return ep;
|
|
}
|
|
|
|
internal SOCK_Endpoint
|
|
sock_endpoint_from_string(String8 address_and_port)
|
|
{
|
|
String8 addr = {0};
|
|
U64 port_off = 0;
|
|
if(address_and_port.size > 0 && address_and_port.str[0] == '[')
|
|
{
|
|
U64 addr_end_off = str8_find_needle(address_and_port, 1, s("]"), 0);
|
|
addr = str8_substr(address_and_port, r1u64(1, addr_end_off));
|
|
port_off = str8_find_needle(address_and_port, addr_end_off+1, s(":"), 0)+1;
|
|
}
|
|
else
|
|
{
|
|
U64 colon_off = str8_find_needle(address_and_port, 0, s(":"), 0);
|
|
port_off = colon_off + 1;
|
|
addr = str8_prefix(address_and_port, colon_off);
|
|
}
|
|
String8 port_string = str8_skip(address_and_port, port_off);
|
|
U16 port = u64_from_str8(port_string, 10);
|
|
SOCK_Endpoint ep = sock_endpoint_from_string_port(addr, port);
|
|
return ep;
|
|
}
|
|
|
|
internal String8
|
|
sock_string_from_endpoint(Arena *arena, SOCK_Endpoint endpoint)
|
|
{
|
|
String8 result = {0};
|
|
switch(endpoint.kind)
|
|
{
|
|
default:{}break;
|
|
case SOCK_EndpointKind_IPv4:
|
|
{
|
|
result = str8f(arena, "%i.%i.%i.%i:%i", (int)endpoint.address_u8[0], (int)endpoint.address_u8[1], (int)endpoint.address_u8[2], (int)endpoint.address_u8[3], (int)endpoint.port);
|
|
}break;
|
|
case SOCK_EndpointKind_IPv6:
|
|
{
|
|
result = str8f(arena, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%i",
|
|
(int)endpoint.address_u16[0],
|
|
(int)endpoint.address_u16[1],
|
|
(int)endpoint.address_u16[2],
|
|
(int)endpoint.address_u16[3],
|
|
(int)endpoint.address_u16[4],
|
|
(int)endpoint.address_u16[5],
|
|
(int)endpoint.address_u16[6],
|
|
(int)endpoint.address_u16[7],
|
|
(int)endpoint.port);
|
|
}break;
|
|
}
|
|
return result;
|
|
}
|