-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmessages.c
163 lines (135 loc) · 4.25 KB
/
messages.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* Author: Nicu Pavel <[email protected]>
* Copyright (c) 2021 Green Electronics LLC
* The MIT License (MIT)
*
*/
#include "messages.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "config.h"
#include "debug.h"
#include "dlist.h"
static DList messages;
static char *message = NULL;
static unsigned int message_size = 0, message_alloc_size = 0;
struct timespec ts_last;
struct timespec ts_now;
static int message_new(void) {
if (!(message = (char *)malloc(READ_BUF_LEN))) {
fprintf(stderr, "Cannot allocate buffer\n");
return -1;
}
message_size = 0;
message_alloc_size = READ_BUF_LEN;
return 0;
}
void message_free(void) {
free(message);
}
int messages_init(unsigned int lines) {
dlist_init(&messages, free, lines);
return message_new();
}
void messages_clear(void) { return dlist_clear(&messages); }
void messages_resize(unsigned int new_size) { return dlist_resize(&messages, new_size); }
int message_add_chunk(char *buffer, int len) {
char *tmp = NULL;
if ((message_size + len + 1) > message_alloc_size) {
fprintf(stderr, "Alloc: %d bytes\n", message_alloc_size + READ_BUF_LEN);
tmp = realloc(message, message_alloc_size + READ_BUF_LEN);
if (!tmp) {
fprintf(stderr, "Cannot realloc message !\n");
return -1;
}
message = tmp;
message_alloc_size += READ_BUF_LEN;
}
memcpy(message + message_size, buffer, len);
message_size += len;
return 0;
}
int message_check_save(unsigned int rate, unsigned int output) {
if (message_size > 0 && message[message_size - 1] == '\n') {
message[message_size] = '\0';
// Check if rate limiting is respected
clock_gettime(CLOCK_MONOTONIC, &ts_now);
if (ts_last.tv_sec > 0 && ts_now.tv_sec - ts_last.tv_sec < rate) {
free(message);
debug_print("%s", "Skip save\n");
} else {
clock_gettime(CLOCK_MONOTONIC, &ts_last);
dlist_insert(&messages, NULL, message);
if (output) {
fprintf(stdout, "%s", message);
fflush(stdout);
}
}
return message_new();
}
return 0;
}
char *message_get_current() { return message; }
char *messages_get_formated(const unsigned int lines, const char *prefix,
const char *suffix, const char *line_delimiter) {
unsigned long int total_messages_size = 0;
unsigned int prefix_len = 0;
unsigned int suffix_len = 0;
unsigned int line_delimiter_len = 0;
DListElmt *e;
debug_print("Requested lines: %u\n", lines);
if (prefix) {
prefix_len = strlen(prefix);
}
if (suffix) {
suffix_len = strlen(suffix);
}
if (line_delimiter) {
line_delimiter_len = strlen(line_delimiter);
}
unsigned int l;
for (l = 0, e = dlist_head(&messages); e != NULL && l < lines;
e = e->next, l++) {
if (e->data) {
total_messages_size += strlen((char *)e->data);
if (line_delimiter && l < lines - 1 && e->next != NULL) {
total_messages_size += line_delimiter_len;
}
}
}
if (prefix) {
total_messages_size += prefix_len;
}
if (suffix) {
total_messages_size += suffix_len;
}
debug_print("Total messages size: %ld\n", total_messages_size);
char *body = (char *)malloc(total_messages_size + 1);
if (!body) {
fprintf(stderr, "Cannot alloc memory for messages\n");
return NULL;
}
memset(body, 0, total_messages_size + 1);
unsigned long int seek = 0;
if (prefix) {
memcpy(body, prefix, prefix_len);
seek += strlen(prefix);
}
for (l = 0, e = dlist_head(&messages); e != NULL && l < lines;
e = e->next, l++) {
if (e->data) {
unsigned int len = strlen(e->data);
memcpy(body + seek, e->data, len);
seek += len;
if (line_delimiter && l < lines - 1 && e->next != NULL) {
memcpy(body + seek, line_delimiter, line_delimiter_len);
seek += line_delimiter_len;
}
}
}
if (suffix) {
memcpy(body + seek, suffix, suffix_len);
}
return body;
}