Compare commits

..

14 Commits

Author SHA1 Message Date
walker0643
53ebc47ace Merge pull request #106 from coypoop/master
Small patches for netbsd
2018-09-08 19:09:56 -04:00
walker0643
f203a7f49e Merge pull request #121 from cuviper/barrier-fromUTF8
Fix data indexes in Unicode::fromUTF8
2018-09-08 19:05:13 -04:00
walker0643
e65ea3c545 Update README.md 2018-09-08 18:27:00 -04:00
3794767459 add firewall rule for default port on installation (windows) 2018-09-08 16:49:08 -04:00
b2aac6719f rename field Interface to Address in GUI settings dialog 2018-09-08 15:20:02 -04:00
075d4f4758 enable high-dps awareness for barriers/barrierc. fixes screen geometry calculations for screens with >100% scaling 2018-09-08 14:36:50 -04:00
c63dd6f4f1 Merge branch 'master' of github.com:debauchee/barrier 2018-09-07 18:15:17 -04:00
9e2fbe269d bump ssl cert key size up to 2048 from 1024. fixes #126 2018-09-07 18:14:03 -04:00
Josh Stone
7a0bc3abb7 Fix data indexes in Unicode::fromUTF8 2018-08-29 14:40:39 -07:00
walker0643
5916d40053 Merge pull request #111 from pbogut/fix-server-help-message
Fix config file name in server help message
2018-08-25 21:04:20 -04:00
Pawel Bogut
af8bbf2674 Fix config file name in server help message 2018-08-09 07:54:30 +02:00
coypu
443e656be2 Use ${CMAKE_DL_LIBS} rather than listing OSes.
CMake makes our lives easier. Needed for NetBSD, which also
doesn't have libdl.so.
2018-08-02 15:46:01 +03:00
coypu
87820d9387 have all other OSes handled in the else case.
No reason to limit to just freebsd and linux, we handle all existing
supported OSes in the previous cases.
Needed for NetBSD support.
2018-08-02 15:46:01 +03:00
coypu
c7c14f02dd Also add curl include directories.
While here, use the variables from FindCURL.cmake
2018-08-02 15:46:01 +03:00
22 changed files with 68 additions and 346 deletions

View File

@@ -132,7 +132,9 @@ if (UNIX)
# curl is used on both Linux and Mac # curl is used on both Linux and Mac
find_package (CURL) find_package (CURL)
if (CURL_FOUND) if (CURL_FOUND)
list (APPEND libs curl) include_directories(${CURL_INCLUDE_DIRS})
list (APPEND libs ${CURL_LIBRARIES})
else() else()
message (FATAL_ERROR "Missing library: curl") message (FATAL_ERROR "Missing library: curl")
endif() endif()

View File

@@ -10,7 +10,7 @@ Barrier is KVM software forked from Symless's synergy 1.9 codebase. Synergy was
### What's different? ### What's different?
Whereas synergy has moved beyond its goals from the 1.x era, barrier aims to maintain that simplicity. Barrier will let you use your keyboard and mouse from machine A to control machine B (or more). It's that simple. Whereas synergy has moved beyond its goals from the 1.x era, Barrier aims to maintain that simplicity. Barrier will let you use your keyboard and mouse from machine A to control machine B (or more). It's that simple.
### Project goals ### Project goals

View File

@@ -6,6 +6,7 @@
#define MyAppServiceName "Barrier" #define MyAppServiceName "Barrier"
#define MyAppServiceExe "barrierd.exe" #define MyAppServiceExe "barrierd.exe"
#define MyAppServiceDesc "Manages the Barrier background processes." #define MyAppServiceDesc "Manages the Barrier background processes."
#define MyAppListenerDesc "Barrier Listener"
[Setup] [Setup]
AppId={{41036EA6-3F7A-4803-8AE0-469E5E91EFCC} AppId={{41036EA6-3F7A-4803-8AE0-469E5E91EFCC}
@@ -40,6 +41,10 @@ Name: "{commonprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run] [Run]
; there's no "check if exists" or "insert if not exists" for netsh's firewall commands
; to avoid duplicate entries remove the existing rule (fails if it doesn't exist) before adding
Filename: {sys}\netsh.exe; Parameters: "advfirewall firewall delete rule name=""{#MyAppListenerDesc}"""; Flags: runhidden
Filename: {sys}\netsh.exe; Parameters: "advfirewall firewall add rule name=""{#MyAppListenerDesc}"" protocol=TCP dir=in localport=24800 action=allow"; Flags: runhidden
Filename: {sys}\sc.exe; Parameters: "create {#MyAppServiceName} start= auto binPath= ""{app}\{#MyAppServiceExe}"""; Flags: runhidden Filename: {sys}\sc.exe; Parameters: "create {#MyAppServiceName} start= auto binPath= ""{app}\{#MyAppServiceExe}"""; Flags: runhidden
Filename: {sys}\sc.exe; Parameters: "description {#MyAppServiceName} ""{#MyAppServiceDesc}"""; Flags: runhidden Filename: {sys}\sc.exe; Parameters: "description {#MyAppServiceName} ""{#MyAppServiceDesc}"""; Flags: runhidden
Filename: {sys}\sc.exe; Parameters: "start {#MyAppServiceName}"; Flags: runhidden Filename: {sys}\sc.exe; Parameters: "start {#MyAppServiceName}"; Flags: runhidden
@@ -51,6 +56,7 @@ Type: files; Name: "{app}\barrierd.log"
[UninstallRun] [UninstallRun]
Filename: {sys}\sc.exe; Parameters: "stop {#MyAppServiceName}"; Flags: runhidden Filename: {sys}\sc.exe; Parameters: "stop {#MyAppServiceName}"; Flags: runhidden
Filename: {sys}\sc.exe; Parameters: "delete {#MyAppServiceName}"; Flags: runhidden Filename: {sys}\sc.exe; Parameters: "delete {#MyAppServiceName}"; Flags: runhidden
Filename: {sys}\netsh.exe; Parameters: "advfirewall firewall delete rule name=""{#MyAppListenerDesc}"""; Flags: runhidden
[CustomMessages] [CustomMessages]
DependenciesDir="redist" DependenciesDir="redist"
@@ -68,7 +74,7 @@ begin
// initialize windows version // initialize windows version
initwinversion(); initwinversion();
vcredist2017('14'); // min allowed version is 14.0 vcredist2017('14'); // min allowed version is 14.0
Result := true; Result := true;
end; end;

View File

@@ -29,6 +29,7 @@ if (WIN32)
tb_idle.ico tb_idle.ico
tb_run.ico tb_run.ico
tb_wait.ico tb_wait.ico
barrierc.exe.manifest
) )
elseif (APPLE) elseif (APPLE)
file(GLOB arch_headers "OSX*.h") file(GLOB arch_headers "OSX*.h")

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"><security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo><application xmlns="urn:schemas-microsoft-com:asm.v3"><windowsSettings><dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware></windowsSettings></application></assembly>

View File

@@ -29,6 +29,7 @@ if (WIN32)
tb_idle.ico tb_idle.ico
tb_run.ico tb_run.ico
tb_wait.ico tb_wait.ico
barriers.exe.manifest
) )
elseif (APPLE) elseif (APPLE)
file(GLOB arch_headers "OSX*.h") file(GLOB arch_headers "OSX*.h")

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"><security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo><application xmlns="urn:schemas-microsoft-com:asm.v3"><windowsSettings><dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware></windowsSettings></application></assembly>

View File

@@ -6,25 +6,17 @@ set (CMAKE_AUTORCC ON)
set (CMAKE_AUTOUIC ON) set (CMAKE_AUTOUIC ON)
set (CMAKE_INCLUDE_CURRENT_DIR ON) set (CMAKE_INCLUDE_CURRENT_DIR ON)
file (GLOB GUI_SOURCE_FILES src/*.cpp src/*.h)
file (GLOB GUI_UI_FILES src/*.ui)
if (WIN32) if (WIN32)
set (resources res/win/Barrier.rc) set (GUI_RC_FILES res/win/Barrier.rc)
set (arch "win32")
else()
set (arch "unix")
endif()
file (GLOB sources src/*.cpp src/${arch}/*.cpp)
file (GLOB headers src/*.h src/${arch}/*.h)
file (GLOB designs src/*.ui)
if (BARRIER_ADD_HEADERS)
list (APPEND sources ${headers})
endif() endif()
add_executable (barrier WIN32 add_executable (barrier WIN32
${sources} ${GUI_SOURCE_FILES}
${designs} ${GUI_UI_FILES}
${resources} ${GUI_RC_FILES}
res/Barrier.qrc res/Barrier.qrc
) )
@@ -40,12 +32,11 @@ if (WIN32)
HINTS ENV BONJOUR_SDK_HOME HINTS ENV BONJOUR_SDK_HOME
PATH_SUFFIXES "Lib/x64") PATH_SUFFIXES "Lib/x64")
set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT") set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
target_link_libraries (barrier ${DNSSD_LIB} Ws2_32.lib Iphlpapi.lib) target_link_libraries (barrier ${DNSSD_LIB})
elseif (APPLE) elseif (APPLE)
find_library(APPSERVICES_LIB ApplicationServices) find_library(APPSERVICES_LIB ApplicationServices)
target_link_libraries(barrier ${APPSERVICES_LIB}) target_link_libraries(barrier ${APPSERVICES_LIB})
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR else()
${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
target_link_libraries (barrier dns_sd) target_link_libraries (barrier dns_sd)
endif() endif()

View File

@@ -1,10 +0,0 @@
#pragma once
#include <string>
namespace Debauchee
{
std::string default_interface_ip();
}

View File

@@ -167,7 +167,7 @@
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="m_pLabel_21"> <widget class="QLabel" name="m_pLabel_21">
<property name="text"> <property name="text">
<string>&amp;Interface:</string> <string>&amp;Address:</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>m_pLineEditInterface</cstring> <cstring>m_pLineEditInterface</cstring>

View File

@@ -121,7 +121,7 @@ void SslCertificate::generateCertificate()
// private key // private key
arguments.append("-newkey"); arguments.append("-newkey");
arguments.append("rsa:1024"); arguments.append("rsa:2048");
QDir sslDir(sslDirPath); QDir sslDir(sslDirPath);
if (!sslDir.exists()) { if (!sslDir.exists()) {

View File

@@ -20,7 +20,6 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "ZeroconfRegister.h" #include "ZeroconfRegister.h"
#include "ZeroconfBrowser.h" #include "ZeroconfBrowser.h"
#include "DefaultInterfaceIP.h"
#include <QtNetwork> #include <QtNetwork>
#include <QMessageBox> #include <QMessageBox>
@@ -35,6 +34,12 @@
#include <stdlib.h> #include <stdlib.h>
#endif #endif
static const QStringList preferedIPAddress(
QStringList() <<
"192.168." <<
"10." <<
"172.");
const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp"; const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp";
const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp"; const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp";
@@ -119,6 +124,27 @@ void ZeroconfService::errorHandle(DNSServiceErrorType errorCode)
tr("Error code: %1.").arg(errorCode)); tr("Error code: %1.").arg(errorCode));
} }
QString ZeroconfService::getLocalIPAddresses()
{
QStringList addresses;
foreach (const QHostAddress& address, QNetworkInterface::allAddresses()) {
if (address.protocol() == QAbstractSocket::IPv4Protocol &&
address != QHostAddress(QHostAddress::LocalHost)) {
addresses.append(address.toString());
}
}
foreach (const QString& preferedIP, preferedIPAddress) {
foreach (const QString& address, addresses) {
if (address.startsWith(preferedIP)) {
return address;
}
}
}
return "";
}
bool ZeroconfService::registerService(bool server) bool ZeroconfService::registerService(bool server)
{ {
bool result = true; bool result = true;
@@ -133,7 +159,7 @@ bool ZeroconfService::registerService(bool server)
else { else {
m_pZeroconfRegister = new ZeroconfRegister(this); m_pZeroconfRegister = new ZeroconfRegister(this);
if (server) { if (server) {
QString localIP = QString::fromStdString(Debauchee::default_interface_ip()); QString localIP = getLocalIPAddresses();
if (localIP.isEmpty()) { if (localIP.isEmpty()) {
QMessageBox::warning(m_pMainWindow, tr("Barrier"), QMessageBox::warning(m_pMainWindow, tr("Barrier"),
tr("Failed to get local IP address. " tr("Failed to get local IP address. "

View File

@@ -42,6 +42,7 @@ private slots:
void errorHandle(DNSServiceErrorType errorCode); void errorHandle(DNSServiceErrorType errorCode);
private: private:
QString getLocalIPAddresses();
bool registerService(bool server); bool registerService(bool server);
private: private:

View File

@@ -67,13 +67,6 @@ int main(int argc, char* argv[])
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */ /* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */
::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1); ::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1);
#endif #endif
#if _WIN32
// winsock needs to be initialized for DefaultInterfaceIP
WSADATA wd;
WSAStartup(MAKEWORD(2, 0), &wd);
#endif
QCoreApplication::setOrganizationName("Debauchee"); QCoreApplication::setOrganizationName("Debauchee");
QCoreApplication::setOrganizationDomain("github.com"); QCoreApplication::setOrganizationDomain("github.com");
QCoreApplication::setApplicationName("Barrier"); QCoreApplication::setApplicationName("Barrier");

View File

@@ -1,79 +0,0 @@
#include "IfAddrsResource.h"
#include "SocketResource.h"
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef __linux__
#include <linux/wireless.h>
#else
#include <net/if.h>
#include <net/if_media.h>
#endif
#include <string>
#include <cstring>
namespace Debauchee
{
static bool is_wireless(const char * ifname, const SocketResource& sock)
{
#ifdef __linux__
struct iwreq req;
::memset(&req, 0, sizeof(struct iwreq));
::strncpy(req.ifr_name, ifname, IFNAMSIZ - 1);
return ioctl(sock, SIOCGIWMODE, &req) >= 0;
#else
struct ifmediareq req;
::memset(&req, 0, sizeof(struct ifmediareq));
::strncpy(req.ifm_name, ifname, IFNAMSIZ - 1);
if (ioctl(sock, SIOCGIFMEDIA, &req) >= 0 &&
(req.ifm_status & IFM_AVALID)
) {
return IFM_TYPE(req.ifm_active) == IFM_IEEE80211;
}
return false;
#endif
}
static bool is_wireless(const char * ifname)
{
if (ifname) {
SocketResource sock(AF_INET, SOCK_DGRAM, 0);
if (sock.is_valid()) {
return is_wireless(ifname, sock);
}
}
return false;
}
std::string default_interface_ip()
{
std::string wirelessAddress;
IfAddrsResource ifa;
if (ifa.is_valid()) {
for (struct ifaddrs * next = ifa; next; next = next->ifa_next) {
auto sain = (struct sockaddr_in *)next->ifa_addr;
if (!sain || sain->sin_family != AF_INET ||
!(next->ifa_flags & IFF_RUNNING) ||
(next->ifa_flags & IFF_LOOPBACK)
) {
continue;
}
std::string address = inet_ntoa(sain->sin_addr);
// take first wired address right away
if (!is_wireless(next->ifa_name)) {
return address;
}
// save first wireless address to be used if we don't find a wired one
if (wirelessAddress.empty()) {
wirelessAddress = address;
}
}
}
return wirelessAddress;
}
}

View File

@@ -1,32 +0,0 @@
#include <sys/types.h>
#include <ifaddrs.h>
namespace Debauchee
{
class IfAddrsResource
{
public:
explicit IfAddrsResource() :
_valid(getifaddrs(&_ifa) == 0)
{
}
~IfAddrsResource()
{
if (_valid) {
freeifaddrs(_ifa);
}
}
bool is_valid() const { return _valid; }
operator struct ifaddrs * () const { return _ifa; }
private:
bool _valid;
struct ifaddrs * _ifa;
};
}

View File

@@ -1,32 +0,0 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
namespace Debauchee
{
class SocketResource
{
public:
explicit SocketResource(int domain, int type, int protocol) :
_fd(socket(domain, type, protocol))
{
}
~SocketResource()
{
if (is_valid()) {
close(_fd);
}
}
bool is_valid() const { return _fd >= 0; }
operator int() const { return _fd; }
private:
int _fd;
};
}

View File

@@ -1,100 +0,0 @@
// REQUIRES: Ws2_32.lib, Iphlpapi.lib
// REQUIRES: WSAStartup(..)
// see comments regarding WSAAddressToStringA in address_string(..)
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iphlpapi.h>
#include <string>
#include "HeapResource.h"
namespace Debauchee
{
static ULONG get_addresses(IP_ADAPTER_ADDRESSES * addresses, PULONG sz)
{
return GetAdaptersAddresses(AF_INET,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL, addresses, sz);
}
static std::string address_string(const SOCKET_ADDRESS& address)
{
// planning to use this with Qt but QString does not have a c'tor
// for wide strings so we need to force the ANSI API here
DWORD szStrAddress = 1023;
char strAddress[1024];
if (WSAAddressToStringA(address.lpSockaddr, address.iSockaddrLength, NULL, strAddress, &szStrAddress)) {
return "";
}
return strAddress;
}
static std::string first_unicast_address(IP_ADAPTER_UNICAST_ADDRESS * unicast)
{
while (unicast) {
auto address = address_string(unicast->Address);
if (!address.empty()) {
return address;
}
unicast = unicast->Next;
}
return std::string();
}
static bool is_useable_interface(const IP_ADAPTER_ADDRESSES * ifa)
{
return
// is an ethernet or wireless interface AND
(ifa->IfType == IF_TYPE_ETHERNET_CSMACD || ifa->IfType == IF_TYPE_IEEE80211) &&
// is up
ifa->OperStatus == IfOperStatusUp;
}
static std::string default_ip_address(const IP_ADAPTER_ADDRESSES * next)
{
std::string wirelessAddress;
for ( ; next; next = next->Next) {
if (!is_useable_interface(next)) {
continue;
}
std::string address = first_unicast_address(next->FirstUnicastAddress);
if (address.empty()) {
continue;
}
// take first wired address right away
if (next->IfType == IF_TYPE_ETHERNET_CSMACD) {
return address;
}
// save first wireless address to be used if we don't find a wired one
if (wirelessAddress.empty()) {
wirelessAddress = address;
}
}
return wirelessAddress;
}
std::string default_interface_ip()
{
const ULONG DefaultSzAddresses = 15 * 1024; // 15k recommended by msdn
ULONG szAddresses = DefaultSzAddresses;
HeapResource<IP_ADAPTER_ADDRESSES> addresses(GetProcessHeap(), 0, DefaultSzAddresses);
if (addresses.is_valid()) {
ULONG result;
while (ERROR_BUFFER_OVERFLOW == (result = get_addresses(addresses, &szAddresses))) {
// add more space in case more adapters have shown up
szAddresses += DefaultSzAddresses;
swap(addresses, HeapResource<IP_ADAPTER_ADDRESSES>(GetProcessHeap(), 0, szAddresses));
if (!addresses.is_valid()) {
break;
}
}
if (result == ERROR_SUCCESS) {
return default_ip_address(addresses);
}
}
return std::string();
}
}

View File

@@ -1,48 +0,0 @@
#pragma once
namespace Debauchee
{
template<class T>
class HeapResource
{
public:
explicit HeapResource(HANDLE heap, DWORD flags, SIZE_T sz) :
_heap(heap),
_flags(flags),
_mem((T*)HeapAlloc(heap, flags, sz))
{
}
HeapResource(HeapResource<T>&& other)
: _mem(NULL)
{
swap(*this, other);
}
~HeapResource()
{
if (is_valid()) {
HeapFree(_heap, _flags, _mem);
}
}
friend void swap(HeapResource<T>& first, HeapResource<T>& second)
{
using std::swap;
swap(first._heap, second._heap);
swap(first._flags, second._flags);
swap(first._mem, second._mem);
}
bool is_valid() const { return _mem != NULL; }
operator T*() const { return _mem; }
private:
HANDLE _heap;
DWORD _flags;
T * _mem;
};
}

View File

@@ -41,7 +41,5 @@ add_library(arch STATIC ${sources})
if (UNIX) if (UNIX)
target_link_libraries(arch ${libs}) target_link_libraries(arch ${libs})
if (NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") target_link_libraries(arch ${CMAKE_DL_LIBS})
target_link_libraries(arch dl)
endif()
endif() endif()

View File

@@ -145,7 +145,7 @@ ServerApp::help()
<< std::endl << std::endl
<< "If no configuration file pathname is provided then the first of the" << std::endl << "If no configuration file pathname is provided then the first of the" << std::endl
<< "following to load successfully sets the configuration:" << std::endl << "following to load successfully sets the configuration:" << std::endl
<< " " << PathUtilities::concat(DataDirectories::profile(), SYS_CONFIG_NAME) << std::endl << " " << PathUtilities::concat(DataDirectories::profile(), USR_CONFIG_NAME) << std::endl
<< " " << PathUtilities::concat(DataDirectories::systemconfig(), SYS_CONFIG_NAME) << std::endl; << " " << PathUtilities::concat(DataDirectories::systemconfig(), SYS_CONFIG_NAME) << std::endl;
LOG((CLOG_PRINT "%s", buffer.str().c_str())); LOG((CLOG_PRINT "%s", buffer.str().c_str()));

View File

@@ -628,25 +628,25 @@ Unicode::fromUTF8(const UInt8*& data, UInt32& n)
case 4: case 4:
c = ((static_cast<UInt32>(data[0]) & 0x07) << 18) | c = ((static_cast<UInt32>(data[0]) & 0x07) << 18) |
((static_cast<UInt32>(data[1]) & 0x3f) << 12) | ((static_cast<UInt32>(data[1]) & 0x3f) << 12) |
((static_cast<UInt32>(data[1]) & 0x3f) << 6) | ((static_cast<UInt32>(data[2]) & 0x3f) << 6) |
((static_cast<UInt32>(data[1]) & 0x3f) ); ((static_cast<UInt32>(data[3]) & 0x3f) );
break; break;
case 5: case 5:
c = ((static_cast<UInt32>(data[0]) & 0x03) << 24) | c = ((static_cast<UInt32>(data[0]) & 0x03) << 24) |
((static_cast<UInt32>(data[1]) & 0x3f) << 18) | ((static_cast<UInt32>(data[1]) & 0x3f) << 18) |
((static_cast<UInt32>(data[1]) & 0x3f) << 12) | ((static_cast<UInt32>(data[2]) & 0x3f) << 12) |
((static_cast<UInt32>(data[1]) & 0x3f) << 6) | ((static_cast<UInt32>(data[3]) & 0x3f) << 6) |
((static_cast<UInt32>(data[1]) & 0x3f) ); ((static_cast<UInt32>(data[4]) & 0x3f) );
break; break;
case 6: case 6:
c = ((static_cast<UInt32>(data[0]) & 0x01) << 30) | c = ((static_cast<UInt32>(data[0]) & 0x01) << 30) |
((static_cast<UInt32>(data[1]) & 0x3f) << 24) | ((static_cast<UInt32>(data[1]) & 0x3f) << 24) |
((static_cast<UInt32>(data[1]) & 0x3f) << 18) | ((static_cast<UInt32>(data[2]) & 0x3f) << 18) |
((static_cast<UInt32>(data[1]) & 0x3f) << 12) | ((static_cast<UInt32>(data[3]) & 0x3f) << 12) |
((static_cast<UInt32>(data[1]) & 0x3f) << 6) | ((static_cast<UInt32>(data[4]) & 0x3f) << 6) |
((static_cast<UInt32>(data[1]) & 0x3f) ); ((static_cast<UInt32>(data[5]) & 0x3f) );
break; break;
default: default: