Skip to content

Instantly share code, notes, and snippets.

@cho0h5
Created April 13, 2025 06:08
Show Gist options
  • Save cho0h5/2aec8fd3f90976349f9c71c0a5da90f5 to your computer and use it in GitHub Desktop.
Save cho0h5/2aec8fd3f90976349f9c71c0a5da90f5 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
typedef struct
{
int fd;
char *buffer;
ssize_t len;
} BufReader;
static void bufreader_init(BufReader *bufreader, int fd)
{
bufreader->fd = fd;
bufreader->buffer = NULL;
bufreader->len = 0;
}
static void bufreader_destroy(BufReader *bufreader)
{
free(bufreader->buffer);
bufreader->fd = -1;
bufreader->buffer = NULL;
bufreader->len = 0;
}
static int bufreader_read(BufReader *bufreader)
{
// Read
char buffer[BUFFER_SIZE];
ssize_t bytes_read = read(bufreader->fd, buffer, BUFFER_SIZE);
if (bytes_read <= 0 && bufreader->len == 0)
{
return -1;
}
// Resize bufreader according to bytes_read
bufreader->buffer = realloc(bufreader->buffer, bufreader->len + bytes_read);
if (bufreader->buffer == NULL)
{
perror("Failed to realloc");
exit(EXIT_FAILURE);
}
// Concat read buffer to bufreader
memcpy(bufreader->buffer + bufreader->len, buffer, bytes_read);
bufreader->len += bytes_read;
return 0;
}
static char *bufreader_readline(BufReader *bufreader)
{
// Find newline character
ssize_t newline = 0;
while (newline < bufreader->len && bufreader->buffer[newline] != '\n')
{
newline += 1;
}
// If newline character not found
if (newline == bufreader->len)
{
return NULL;
}
// Duplicate a line
bufreader->buffer[newline] = '\0';
char *line = strdup(bufreader->buffer);
// Shift remain data to the front
ssize_t dst = 0;
ssize_t src = newline + 1;
while (src < bufreader->len)
{
bufreader->buffer[dst++] = bufreader->buffer[src++];
}
bufreader->len = dst;
return line;
}
int main()
{
BufReader bufreader;
bufreader_init(&bufreader, 0);
while (1)
{
if (bufreader_read(&bufreader) < 0)
{
printf("End\n");
break;
}
char *line = bufreader_readline(&bufreader);
if (line == NULL)
{
continue;
}
printf("read: \"%s\"\n", line);
free(line);
}
bufreader_destroy(&bufreader);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment