]> arthur.barton.de Git - netdata.git/blob - src/web_buffer.c
added nfacct charts (disabled for the moment - they must be made an external plugin...
[netdata.git] / src / web_buffer.c
1 #include <stdlib.h>
2 #include <math.h>
3
4 #include "web_buffer.h"
5
6 #include "common.h"
7 #include "log.h"
8
9 void web_buffer_strcpy(struct web_buffer *wb, const char *txt)
10 {
11         char *buffer = wb->buffer;
12         long bytes = wb->bytes, size = wb->size, i = 0;
13
14         while(txt[i] && bytes < size)
15                 buffer[bytes++] = txt[i++];
16
17         wb->bytes = bytes;
18 }
19
20 int print_calculated_number(char *str, calculated_number value)
21 {
22         char *wstr = str;
23
24         int sign = (value < 0) ? 1 : 0;
25         if(sign) value = -value;
26
27         // without llrint() there are rounding problems
28         // for example 0.9 becomes 0.89
29         unsigned long long uvalue = llrint(value * (calculated_number)100000);
30
31         // print each digit
32         do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
33
34         // make sure we have 6 bytes at least
35         while((wstr - str) < 6) *wstr++ = '0';
36
37         // put the sign back
38         if(sign) *wstr++ = '-';
39
40         // reverse it
41         wstr--;
42         strreverse(str, wstr);
43
44         // remove trailing zeros
45         int decimal = 5;
46         while(decimal > 0 && *wstr == '0') {
47                 *wstr-- = '\0';
48                 decimal--;
49         }
50
51         // terminate it, one position to the right
52         // to let space for a dot
53         wstr[2] = '\0';
54
55         // make space for the dot
56         int i;
57         for(i = 0; i < decimal ;i++) {
58                 wstr[1] = wstr[0];
59                 wstr--;
60         }
61
62         // put the dot
63         if(wstr[2] == '\0') { wstr[1] = '\0'; decimal--; }
64         else wstr[1] = '.';
65
66         // return the buffer length
67         return ( (wstr - str) + 2 + decimal );
68 }
69
70 void web_buffer_rrd_value(struct web_buffer *wb, calculated_number value)
71 {
72         if(wb->size - wb->bytes < 50) return;
73         wb->bytes += print_calculated_number(&wb->buffer[wb->bytes], value);
74 }
75
76 // generate a javascript date, the fastest possible way...
77 void web_buffer_jsdate(struct web_buffer *wb, int year, int month, int day, int hours, int minutes, int seconds)
78 {
79         //         10        20        30      = 35
80         // 01234567890123456789012345678901234
81         // Date(2014, 04, 01, 03, 28, 20, 065)
82
83         if(wb->size - wb->bytes < 36) return;
84
85         char *b = &wb->buffer[wb->bytes];
86
87         int i = 0;
88         b[i++]='D';
89         b[i++]='a';
90         b[i++]='t';
91         b[i++]='e';
92         b[i++]='(';
93         b[i++]= 48 + year / 1000; year -= (year / 1000) * 1000;
94         b[i++]= 48 + year / 100; year -= (year / 100) * 100;
95         b[i++]= 48 + year / 10;
96         b[i++]= 48 + year % 10;
97         b[i++]=',';
98         //b[i++]=' ';
99         b[i]= 48 + month / 10; if(b[i] != '0') i++;
100         b[i++]= 48 + month % 10;
101         b[i++]=',';
102         //b[i++]=' ';
103         b[i]= 48 + day / 10; if(b[i] != '0') i++;
104         b[i++]= 48 + day % 10;
105         b[i++]=',';
106         //b[i++]=' ';
107         b[i]= 48 + hours / 10; if(b[i] != '0') i++;
108         b[i++]= 48 + hours % 10;
109         b[i++]=',';
110         //b[i++]=' ';
111         b[i]= 48 + minutes / 10; if(b[i] != '0') i++;
112         b[i++]= 48 + minutes % 10;
113         b[i++]=',';
114         //b[i++]=' ';
115         b[i]= 48 + seconds / 10; if(b[i] != '0') i++;
116         b[i++]= 48 + seconds % 10;
117         b[i++]=')';
118         b[i]='\0';
119
120         wb->bytes += i;
121 }
122
123 struct web_buffer *web_buffer_create(long size)
124 {
125         struct web_buffer *b;
126
127         debug(D_WEB_BUFFER, "Creating new web buffer of size %d.", size);
128
129         b = calloc(1, sizeof(struct web_buffer));
130         if(!b) {
131                 error("Cannot allocate a web_buffer.");
132                 return NULL;
133         }
134
135         b->buffer = malloc(size);
136         if(!b->buffer) {
137                 error("Cannot allocate a buffer of size %u.", size);
138                 free(b);
139                 return NULL;
140         }
141         b->buffer[0] = '\0';
142         b->size = size;
143         b->contenttype = CT_TEXT_PLAIN;
144         return(b);
145 }
146
147 void web_buffer_free(struct web_buffer *b)
148 {
149         debug(D_WEB_BUFFER, "Freeing web buffer of size %d.", b->size);
150
151         if(b->buffer) free(b->buffer);
152         free(b);
153 }
154
155 void web_buffer_increase(struct web_buffer *b, long free_size_required)
156 {
157         long left = b->size - b->bytes;
158
159         if(left >= free_size_required) return;
160         long increase = free_size_required - left;
161         if(increase < WEB_DATA_LENGTH_INCREASE_STEP) increase = WEB_DATA_LENGTH_INCREASE_STEP;
162
163         debug(D_WEB_BUFFER, "Increasing data buffer from size %d to %d.", b->size, b->size + increase);
164
165         b->buffer = realloc(b->buffer, b->size + increase);
166         if(!b->buffer) fatal("Failed to increase data buffer from size %d to %d.", b->size, b->size + increase);
167         
168         b->size += increase;
169 }