mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-10-26 11:19:16 +00:00
- peekProcString(): reads the specified amount of data at the specified address and returns it as std::string. An empty std::string is returned in case of error. If length is 0, the function reads one byte at a time and stops when either '\0' is found or 3 seconds have passed. The successfully read data is returned, also in case of error. - peekProcVector(): can be used to read a dynamic array (size known at runtime) from the process' memory. Dynamic arrays are part of C99, which should be supported by most compilers nowadays, but std::vector provides many advantages (e.g. easy resize) over a raw array. - getVirtualFunction(): gets the address of a virtual function given its index and the class object's base address. A macro called GET_POINTER_SIZE is added because "is64Bit ? 8 : 4" is used in two places now. Also, it's useful and intuitive for plugin(s) programmers. - sinCos(): calculates sine and cosine of the specified value. On Linux the calculation is guaranteed to be simultaneous. - degreesToRadians(): converts degrees to radians. - isBigEndian(): returns whether the architecture is big-endian, by checking how a 4-byte value is stored in memory. - networkToHost() converts from network byte order to host byte order. I decided to create our own function because ntohs() is part of winsock(2).h on Windows, which means we would have to link to "ws2_32". This commit also adds and makes use of the new "OS_WINDOWS" and "OS_LINUX" definitions. The reason behind their existence is the "_WIN32" and "__linux__" definitions not being intuitive, mainly because they don't follow the same naming convention.
116 lines
2.9 KiB
C++
116 lines
2.9 KiB
C++
// Copyright 2005-2020 The Mumble Developers. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license
|
|
// that can be found in the LICENSE file at the root of the
|
|
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
|
|
|
|
#ifndef MUMBLE_MUMBLE_PLUGIN_UTILS_H_
|
|
#define MUMBLE_MUMBLE_PLUGIN_UTILS_H_
|
|
|
|
#include <codecvt>
|
|
#include <locale>
|
|
|
|
#ifdef OS_LINUX
|
|
# include <fenv.h>
|
|
#endif
|
|
|
|
#ifdef _MSC_VER
|
|
# include <intrin.h>
|
|
#endif
|
|
|
|
/// This union is used by isBigEndian() to determine the endianness.
|
|
union SingleSplit4Bytes {
|
|
uint32_t single;
|
|
uint8_t split[4];
|
|
|
|
constexpr SingleSplit4Bytes(const uint32_t value) : single(value) {}
|
|
};
|
|
|
|
static inline std::string utf16ToUtf8(const std::wstring &wstr) {
|
|
std::wstring_convert< std::codecvt_utf8_utf16< wchar_t > > conv;
|
|
return conv.to_bytes(wstr);
|
|
}
|
|
|
|
// escape lossily converts the given
|
|
// string to ASCII, replacing any
|
|
// character not within the printable
|
|
// ASCII region (32-126) with an ASCII
|
|
// space character.
|
|
//
|
|
// escape also replaces any double quote
|
|
// characters with an ASCII space. This
|
|
// allows the string to be safely used
|
|
// when constructing JSON documents via
|
|
// string concatenation.
|
|
//
|
|
// Finally, escape ensures that the given
|
|
// string is NUL-terminated by always
|
|
// setting the last byte of the input
|
|
// string to the value 0.
|
|
static inline void escape(char *str, const size_t &size) {
|
|
// Ensure the input string is properly NUL-terminated.
|
|
str[size - 1] = 0;
|
|
char *c = str;
|
|
|
|
while (*c != '\0') {
|
|
// For JSON compatibility, the string
|
|
// can't contain double quotes.
|
|
// If a double quote is found, replace
|
|
// it with an ASCII space.
|
|
if (*c == '"') {
|
|
*c = ' ';
|
|
}
|
|
|
|
// Ensure the string is within printable
|
|
// ASCII. If not, replace the offending
|
|
// byte with an ASCII space.
|
|
if (*c < 32 || *c > 126) {
|
|
*c = ' ';
|
|
}
|
|
|
|
c += 1;
|
|
}
|
|
}
|
|
|
|
/// Calculates sine and cosine of the specified value.
|
|
/// On Linux the calculation is guaranteed to be simultaneous.
|
|
static inline bool sinCos(const float value, float &outSin, float &outCos) {
|
|
#ifdef OS_WINDOWS
|
|
outSin = sin(value);
|
|
outCos = cos(value);
|
|
return true;
|
|
#else
|
|
errno = 0;
|
|
feclearexcept(FE_ALL_EXCEPT);
|
|
|
|
sincosf(value, &outSin, &outCos);
|
|
|
|
return fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) == 0;
|
|
#endif
|
|
}
|
|
|
|
/// Converts degrees to radians.
|
|
static inline float degreesToRadians(const float degrees) {
|
|
constexpr float piOver180 = M_PI / 180.0f;
|
|
return piOver180 * degrees;
|
|
}
|
|
|
|
/// Detects whether the architecture is big-endian.
|
|
static constexpr bool isBigEndian() {
|
|
// An union allows access to a single byte without the need for a cast.
|
|
return SingleSplit4Bytes(0x01020304).split[0] == 1;
|
|
}
|
|
|
|
/// Converts from network byte order to host byte order.
|
|
static inline uint16_t networkToHost(const uint16_t value) {
|
|
if (isBigEndian()) {
|
|
return value;
|
|
}
|
|
#ifdef _MSC_VER
|
|
return _byteswap_ushort(value);
|
|
#else
|
|
return __builtin_bswap16(value);
|
|
#endif
|
|
}
|
|
|
|
#endif
|