Crossfire Server, Trunk
bufferreader.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2021 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include "global.h"
18 #include "compat.h"
19 #include "bufferreader.h"
20 
21 struct BufferReader {
22  char *buf;
24  size_t allocated_size;
25  size_t buffer_length;
27  char *current_line;
28  size_t line_index;
29 };
30 
32  BufferReader *buffer = static_cast<BufferReader *>(calloc(1, sizeof(*buffer)));
33  if (!buffer) {
35  }
36 
37  return buffer;
38 }
39 
41  free(br->buf);
42  free(br);
43 }
44 
50 static void bufferreader_init_for_length(BufferReader *br, size_t length) {
51  size_t needed = length + 1;
52  if (needed > br->allocated_size) {
53  br->buf = static_cast<char *>(realloc(br->buf, needed));
54  if (!br->buf) {
56  }
57  br->allocated_size = needed;
58  }
59  br->buffer_length = length;
60  br->buf[br->buffer_length] = '\0';
61  br->current_line = br->buffer_length > 0 ? br->buf : NULL;
62  br->line_index = 0;
63 }
64 
65 BufferReader *bufferreader_init_from_file(BufferReader *br, const char *filepath, const char *failureMessage, LogLevel failureLevel) {
66  FILE *file = fopen(filepath, "rb");
67  if (!file) {
68  LOG(failureLevel, failureMessage, filepath, strerror(errno));
69  return NULL;
70  }
71  if (!br) {
72  br = bufferreader_create();
73  }
74 
75  fseek(file, 0L, SEEK_END);
77  fseek(file, 0, SEEK_SET);
78 
79  size_t actual = fread(br->buf, 1, br->buffer_length, file);
80  if (actual != br->buffer_length) {
81  LOG(llevError, "Expected to read %zu bytes, only read %zu!\n", br->buffer_length, actual);
82  br->buffer_length = actual;
83  }
84  fclose(file);
85  return br;
86 }
87 
90  mtar_read_data(tar, br->buf, h->size);
91 }
92 
93 BufferReader *bufferreader_init_from_memory(BufferReader *br, const char *data, size_t length) {
94  if (!br) {
95  br = bufferreader_create();
96  }
97  bufferreader_init_for_length(br, length);
98  memcpy(br->buf, data, length);
99  return br;
100 }
101 
103  if (!br->current_line) {
104  return NULL;
105  }
106 
107  br->line_index++;
108  char *newline = strchr(br->current_line, '\n');
109  char *curr = br->current_line;
110  if (newline) {
111  br->current_line = newline + 1;
112  (*newline) = '\0';
113  } else {
114  br->current_line = NULL;
115  }
116  return curr;
117 }
118 
119 char *bufferreader_get_line(BufferReader *br, char *buffer, size_t length) {
120  if (!br->current_line) {
121  return NULL;
122  }
123 
124  br->line_index++;
125  char *newline = strchr(br->current_line, '\n');
126  char *curr = br->current_line;
127  if (newline) {
128  size_t cp = MIN(length, (size_t)(newline - curr + 1));
129  br->current_line = newline + 1;
130  strncpy(buffer, curr, cp);
131  buffer[cp] = '\0';
132  } else {
133  strncpy(buffer, curr, length);
134  br->current_line = NULL;
135  }
136 
137  return buffer;
138 }
139 
141  return br->line_index;
142 }
143 
145  return br->buffer_length;
146 }
147 
149  return br->buf;
150 }
global.h
BufferReader::current_line
char * current_line
Definition: bufferreader.cpp:27
bufferreader_data
char * bufferreader_data(BufferReader *br)
Definition: bufferreader.cpp:148
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Definition: bufferreader.cpp:140
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
mtar_t
Definition: microtar.h:51
mtar_header_t::size
unsigned size
Definition: microtar.h:41
mad_mage_user.file
file
Definition: mad_mage_user.py:15
MIN
#define MIN(x, y)
Definition: compat.h:21
bufferreader_destroy
void bufferreader_destroy(BufferReader *br)
Definition: bufferreader.cpp:40
bufferreader_data_length
size_t bufferreader_data_length(BufferReader *br)
Definition: bufferreader.cpp:144
bufferreader_get_line
char * bufferreader_get_line(BufferReader *br, char *buffer, size_t length)
Definition: bufferreader.cpp:119
bufferreader_init_for_length
static void bufferreader_init_for_length(BufferReader *br, size_t length)
Definition: bufferreader.cpp:50
bufferreader_init_from_file
BufferReader * bufferreader_init_from_file(BufferReader *br, const char *filepath, const char *failureMessage, LogLevel failureLevel)
Definition: bufferreader.cpp:65
compat.h
navar-midane_time.data
data
Definition: navar-midane_time.py:11
BufferReader::line_index
size_t line_index
Definition: bufferreader.cpp:28
BufferReader::allocated_size
size_t allocated_size
Definition: bufferreader.cpp:24
bufferreader.h
mtar_header_t
Definition: microtar.h:38
fatal
void fatal(enum fatal_error err)
Definition: utils.cpp:590
bufferreader_init_from_memory
BufferReader * bufferreader_init_from_memory(BufferReader *br, const char *data, size_t length)
Definition: bufferreader.cpp:93
bufferreader_init_from_tar_file
void bufferreader_init_from_tar_file(BufferReader *br, mtar_t *tar, mtar_header_t *h)
Definition: bufferreader.cpp:88
bufferreader_create
BufferReader * bufferreader_create()
Definition: bufferreader.cpp:31
LogLevel
LogLevel
Definition: logger.h:10
BufferReader::buffer_length
size_t buffer_length
Definition: bufferreader.cpp:25
BufferReader::buf
char * buf
Definition: bufferreader.cpp:22
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
BufferReader
Definition: bufferreader.cpp:21
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.cpp:102
mtar_read_data
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size)
Definition: microtar.cpp:290