blob: f52213b32063fbb001d47f410079ec3e42bbf8e8 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
Adam Tkac8aee1a82009-09-04 12:08:56 +000019#ifdef HAVE_CONFIG_H
20#include <config.h>
Adam Tkacad1cbd92008-10-06 14:08:00 +000021#endif
22
Pierre Ossmanba6fbfe2015-03-03 16:41:29 +010023#include <stdarg.h>
Pierre Ossman64624342015-03-03 16:30:13 +010024#include <stdio.h>
Pierre Ossman5bc20a62011-11-08 12:42:41 +000025#include <sys/time.h>
26
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000027#include <rfb/util.h>
28
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000029namespace rfb {
30
Pierre Ossmanba6fbfe2015-03-03 16:41:29 +010031 void CharArray::format(const char *fmt, ...) {
32 va_list ap;
Steve Kondikb3c9f7b2017-07-08 02:08:43 -070033 int len;
Pierre Ossmanba6fbfe2015-03-03 16:41:29 +010034
35 va_start(ap, fmt);
36 len = vsnprintf(NULL, 0, fmt, ap);
37 va_end(ap);
38
39 delete [] buf;
40
41 if (len < 0) {
42 buf = new char[1];
43 buf[0] = '\0';
44 return;
45 }
46
47 buf = new char[len+1];
48
49 va_start(ap, fmt);
50 vsnprintf(buf, len+1, fmt, ap);
51 va_end(ap);
52 }
53
Adam Tkacd36b6262009-09-04 10:57:20 +000054 char* strDup(const char* s) {
55 if (!s) return 0;
56 int l = strlen(s);
57 char* r = new char[l+1];
58 memcpy(r, s, l+1);
59 return r;
60 };
61
62 void strFree(char* s) {
63 delete [] s;
64 }
65
66
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000067 bool strSplit(const char* src, const char limiter, char** out1, char** out2, bool fromEnd) {
68 CharArray out1old, out2old;
69 if (out1) out1old.buf = *out1;
70 if (out2) out2old.buf = *out2;
71 int len = strlen(src);
72 int i=0, increment=1, limit=len;
73 if (fromEnd) {
74 i=len-1; increment = -1; limit = -1;
75 }
76 while (i!=limit) {
77 if (src[i] == limiter) {
78 if (out1) {
79 *out1 = new char[i+1];
80 if (i) memcpy(*out1, src, i);
81 (*out1)[i] = 0;
82 }
83 if (out2) {
84 *out2 = new char[len-i];
85 if (len-i-1) memcpy(*out2, &src[i+1], len-i-1);
86 (*out2)[len-i-1] = 0;
87 }
88 return true;
89 }
90 i+=increment;
91 }
Adam Tkacd36b6262009-09-04 10:57:20 +000092 if (out1) *out1 = strDup(src);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000093 if (out2) *out2 = 0;
94 return false;
95 }
96
97 bool strContains(const char* src, char c) {
98 int l=strlen(src);
99 for (int i=0; i<l; i++)
100 if (src[i] == c) return true;
101 return false;
102 }
103
104 void strCopy(char* dest, const char* src, int destlen) {
105 if (src)
106 strncpy(dest, src, destlen-1);
107 dest[src ? destlen-1 : 0] = 0;
108 }
109
Pierre Ossmana99d14d2015-12-13 15:43:46 +0100110 unsigned msBetween(const struct timeval *first,
111 const struct timeval *second)
112 {
113 unsigned diff;
114
115 diff = (second->tv_sec - first->tv_sec) * 1000;
116
117 diff += second->tv_usec / 1000;
118 diff -= first->tv_usec / 1000;
119
120 return diff;
121 }
122
Pierre Ossman5bc20a62011-11-08 12:42:41 +0000123 unsigned msSince(const struct timeval *then)
124 {
125 struct timeval now;
Pierre Ossman5bc20a62011-11-08 12:42:41 +0000126
127 gettimeofday(&now, NULL);
128
Pierre Ossmana99d14d2015-12-13 15:43:46 +0100129 return msBetween(then, &now);
130 }
Pierre Ossman5bc20a62011-11-08 12:42:41 +0000131
Pierre Ossmana99d14d2015-12-13 15:43:46 +0100132 bool isBefore(const struct timeval *first,
133 const struct timeval *second)
134 {
135 if (first->tv_sec < second->tv_sec)
136 return true;
137 if (first->tv_sec > second->tv_sec)
138 return false;
139 if (first->tv_usec < second->tv_usec)
140 return true;
141 return false;
Pierre Ossman5bc20a62011-11-08 12:42:41 +0000142 }
Pierre Ossman64624342015-03-03 16:30:13 +0100143
144 static size_t doPrefix(long long value, const char *unit,
145 char *buffer, size_t maxlen,
146 unsigned divisor, const char **prefixes,
Pierre Ossman921f6c82017-02-24 12:33:09 +0100147 size_t prefixCount, int precision) {
Pierre Ossman64624342015-03-03 16:30:13 +0100148 double newValue;
149 size_t prefix, len;
150
151 newValue = value;
152 prefix = 0;
153 while (newValue >= divisor) {
154 if (prefix >= prefixCount)
155 break;
156 newValue /= divisor;
157 prefix++;
158 }
159
Pierre Ossman921f6c82017-02-24 12:33:09 +0100160 len = snprintf(buffer, maxlen, "%.*g %s%s", precision, newValue,
Pierre Ossman64624342015-03-03 16:30:13 +0100161 (prefix == 0) ? "" : prefixes[prefix-1], unit);
162 buffer[maxlen-1] = '\0';
163
164 return len;
165 }
166
167 static const char *siPrefixes[] =
168 { "k", "M", "G", "T", "P", "E", "Z", "Y" };
169 static const char *iecPrefixes[] =
170 { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
171
172 size_t siPrefix(long long value, const char *unit,
Pierre Ossman921f6c82017-02-24 12:33:09 +0100173 char *buffer, size_t maxlen, int precision) {
Pierre Ossman64624342015-03-03 16:30:13 +0100174 return doPrefix(value, unit, buffer, maxlen, 1000, siPrefixes,
Pierre Ossman921f6c82017-02-24 12:33:09 +0100175 sizeof(siPrefixes)/sizeof(*siPrefixes),
176 precision);
Pierre Ossman64624342015-03-03 16:30:13 +0100177 }
178
179 size_t iecPrefix(long long value, const char *unit,
Pierre Ossman921f6c82017-02-24 12:33:09 +0100180 char *buffer, size_t maxlen, int precision) {
Pierre Ossman64624342015-03-03 16:30:13 +0100181 return doPrefix(value, unit, buffer, maxlen, 1024, iecPrefixes,
Pierre Ossman921f6c82017-02-24 12:33:09 +0100182 sizeof(iecPrefixes)/sizeof(*iecPrefixes),
183 precision);
Pierre Ossman64624342015-03-03 16:30:13 +0100184 }
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000185};