Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions code/logic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(TEST_CODE
soap.c
stream.c
keyboard.c
network.c
)

# Create the library target
Expand All @@ -23,6 +24,11 @@ add_library(fossil-io STATIC ${TEST_CODE} ${HEADER_FILES})
# Link the math library
target_link_libraries(fossil-io PUBLIC m)

# Link to Winsock library only on Windows
if(WIN32)
target_link_libraries(fossil-io PUBLIC ws2_32)
endif()

# Set the library to be installed
install(TARGETS fossil-io
ARCHIVE DESTINATION lib
Expand Down
1 change: 1 addition & 0 deletions code/logic/fossil/io/framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

// Include the necessary headers
#include "keyboard.h"
#include "network.h"
#include "output.h"
#include "input.h"
#include "error.h"
Expand Down
196 changes: 196 additions & 0 deletions code/logic/fossil/io/network.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* -----------------------------------------------------------------------------
* Project: Fossil Logic
*
* This file is part of the Fossil Logic project, which aims to develop high-
* performance, cross-platform applications and libraries. The code contained
* herein is subject to the terms and conditions defined in the project license.
*
* Author: Michael Gene Brockus (Dreamer)
*
* Copyright (C) 2024 Fossil Logic. All rights reserved.
* -----------------------------------------------------------------------------
*/
#ifndef FOSSIL_IO_NETWORK_H
#define FOSSIL_IO_NETWORK_H

#include <stdint.h>

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
typedef SOCKET fossil_io_socket_t;
#define FOSSIL_IO_INVALID_SOCKET INVALID_SOCKET
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define closesocket close
typedef int fossil_io_socket_t;
#define FOSSIL_IO_INVALID_SOCKET (-1)
#endif

#ifdef __cplusplus
extern "C" {
#endif

/**
* Initialize the network stack (needed for Windows).
* Returns 0 on success, non-zero on failure.
*/
int fossil_io_network_create(void);

/**
* Clean up network stack (needed for Windows).
*/
void fossil_io_network_destroy(void);

/**
* Create a new TCP socket.
* Returns a valid socket on success or FOSSIL_IO_INVALID_SOCKET on failure.
*/
fossil_io_socket_t fossil_io_network_create_socket(void);

/**
* Bind a socket to a specific port (IPv4/IPv6).
* Returns 0 on success, -1 on failure.
*/
int fossil_io_network_bind(fossil_io_socket_t sock, const char *ip, uint16_t port);

/**
* Listen for incoming connections.
* Returns 0 on success, -1 on failure.
*/
int fossil_io_network_listen(fossil_io_socket_t sock, int backlog);

/**
* Accept a new connection.
* Returns a valid socket on success, or FOSSIL_IO_INVALID_SOCKET on failure.
*/
fossil_io_socket_t fossil_io_network_accept(fossil_io_socket_t sock, char *client_ip, uint16_t *client_port);

/**
* Connect to a remote server.
* Returns 0 on success, -1 on failure.
*/
int fossil_io_network_connect(fossil_io_socket_t sock, const char *ip, uint16_t port);

/**
* Send data over a socket.
* Returns the number of bytes sent, or -1 on failure.
*/
int fossil_io_network_send(fossil_io_socket_t sock, const void *data, size_t len);

/**
* Receive data from a socket.
* Returns the number of bytes received, or -1 on failure.
*/
int fossil_io_network_receive(fossil_io_socket_t sock, void *buffer, size_t len);

/**
* Close a socket.
*/
void fossil_io_network_close(fossil_io_socket_t sock);

#ifdef __cplusplus
}
/**
* C++ wrapper for the output functions.
*/
namespace fossil {
/**
* Namespace for input/output operations.
*/
namespace io {
/**
* Class for network operations.
*/
class Network {
public:
/**
* Initialize the network stack (needed for Windows).
* Returns 0 on success, non-zero on failure.
*/
static int init(void) {
return fossil_io_network_create();
}

/**
* Clean up network stack (needed for Windows).
*/
static void cleanup(void) {
fossil_io_network_destroy();
}

/**
* Create a new TCP socket.
* Returns a valid socket on success or FOSSIL_IO_INVALID_SOCKET on failure.
*/
static fossil_io_socket_t create_socket(void) {
return fossil_io_network_create_socket();
}

/**
* Bind a socket to a specific port (IPv4/IPv6).
* Returns 0 on success, -1 on failure.
*/
static int bind(fossil_io_socket_t sock, const char *ip, uint16_t port) {
return fossil_io_network_bind(sock, ip, port);
}

/**
* Listen for incoming connections.
* Returns 0 on success, -1 on failure.
*/
static int listen(fossil_io_socket_t sock, int backlog) {
return fossil_io_network_listen(sock, backlog);
}

/**
* Accept a new connection.
* Returns a valid socket on success, or FOSSIL_IO_INVALID_SOCKET on failure.
*/
static fossil_io_socket_t accept(fossil_io_socket_t sock, char *client_ip, uint16_t *client_port) {
return fossil_io_network_accept(sock, client_ip, client_port);
}

/**
* Connect to a remote server.
* Returns 0 on success, -1 on failure.
*/
static int connect(fossil_io_socket_t sock, const char *ip, uint16_t port) {
return fossil_io_network_connect(sock, ip, port);
}

/**
* Send data over a socket.
* Returns the number of bytes sent, or -1 on failure.
*/
static int send(fossil_io_socket_t sock, const void *data, size_t len) {
return fossil_io_network_send(sock, data, len);
}

/**
* Receive data from a socket.
* Returns the number of bytes received, or -1 on failure.
*/
static int receive(fossil_io_socket_t sock, void *buffer, size_t len) {
return fossil_io_network_receive(sock, buffer, len);
}

/**
* Close a socket.
*/
static void close(fossil_io_socket_t sock) {
fossil_io_network_close(sock);
}

};
}
}

#endif

#endif /* FOSSIL_IO_FRAMEWORK_H */
11 changes: 9 additions & 2 deletions code/logic/meson.build
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
dir = include_directories('.')
cc = meson.get_compiler('c')

# Check if the host system is Windows
if host_machine.system() == 'windows'
winsock_dep = cc.find_library('ws2_32', required: true)
else
winsock_dep = []
endif

fossil_io_lib = library('fossil-io',
files('parser.c', 'input.c', 'output.c', 'error.c', 'soap.c', 'stream.c', 'keyboard.c'),
files('parser.c', 'input.c', 'output.c', 'error.c', 'soap.c', 'stream.c', 'keyboard.c', 'network.c'),
install: true,
dependencies: cc.find_library('m', required : false),
dependencies: [cc.find_library('m', required: false), winsock_dep],
include_directories: dir)

fossil_io_dep = declare_dependency(
Expand Down
151 changes: 151 additions & 0 deletions code/logic/network.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* -----------------------------------------------------------------------------
* Project: Fossil Logic
*
* This file is part of the Fossil Logic project, which aims to develop high-
* performance, cross-platform applications and libraries. The code contained
* herein is subject to the terms and conditions defined in the project license.
*
* Author: Michael Gene Brockus (Dreamer)
*
* Copyright (C) 2024 Fossil Logic. All rights reserved.
* -----------------------------------------------------------------------------
*/
#include "fossil/io/network.h"
#include <stdio.h>
#include <string.h>
#include <errno.h> // For POSIX error handling
#include <stdlib.h> // For exit()

#ifdef _WIN32
static WSADATA wsa;
#endif

int fossil_io_network_create(void) {
#ifdef _WIN32
return WSAStartup(MAKEWORD(2, 2), &wsa);
#else
return 0; // No initialization needed on Unix-like systems
#endif
}

void fossil_io_network_destroy(void) {
#ifdef _WIN32
WSACleanup();
#endif
}

fossil_io_socket_t fossil_io_network_create_socket(void) {
fossil_io_socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == FOSSIL_IO_INVALID_SOCKET) {
#ifdef _WIN32
fprintf(stderr, "Socket creation failed with error: %d\n", WSAGetLastError());
#else
perror("Socket creation failed");
#endif
}
return sock;
}

int fossil_io_network_bind(fossil_io_socket_t sock, const char *ip, uint16_t port) {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip ? inet_addr(ip) : INADDR_ANY;

if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
#ifdef _WIN32
fprintf(stderr, "Bind failed with error: %d\n", WSAGetLastError());
#else
perror("Bind failed");
#endif
return -1;
}
return 0;
}

int fossil_io_network_listen(fossil_io_socket_t sock, int backlog) {
if (listen(sock, backlog) == -1) {
#ifdef _WIN32
fprintf(stderr, "Listen failed with error: %d\n", WSAGetLastError());
#else
perror("Listen failed");
#endif
return -1;
}
return 0;
}

fossil_io_socket_t fossil_io_network_accept(fossil_io_socket_t sock, char *client_ip, uint16_t *client_port) {
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
fossil_io_socket_t client_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);

if (client_sock == FOSSIL_IO_INVALID_SOCKET) {
#ifdef _WIN32
fprintf(stderr, "Accept failed with error: %d\n", WSAGetLastError());
#else
perror("Accept failed");
#endif
} else if (client_ip) {
strcpy(client_ip, inet_ntoa(client_addr.sin_addr));
if (client_port) {
*client_port = ntohs(client_addr.sin_port);
}
}

return client_sock;
}

int fossil_io_network_connect(fossil_io_socket_t sock, const char *ip, uint16_t port) {
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(ip);

if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
#ifdef _WIN32
fprintf(stderr, "Connect failed with error: %d\n", WSAGetLastError());
#else
perror("Connect failed");
#endif
return -1;
}
return 0;
}

int fossil_io_network_send(fossil_io_socket_t sock, const void *data, size_t len) {
int bytes_sent = send(sock, data, (int)len, 0);
if (bytes_sent == -1) {
#ifdef _WIN32
fprintf(stderr, "Send failed with error: %d\n", WSAGetLastError());
#else
perror("Send failed");
#endif
}
return bytes_sent;
}

int fossil_io_network_receive(fossil_io_socket_t sock, void *buffer, size_t len) {
int bytes_received = recv(sock, buffer, (int)len, 0);
if (bytes_received == -1) {
#ifdef _WIN32
fprintf(stderr, "Receive failed with error: %d\n", WSAGetLastError());
#else
perror("Receive failed");
#endif
}
return bytes_received;
}

void fossil_io_network_close(fossil_io_socket_t sock) {
#ifdef _WIN32
if (closesocket(sock) == SOCKET_ERROR) {
fprintf(stderr, "Close socket failed with error: %d\n", WSAGetLastError());
}
#else
if (close(sock) == -1) {
perror("Close socket failed");
}
#endif
}
Loading