1 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
2  * Copyright 2011-2019 Pierre Ossman for Cendio AB
3  *
4  * This is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This software is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this software; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17  * USA.
18  */
19 
20 //
21 // util.h - miscellaneous useful bits
22 //
23 
24 #ifndef __RFB_UTIL_H__
25 #define __RFB_UTIL_H__
26 
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 
31 #include <limits.h>
32 #include <string.h>
33 
34 struct timeval;
35 
36 #ifdef __GNUC__
37 #  define __printf_attr(a, b) __attribute__((__format__ (__printf__, a, b)))
38 #else
39 #  define __printf_attr(a, b)
40 #endif // __GNUC__
41 
42 #ifndef __unused_attr
43 #  define __unused_attr __attribute((__unused__))
44 #endif
45 
46 namespace rfb {
47 
48   // -=- Class to handle cleanup of arrays of characters
49   class CharArray {
50   public:
CharArray()51     CharArray() : buf(0) {}
CharArray(char * str)52     CharArray(char* str) : buf(str) {} // note: assumes ownership
CharArray(size_t len)53     CharArray(size_t len) {
54       buf = new char[len]();
55       memset(buf, 0, len);
56     }
~CharArray()57     ~CharArray() {
58       delete [] buf;
59     }
60     void format(const char *fmt, ...) __printf_attr(2, 3);
61     // Get the buffer pointer & clear it (i.e. caller takes ownership)
takeBuf()62     char* takeBuf() {char* tmp = buf; buf = 0; return tmp;}
replaceBuf(char * b)63     void replaceBuf(char* b) {delete [] buf; buf = b;}
64     char* buf;
65   private:
66     CharArray(const CharArray&);
67     CharArray& operator=(const CharArray&);
68   };
69 
70   char* strDup(const char* s);
71   void strFree(char* s);
72   void strFree(wchar_t* s);
73 
74   // Returns true if split successful.  Returns false otherwise.
75   // ALWAYS *copies* first part of string to out1 buffer.
76   // If limiter not found, leaves out2 alone (null) and just copies to out1.
77   // If out1 or out2 non-zero, calls strFree and zeroes them.
78   // If fromEnd is true, splits at end of string rather than beginning.
79   // Either out1 or out2 may be null, in which case the split will not return
80   // that part of the string.  Obviously, setting both to 0 is not useful...
81   bool strSplit(const char* src, const char limiter, char** out1, char** out2, bool fromEnd=false);
82 
83   // Returns true if src contains c
84   bool strContains(const char* src, char c);
85 
86   // Copies src to dest, up to specified length-1, and guarantees termination
87   void strCopy(char* dest, const char* src, int destlen);
88 
89   // Makes sure line endings are in a certain format
90 
91   char* convertLF(const char* src, size_t bytes = (size_t)-1);
92   char* convertCRLF(const char* src, size_t bytes = (size_t)-1);
93 
94   // Convertions between various Unicode formats. The returned strings are
95   // always null terminated and must be freed using strFree().
96 
97   size_t ucs4ToUTF8(unsigned src, char* dst);
98   size_t utf8ToUCS4(const char* src, size_t max, unsigned* dst);
99 
100   size_t ucs4ToUTF16(unsigned src, wchar_t* dst);
101   size_t utf16ToUCS4(const wchar_t* src, size_t max, unsigned* dst);
102 
103   char* latin1ToUTF8(const char* src, size_t bytes = (size_t)-1);
104   char* utf8ToLatin1(const char* src, size_t bytes = (size_t)-1);
105 
106   char* utf16ToUTF8(const wchar_t* src, size_t units = (size_t)-1);
107   wchar_t* utf8ToUTF16(const char* src, size_t bytes = (size_t)-1);
108 
109   // HELPER functions for timeout handling
110 
111   // soonestTimeout() is a function to help work out the soonest of several
112   //   timeouts.
soonestTimeout(int * timeout,int newTimeout)113   inline void soonestTimeout(int* timeout, int newTimeout) {
114     if (newTimeout && (!*timeout || newTimeout < *timeout))
115       *timeout = newTimeout;
116   }
117 
118   // secsToMillis() turns seconds into milliseconds, capping the value so it
119   //   can't wrap round and become -ve
secsToMillis(int secs)120   inline int secsToMillis(int secs) {
121     return (secs < 0 || secs > (INT_MAX/1000) ? INT_MAX : secs * 1000);
122   }
123 
124   // Returns time elapsed between two moments in milliseconds.
125   unsigned msBetween(const struct timeval *first,
126                      const struct timeval *second);
127 
128   // Returns time elapsed since given moment in milliseconds.
129   unsigned msSince(const struct timeval *then);
130 
131   // Returns true if first happened before seconds
132   bool isBefore(const struct timeval *first,
133                 const struct timeval *second);
134 
135   size_t siPrefix(long long value, const char *unit,
136                   char *buffer, size_t maxlen, int precision=6);
137   size_t iecPrefix(long long value, const char *unit,
138                    char *buffer, size_t maxlen, int precision=6);
139 }
140 
141 // Some platforms (e.g. Windows) include max() and min() macros in their
142 // standard headers, but they are also standard C++ template functions, so some
143 // C++ headers will undefine them.  So we steer clear of the names min and max
144 // and define __rfbmin and __rfbmax instead.
145 
146 #ifndef __rfbmax
147 #define __rfbmax(a,b) (((a) > (b)) ? (a) : (b))
148 #endif
149 #ifndef __rfbmin
150 #define __rfbmin(a,b) (((a) < (b)) ? (a) : (b))
151 #endif
152 
153 #endif
154