diff -Nru kodiplatform-15.0.0/CMakeLists.txt kodiplatform-16.0.0/CMakeLists.txt --- kodiplatform-15.0.0/CMakeLists.txt 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/CMakeLists.txt 2015-05-18 12:43:10.000000000 +0000 @@ -8,6 +8,7 @@ find_package(kodi REQUIRED) find_package(TinyXML REQUIRED) find_package(Threads REQUIRED) +find_package(platform REQUIRED) include(UseMultiArch.cmake) include(CheckAtomic.cmake) @@ -17,12 +18,7 @@ set(kodiplatform_VERSION_MINOR ${APP_VERSION_MINOR}) set(kodiplatform_VERSION_PATCH 0) -if(WIN32) - set(PLAT_SOURCES src/windows/dlfcn-win32.cpp - src/windows/os-threads.cpp - src/windows/serialport.cpp) -else() - set(PLAT_SOURCES src/posix/serialport.cpp) +if(NOT WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") endif() @@ -38,46 +34,17 @@ endif() endif() -set(SOURCES src/util/XMLUtils.cpp - src/util/fstrcmp.c - src/util/StringUtils.cpp) - include_directories(${TINYXML_INCLUDE_DIR} ${KODI_INCLUDE_DIR}) +set(SOURCES src/util/XMLUtils.cpp) + +include_directories(${TINYXML_INCLUDE_DIR} ${KODI_INCLUDE_DIR} ${platform_INCLUDE_DIRS}) add_library(kodiplatform ${SOURCES} ${PLAT_SOURCES}) -target_link_libraries(kodiplatform ${kodiplatform_LIBRARIES}) +target_link_libraries(kodiplatform ${kodiplatform_LIBRARIES} ${platform_LIBRARIES}) set_target_properties(kodiplatform PROPERTIES VERSION ${kodiplatform_VERSION_MAJOR}.${kodiplatform_VERSION_MINOR}.${kodiplatform_VERSION_PATCH} SOVERSION ${kodiplatform_VERSION_MAJOR}.0) install(TARGETS kodiplatform DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(FILES src/os.h DESTINATION include/kodi) -IF(WIN32) - INSTALL(FILES src/windows/dlfcn-win32.h - src/windows/os-socket.h - src/windows/os-threads.h - src/windows/os-types.h - DESTINATION include/kodi/windows) -ELSE(WIN32) - install(FILES src/posix/os-socket.h - src/posix/os-threads.h - src/posix/os-types.h - DESTINATION include/kodi/posix) -ENDIF(WIN32) -install(FILES src/sockets/serialport.h - src/sockets/socket.h - src/sockets/tcp.h - DESTINATION include/kodi/sockets) -install(FILES src/threads/atomics.h - src/threads/mutex.h - src/threads/threads.h - DESTINATION include/kodi/threads) -install(FILES src/util/atomic.h - src/util/baudrate.h - src/util/buffer.h - src/util/StringUtils.h - src/util/StdString.h - src/util/timeutils.h - src/util/util.h - src/util/XMLUtils.h +install(FILES src/util/XMLUtils.h DESTINATION include/kodi/util) IF(NOT WIN32) diff -Nru kodiplatform-15.0.0/debian/changelog kodiplatform-16.0.0/debian/changelog --- kodiplatform-15.0.0/debian/changelog 2015-03-14 12:05:09.000000000 +0000 +++ kodiplatform-16.0.0/debian/changelog 2015-05-18 12:49:02.000000000 +0000 @@ -1,9 +1,28 @@ -kodiplatform (15.0.0-1~precise) precise; urgency=low +kodiplatform (16.0.0-2~precise) precise; urgency=low - [ Nobody ] - * Initial release + [ Lars Op den Kamp ] + * split up into libplatform and libkodiplatform, and removed libCEC-only code [ wsnipex ] * no upstream changelog available - -- wsnipex Sat, 14 Mar 2015 13:05:09 +0100 + -- wsnipex Mon, 18 May 2015 14:49:02 +0200 + +kodiplatform (15.0.0-1~precise) precise; urgency=medium + + * rebrand to kodi + * bump to Isengard + + -- wsnipex Thu, 12 Feb 2015 13:28:01 +0100 + +xbmcplatform (14.0.0-1~precise) precise; urgency=medium + + * bump version + + -- wsnipex Mon, 07 Jul 2014 08:23:48 +0200 + +xbmcplatform (13.0.0-1~precise) precise; urgency=low + + * Initial release + + -- Arne Morten Kvarving Sun, 19 May 2013 02:23:53 +0200 diff -Nru kodiplatform-15.0.0/debian/changelog.in kodiplatform-16.0.0/debian/changelog.in --- kodiplatform-15.0.0/debian/changelog.in 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/debian/changelog.in 2015-05-18 12:43:10.000000000 +0000 @@ -1,5 +1,24 @@ -kodiplatform (15.0.0-1~#DIST#) #DIST#; urgency=low +kodiplatform (16.0.0-#TAGREV#~#DIST#) #DIST#; urgency=medium + + * split up into libplatform and libkodiplatform, and removed libCEC-only code + + -- Lars Op den Kamp Thu, 20 Apr 2015 12:16:17 +0100 + +kodiplatform (15.0.0-1~#DIST#) #DIST#; urgency=medium + + * rebrand to kodi + * bump to Isengard + + -- wsnipex Thu, 12 Feb 2015 13:28:01 +0100 + +xbmcplatform (14.0.0-1~#DIST#) #DIST#; urgency=medium + + * bump version + + -- wsnipex Mon, 07 Jul 2014 08:23:48 +0200 + +xbmcplatform (13.0.0-1~#DIST#) #DIST#; urgency=low * Initial release - -- Nobody Sun, 08 May 2015 11:03:53 +0100 + -- Arne Morten Kvarving Sun, 19 May 2013 02:23:53 +0200 diff -Nru kodiplatform-15.0.0/debian/changelog.tmp kodiplatform-16.0.0/debian/changelog.tmp --- kodiplatform-15.0.0/debian/changelog.tmp 2015-03-14 12:05:01.000000000 +0000 +++ kodiplatform-16.0.0/debian/changelog.tmp 2015-05-18 12:47:27.000000000 +0000 @@ -1,5 +1,24 @@ -kodiplatform (15.0.0-1~#DIST#) #DIST#; urgency=low +kodiplatform (16.0.0-2~#DIST#) #DIST#; urgency=medium + + * split up into libplatform and libkodiplatform, and removed libCEC-only code + + -- Lars Op den Kamp Thu, 20 Apr 2015 12:16:17 +0100 + +kodiplatform (15.0.0-1~#DIST#) #DIST#; urgency=medium + + * rebrand to kodi + * bump to Isengard + + -- wsnipex Thu, 12 Feb 2015 13:28:01 +0100 + +xbmcplatform (14.0.0-1~#DIST#) #DIST#; urgency=medium + + * bump version + + -- wsnipex Mon, 07 Jul 2014 08:23:48 +0200 + +xbmcplatform (13.0.0-1~#DIST#) #DIST#; urgency=low * Initial release - -- Nobody Sun, 08 May 2015 11:03:53 +0100 + -- Arne Morten Kvarving Sun, 19 May 2013 02:23:53 +0200 diff -Nru kodiplatform-15.0.0/debian/control kodiplatform-16.0.0/debian/control --- kodiplatform-15.0.0/debian/control 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/debian/control 2015-05-18 12:43:10.000000000 +0000 @@ -1,7 +1,7 @@ Source: kodiplatform Priority: extra Maintainer: Arne Morten Kvarving -Build-Depends: debhelper (>= 8.0.0), cmake, libtinyxml-dev, kodi-addon-dev +Build-Depends: debhelper (>= 8.0.0), cmake, libtinyxml-dev, kodi-addon-dev, libplatform-dev Standards-Version: 3.9.2 Section: libs @@ -9,16 +9,16 @@ Section: libdevel Architecture: any Multi-Arch: same -Depends: libkodiplatform15 (= ${binary:Version}), libtinyxml-dev +Depends: libkodiplatform16 (= ${binary:Version}), libtinyxml-dev, libplatform-dev Provides: libkodiplatform-dev Description: Kodi platform support library -- development files Kodi platform support library -Package: libkodiplatform15 +Package: libkodiplatform16 Section: libs Architecture: any Multi-Arch: same -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: ${shlibs:Depends}, ${misc:Depends}, libplatform1 Provides: libkodiplatform Description: Kodi platform support library Kodi platform support library diff -Nru kodiplatform-15.0.0/debian/libkodiplatform15.install kodiplatform-16.0.0/debian/libkodiplatform15.install --- kodiplatform-15.0.0/debian/libkodiplatform15.install 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/debian/libkodiplatform15.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*/*.so.* diff -Nru kodiplatform-15.0.0/debian/libkodiplatform16.install kodiplatform-16.0.0/debian/libkodiplatform16.install --- kodiplatform-15.0.0/debian/libkodiplatform16.install 1970-01-01 00:00:00.000000000 +0000 +++ kodiplatform-16.0.0/debian/libkodiplatform16.install 2015-05-18 12:43:10.000000000 +0000 @@ -0,0 +1 @@ +usr/lib/*/*.so.* diff -Nru kodiplatform-15.0.0/src/os.h kodiplatform-16.0.0/src/os.h --- kodiplatform-15.0.0/src/os.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/os.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#if (defined(_WIN32) || defined(_WIN64)) -#include "windows/os-types.h" -#else -#include "posix/os-types.h" -#endif diff -Nru kodiplatform-15.0.0/src/posix/os-socket.h kodiplatform-16.0.0/src/posix/os-socket.h --- kodiplatform-15.0.0/src/posix/os-socket.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/posix/os-socket.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,317 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - - -#include "../os.h" -#include "../util/timeutils.h" -#include -#include -#include -#include -#include -#include -#include -#include - -/* Needed on Mac OS/X */ -#ifndef SOL_TCP -#define SOL_TCP IPPROTO_TCP -#endif - -namespace PLATFORM -{ - // Standard sockets - //@{ - inline void SocketClose(socket_t socket) - { - if (socket != INVALID_SOCKET_VALUE) - close(socket); - } - - inline void SocketSetBlocking(socket_t socket, bool bSetTo) - { - if (socket != INVALID_SOCKET_VALUE) - { - if (bSetTo) - fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK); - else - fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK); - } - } - - inline ssize_t SocketWrite(socket_t socket, int *iError, void* data, size_t len) - { - fd_set port; - - if (socket == INVALID_SOCKET_VALUE) - { - *iError = EINVAL; - return -EINVAL; - } - - ssize_t iBytesWritten(0); - struct timeval *tv(NULL); - - while (iBytesWritten < (ssize_t)len) - { - FD_ZERO(&port); - FD_SET(socket, &port); - int returnv = select(socket + 1, NULL, &port, NULL, tv); - if (returnv < 0) - { - *iError = errno; - return -errno; - } - else if (returnv == 0) - { - *iError = ETIMEDOUT; - return -ETIMEDOUT; - } - - returnv = write(socket, (char*)data + iBytesWritten, len - iBytesWritten); - if (returnv == -1) - { - *iError = errno; - return -errno; - } - iBytesWritten += returnv; - } - - return iBytesWritten; - } - - inline ssize_t SocketRead(socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/) - { - fd_set port; - struct timeval timeout, *tv; - ssize_t iBytesRead(0); - *iError = 0; - CTimeout readTimeout(iTimeoutMs); - - if (socket == INVALID_SOCKET_VALUE) - { - *iError = EINVAL; - return -EINVAL; - } - - while (iBytesRead >= 0 && iBytesRead < (ssize_t)len && (iTimeoutMs == 0 || readTimeout.TimeLeft() > 0)) - { - if (iTimeoutMs == 0) - { - tv = NULL; - } - else - { - long iTimeLeft = (long)readTimeout.TimeLeft(); - timeout.tv_sec = iTimeLeft / (long int)1000.; - timeout.tv_usec = iTimeLeft % (long int)1000.; - tv = &timeout; - } - - FD_ZERO(&port); - FD_SET(socket, &port); - int32_t returnv = select(socket + 1, &port, NULL, NULL, tv); - - if (returnv == -1) - { - *iError = errno; - return -errno; - } - else if (returnv == 0) - { - break; //nothing to read - } - - returnv = read(socket, (char*)data + iBytesRead, len - iBytesRead); - if (returnv == -1) - { - *iError = errno; - return -errno; - } - - iBytesRead += returnv; - } - - return iBytesRead; - } - //@} - - // TCP - //@{ - inline void TcpSocketClose(tcp_socket_t socket) - { - SocketClose(socket); - } - - inline void TcpSocketShutdown(tcp_socket_t socket) - { - if (socket != INVALID_SOCKET_VALUE) - shutdown(socket, SHUT_RDWR); - } - - inline ssize_t TcpSocketWrite(tcp_socket_t socket, int *iError, void* data, size_t len) - { - if (socket == INVALID_SOCKET_VALUE) - { - *iError = EINVAL; - return -1; - } - - ssize_t iReturn = send(socket, data, len, 0); - if (iReturn < (ssize_t)len) - *iError = errno; - return iReturn; - } - - inline ssize_t TcpSocketRead(tcp_socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/) - { - int64_t iNow(0), iTarget(0); - ssize_t iBytesRead(0); - *iError = 0; - - if (socket == INVALID_SOCKET_VALUE) - { - *iError = EINVAL; - return -EINVAL; - } - - if (iTimeoutMs > 0) - { - iNow = GetTimeMs(); - iTarget = iNow + (int64_t) iTimeoutMs; - } - - struct pollfd fds; - fds.fd = socket; - fds.events = POLLIN; - fds.revents = 0; - - while (iBytesRead >= 0 && - iBytesRead < (ssize_t)len && - (iTimeoutMs == 0 || iTarget > iNow) && - *iError == 0) - { - if (iTimeoutMs > 0) - { - int iPollResult = poll(&fds, 1, iTarget - iNow); - if (iPollResult == 0) - *iError = ETIMEDOUT; - } - - ssize_t iReadResult = (iTimeoutMs > 0) ? - recv(socket, (char*)data + iBytesRead, len - iBytesRead, MSG_DONTWAIT) : - recv(socket, data, len, MSG_WAITALL); - if (iReadResult < 0) - { - if (errno == EAGAIN && iTimeoutMs > 0) - continue; - *iError = errno; - return (iBytesRead > 0) ? iBytesRead : -errno; - } - else if (iReadResult == 0 || (iReadResult != (ssize_t)len && iTimeoutMs == 0)) - { - *iError = ECONNRESET; - } - - iBytesRead += iReadResult; - - if (iTimeoutMs > 0) - iNow = GetTimeMs(); - } - - if (iBytesRead < (ssize_t)len && iError == 0) - *iError = ETIMEDOUT; - return iBytesRead; - } - - inline bool TcpResolveAddress(const char *strHost, uint16_t iPort, int *iError, struct addrinfo **info) - { - struct addrinfo hints; - char service[33]; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - sprintf(service, "%d", iPort); - - *iError = getaddrinfo(strHost, service, &hints, info); - return !(*iError); - } - - inline int TcpGetSocketError(tcp_socket_t socket) - { - int iReturn(0); - socklen_t optLen = sizeof(socket_t); - getsockopt(socket, SOL_SOCKET, SO_ERROR, (void *)&iReturn, &optLen); - return iReturn; - } - - inline bool TcpSetNoDelay(tcp_socket_t socket) - { - int iSetTo(1); - setsockopt(socket, SOL_TCP, TCP_NODELAY, &iSetTo, sizeof(iSetTo)); - return true; - } - - inline bool TcpConnectSocket(tcp_socket_t socket, struct addrinfo* addr, int *iError, uint64_t iTimeout = 0) - { - *iError = 0; - int iConnectResult = connect(socket, addr->ai_addr, addr->ai_addrlen); - if (iConnectResult == -1) - { - if (errno == EINPROGRESS) - { - struct pollfd pfd; - pfd.fd = socket; - pfd.events = POLLOUT; - pfd.revents = 0; - - int iPollResult = poll(&pfd, 1, iTimeout); - if (iPollResult == 0) - *iError = ETIMEDOUT; - else if (iPollResult == -1) - *iError = errno; - - socklen_t errlen = sizeof(int); - getsockopt(socket, SOL_SOCKET, SO_ERROR, (void *)iError, &errlen); - } - else - { - *iError = errno; - } - } - - return *iError == 0; - } - //@} -} diff -Nru kodiplatform-15.0.0/src/posix/os-threads.h kodiplatform-16.0.0/src/posix/os-threads.h --- kodiplatform-15.0.0/src/posix/os-threads.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/posix/os-threads.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#if defined(TARGET_DARWIN) -# ifndef PTHREAD_MUTEX_RECURSIVE_NP -# define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE -# endif -#endif - -namespace PLATFORM -{ - inline pthread_mutexattr_t *GetRecursiveMutexAttribute(void) - { - static pthread_mutexattr_t g_mutexAttr; - static bool bAttributeInitialised = false; - if (!bAttributeInitialised) - { - pthread_mutexattr_init(&g_mutexAttr); - pthread_mutexattr_settype(&g_mutexAttr, PTHREAD_MUTEX_RECURSIVE); - bAttributeInitialised = true; - } - return &g_mutexAttr; - } - - inline struct timespec GetAbsTime(uint64_t iIncreaseBy = 0) - { - struct timespec now; - #ifdef __APPLE__ - struct timeval tv; - gettimeofday(&tv, NULL); - now.tv_sec = tv.tv_sec; - now.tv_nsec = tv.tv_usec * 1000; - #else - clock_gettime(CLOCK_REALTIME, &now); - #endif - now.tv_nsec += iIncreaseBy % 1000 * 1000000; - now.tv_sec += iIncreaseBy / 1000 + now.tv_nsec / 1000000000; - now.tv_nsec %= 1000000000; - return now; - } - - typedef pthread_t thread_t; - - inline pthread_attr_t *GetDetachedThreadAttribute(void) - { - static pthread_attr_t g_threadAttr; - static bool bAttributeInitialised = false; - if (!bAttributeInitialised) - { - pthread_attr_init(&g_threadAttr); - pthread_attr_setdetachstate(&g_threadAttr, PTHREAD_CREATE_DETACHED); - bAttributeInitialised = true; - } - return &g_threadAttr; - } - - #define ThreadsCreate(thread, func, arg) (pthread_create(&thread, GetDetachedThreadAttribute(), (void *(*) (void *))func, (void *)arg) == 0) - #define ThreadsWait(thread, retval) (pthread_join(thread, retval) == 0) - - typedef pthread_mutex_t mutex_t; - #define MutexCreate(mutex) pthread_mutex_init(&mutex, GetRecursiveMutexAttribute()); - #define MutexDelete(mutex) pthread_mutex_destroy(&mutex); - #define MutexLock(mutex) (pthread_mutex_lock(&mutex) == 0) - #define MutexTryLock(mutex) (pthread_mutex_trylock(&mutex) == 0) - #define MutexUnlock(mutex) pthread_mutex_unlock(&mutex) - - class CConditionImpl - { - public: - CConditionImpl(void) - { - pthread_cond_init(&m_condition, NULL); - } - - virtual ~CConditionImpl(void) - { - pthread_cond_destroy(&m_condition); - } - - void Signal(void) - { - pthread_cond_signal(&m_condition); - } - - void Broadcast(void) - { - pthread_cond_broadcast(&m_condition); - } - - bool Wait(mutex_t &mutex) - { - sched_yield(); - return (pthread_cond_wait(&m_condition, &mutex) == 0); - } - - bool Wait(mutex_t &mutex, uint32_t iTimeoutMs) - { - if (iTimeoutMs == 0) - return Wait(mutex); - - sched_yield(); - struct timespec timeout = GetAbsTime(iTimeoutMs); - return (pthread_cond_timedwait(&m_condition, &mutex, &timeout) == 0); - } - - pthread_cond_t m_condition; - }; -} diff -Nru kodiplatform-15.0.0/src/posix/os-types.h kodiplatform-16.0.0/src/posix/os-types.h --- kodiplatform-15.0.0/src/posix/os-types.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/posix/os-types.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,184 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#define _FILE_OFFSET_BITS 64 -#include -#include -#include -#include -#if !defined(__APPLE__) && !defined(__FreeBSD__) -#include -#endif -#include -#include -#include -#include - -#include -#include -#include -#include - -#define LIBTYPE -#define DECLSPEC - -typedef int socket_t; -typedef socket_t tcp_socket_t; -#define INVALID_SOCKET_VALUE (-1) -typedef socket_t serial_socket_t; -#define INVALID_SERIAL_SOCKET_VALUE (-1) - -typedef long LONG; -typedef LONG HRESULT; - -#define _FILE_OFFSET_BITS 64 -#define FILE_BEGIN 0 -#define FILE_CURRENT 1 -#define FILE_END 2 - -// Success codes -#define S_OK 0L -#define S_FALSE 1L -#define FAILED(Status) ((HRESULT)(Status)<0) -#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) - -// Error codes -#define ERROR_FILENAME_EXCED_RANGE 206L -#define ERROR_INVALID_NAME 123L -#define E_OUTOFMEMORY 0x8007000EL -#define E_FAIL 0x8004005EL - -#ifdef TARGET_LINUX -#include -#define MAX_PATH PATH_MAX -#elif defined TARGET_DARWIN || defined __FreeBSD__ -#include -#define MAX_PATH PATH_MAX -#else -#define MAX_PATH 256 -#endif - -#if defined(__APPLE__) - #include // for fpos_t - #include - #include - typedef int64_t off64_t; - typedef off_t __off_t; - typedef off64_t __off64_t; - typedef fpos_t fpos64_t; - #define __stat64 stat - #define stat64 stat - #if defined(TARGET_DARWIN_IOS) - #define statfs64 statfs - #endif - #define fstat64 fstat -#elif defined(__FreeBSD__) - #include // for fpos_t - typedef int64_t off64_t; - typedef off_t __off_t; - typedef off64_t __off64_t; - typedef fpos_t fpos64_t; - #define __stat64 stat - #define stat64 stat - #define statfs64 statfs - #define fstat64 fstat -#else - #define __stat64 stat64 -#endif - -#include -#define strnicmp(X,Y,N) strncasecmp(X,Y,N) - -typedef unsigned char byte; - -/* Platform dependent path separator */ -#ifndef PATH_SEPARATOR_CHAR -#define PATH_SEPARATOR_CHAR '/' -#define PATH_SEPARATOR_STRING "/" -#endif - -#ifdef TARGET_LINUX -// Retrieve the number of milliseconds that have elapsed since the system was started -#include -inline unsigned long GetTickCount(void) -{ - struct timespec ts; - if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) - { - return 0; - } - return (unsigned long)( (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000) ); -}; -#else -#include -inline unsigned long GetTickCount(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (unsigned long)( (tv.tv_sec * 1000) + (tv.tv_usec / 1000) ); -}; -#endif /* TARGET_LINUX || TARGET_DARWIN */ - -/* Handling of 2-byte Windows wchar strings on non-Windows targets - * Used by The MediaPortal and ForTheRecord pvr addons - */ -typedef uint16_t Wchar_t; /* sizeof(wchar_t) = 4 bytes on Linux, but the MediaPortal buffer files have 2-byte wchars */ - -/* This is a replacement of the Windows wcslen() function which assumes that - * wchar_t is a 2-byte character. - * It is used for processing Windows wchar strings - */ -inline size_t WcsLen(const Wchar_t *str) -{ - const unsigned short *eos = (const unsigned short*)str; - while( *eos++ ) ; - return( (size_t)(eos - (const unsigned short*)str) -1); -}; - -/* This is a replacement of the Windows wcstombs() function which assumes that - * wchar_t is a 2-byte character. - * It is used for processing Windows wchar strings - */ -inline size_t WcsToMbs(char *s, const Wchar_t *w, size_t n) -{ - size_t i = 0; - const unsigned short *wc = (const unsigned short*) w; - while(wc[i] && (i < n)) - { - s[i] = wc[i]; - ++i; - } - if (i < n) s[i] = '\0'; - - return (i); -}; diff -Nru kodiplatform-15.0.0/src/posix/serialport.cpp kodiplatform-16.0.0/src/posix/serialport.cpp --- kodiplatform-15.0.0/src/posix/serialport.cpp 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/posix/serialport.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../os.h" -#include -#include -#include "../sockets/serialport.h" -#include "../util/baudrate.h" -#include "../posix/os-socket.h" - -#if defined(__APPLE__) || defined(__FreeBSD__) -#ifndef XCASE -#define XCASE 0 -#endif -#ifndef OLCUC -#define OLCUC 0 -#endif -#ifndef IUCLC -#define IUCLC 0 -#endif -#endif -using namespace std; -using namespace PLATFORM; - -void CSerialSocket::Close(void) -{ - if (IsOpen()) - SocketClose(m_socket); -} - -void CSerialSocket::Shutdown(void) -{ - if (IsOpen()) - SocketClose(m_socket); -} - -ssize_t CSerialSocket::Write(void* data, size_t len) -{ - return IsOpen() ? SocketWrite(m_socket, &m_iError, data, len) : -1; -} - -ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 */) -{ - return IsOpen() ? SocketRead(m_socket, &m_iError, data, len, iTimeoutMs) : -1; -} - -//setting all this stuff up is a pain in the ass -bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) -{ - iTimeoutMs = 0; - if (IsOpen()) - return false; - - if (m_iDatabits != SERIAL_DATA_BITS_FIVE && m_iDatabits != SERIAL_DATA_BITS_SIX && - m_iDatabits != SERIAL_DATA_BITS_SEVEN && m_iDatabits != SERIAL_DATA_BITS_EIGHT) - { - m_strError = "Databits has to be between 5 and 8"; - return false; - } - - if (m_iStopbits != SERIAL_STOP_BITS_ONE && m_iStopbits != SERIAL_STOP_BITS_TWO) - { - m_strError = "Stopbits has to be 1 or 2"; - return false; - } - - if (m_iParity != SERIAL_PARITY_NONE && m_iParity != SERIAL_PARITY_EVEN && m_iParity != SERIAL_PARITY_ODD) - { - m_strError = "Parity has to be none, even or odd"; - return false; - } - - m_socket = open(m_strName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); - - if (m_socket == INVALID_SERIAL_SOCKET_VALUE) - { - m_strError = strerror(errno); - return false; - } - - SocketSetBlocking(m_socket, false); - - if (!SetBaudRate(m_iBaudrate)) - return false; - - m_options.c_cflag |= (CLOCAL | CREAD); - m_options.c_cflag &= ~HUPCL; - - m_options.c_cflag &= ~CSIZE; - if (m_iDatabits == SERIAL_DATA_BITS_FIVE) m_options.c_cflag |= CS5; - if (m_iDatabits == SERIAL_DATA_BITS_SIX) m_options.c_cflag |= CS6; - if (m_iDatabits == SERIAL_DATA_BITS_SEVEN) m_options.c_cflag |= CS7; - if (m_iDatabits == SERIAL_DATA_BITS_EIGHT) m_options.c_cflag |= CS8; - - m_options.c_cflag &= ~PARENB; - if (m_iParity == SERIAL_PARITY_EVEN || m_iParity == SERIAL_PARITY_ODD) - m_options.c_cflag |= PARENB; - if (m_iParity == SERIAL_PARITY_ODD) - m_options.c_cflag |= PARODD; - -#ifdef CRTSCTS - m_options.c_cflag &= ~CRTSCTS; -#elif defined(CNEW_RTSCTS) - m_options.c_cflag &= ~CNEW_RTSCTS; -#endif - - if (m_iStopbits == SERIAL_STOP_BITS_ONE) m_options.c_cflag &= ~CSTOPB; - else m_options.c_cflag |= CSTOPB; - - //I guessed a little here - m_options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | XCASE | ECHOK | ECHONL | ECHOCTL | ECHOPRT | ECHOKE | TOSTOP); - - if (m_iParity == SERIAL_PARITY_NONE) - m_options.c_iflag &= ~INPCK; - else - m_options.c_iflag |= INPCK | ISTRIP; - - m_options.c_iflag &= ~(IXON | IXOFF | IXANY | BRKINT | INLCR | IGNCR | ICRNL | IUCLC | IMAXBEL); - m_options.c_oflag &= ~(OPOST | ONLCR | OCRNL); - - if (tcsetattr(m_socket, TCSANOW, &m_options) != 0) - { - m_strError = strerror(errno); - return false; - } - - SocketSetBlocking(m_socket, true); - m_bIsOpen = true; - - return true; -} - -bool CSerialSocket::SetBaudRate(uint32_t baudrate) -{ - int rate = IntToBaudrate(baudrate); - if (rate == -1) - { - char buff[255]; - sprintf(buff, "%i is not a valid baudrate", baudrate); - m_strError = buff; - return false; - } - - //get the current port attributes - if (tcgetattr(m_socket, &m_options) != 0) - { - m_strError = strerror(errno); - return false; - } - - if (cfsetispeed(&m_options, rate) != 0) - { - m_strError = strerror(errno); - return false; - } - - if (cfsetospeed(&m_options, rate) != 0) - { - m_strError = strerror(errno); - return false; - } - - return true; -} diff -Nru kodiplatform-15.0.0/src/sockets/serialport.h kodiplatform-16.0.0/src/sockets/serialport.h --- kodiplatform-15.0.0/src/sockets/serialport.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/sockets/serialport.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../os.h" -#include "../util/buffer.h" - -#include -#include - -#if !defined(__WINDOWS__) -#include -#endif - -#include "socket.h" - -namespace PLATFORM -{ - enum SerialParity - { - SERIAL_PARITY_NONE = 0, - SERIAL_PARITY_EVEN, - SERIAL_PARITY_ODD - }; - - enum SerialStopBits - { - SERIAL_STOP_BITS_ONE = 1, - SERIAL_STOP_BITS_TWO = 2 - }; - - enum SerialDataBits - { - SERIAL_DATA_BITS_FIVE = 5, - SERIAL_DATA_BITS_SIX = 6, - SERIAL_DATA_BITS_SEVEN = 7, - SERIAL_DATA_BITS_EIGHT = 8 - }; - - class CSerialSocket : public CCommonSocket - { - public: - CSerialSocket(const CStdString &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) : - CCommonSocket(INVALID_SERIAL_SOCKET_VALUE, strName), - m_bIsOpen(false), - m_iBaudrate(iBaudrate), - m_iDatabits(iDatabits), - m_iStopbits(iStopbits), - m_iParity(iParity) {} - - virtual ~CSerialSocket(void) { Close(); } - - virtual bool Open(uint64_t iTimeoutMs = 0); - virtual void Close(void); - virtual void Shutdown(void); - virtual ssize_t Write(void* data, size_t len); - virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0); - - virtual bool IsOpen(void) - { - return m_socket != INVALID_SERIAL_SOCKET_VALUE && - m_bIsOpen; - } - - virtual bool SetBaudRate(uint32_t baudrate); - - protected: - #ifndef __WINDOWS__ - struct termios m_options; - #endif - - bool m_bIsOpen; - uint32_t m_iBaudrate; - SerialDataBits m_iDatabits; - SerialStopBits m_iStopbits; - SerialParity m_iParity; - }; - - class CSerialPort : public CProtectedSocket - { - public: - CSerialPort(const CStdString &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) : - CProtectedSocket (new CSerialSocket(strName, iBaudrate, iDatabits, iStopbits, iParity)) {} - virtual ~CSerialPort(void) {} - }; -}; diff -Nru kodiplatform-15.0.0/src/sockets/socket.h kodiplatform-16.0.0/src/sockets/socket.h --- kodiplatform-15.0.0/src/sockets/socket.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/sockets/socket.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../threads/mutex.h" -#include "../util/StdString.h" - -#if defined(__WINDOWS__) -#include "../windows/os-socket.h" -#else -#include "../posix/os-socket.h" -#endif - -// Common socket operations - -namespace PLATFORM -{ - class ISocket : public PreventCopy - { - public: - ISocket(void) {}; - virtual ~ISocket(void) {} - - virtual bool Open(uint64_t iTimeoutMs = 0) = 0; - virtual void Close(void) = 0; - virtual void Shutdown(void) = 0; - virtual bool IsOpen(void) = 0; - virtual ssize_t Write(void* data, size_t len) = 0; - virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) = 0; - virtual CStdString GetError(void) = 0; - virtual int GetErrorNumber(void) = 0; - virtual CStdString GetName(void) = 0; - }; - - template - class CCommonSocket : public ISocket - { - public: - CCommonSocket(_SType initialSocketValue, const CStdString &strName) : - m_socket(initialSocketValue), - m_strName(strName), - m_iError(0) {} - - virtual ~CCommonSocket(void) {} - - virtual CStdString GetError(void) - { - CStdString strError; - strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError; - return strError; - } - - virtual int GetErrorNumber(void) - { - return m_iError; - } - - virtual CStdString GetName(void) - { - CStdString strName; - strName = m_strName; - return strName; - } - - protected: - _SType m_socket; - CStdString m_strError; - CStdString m_strName; - int m_iError; - CMutex m_mutex; - }; - - template - class CProtectedSocket : public ISocket - { - public: - CProtectedSocket(_Socket *socket) : - m_socket(socket), - m_bIsIdle(true) {} - - virtual ~CProtectedSocket(void) - { - delete m_socket; - } - - virtual bool Open(uint64_t iTimeoutMs = 0) - { - bool bReturn(false); - if (m_socket && WaitReady()) - { - bReturn = m_socket->Open(iTimeoutMs); - MarkReady(); - } - return bReturn; - } - - virtual void Close(void) - { - if (m_socket && WaitReady()) - { - m_socket->Close(); - MarkReady(); - } - } - - virtual void Shutdown(void) - { - CLockObject lock(m_mutex); - if (m_socket) - { - m_socket->Shutdown(); - } - } - - virtual bool IsOpen(void) - { - CLockObject lock(m_mutex); - return m_socket && m_socket->IsOpen(); - } - - virtual bool IsBusy(void) - { - CLockObject lock(m_mutex); - return m_socket && !m_bIsIdle; - } - - virtual bool IsIdle(void) - { - CLockObject lock(m_mutex); - return m_socket && m_bIsIdle; - } - - virtual ssize_t Write(void* data, size_t len) - { - if (!m_socket || !WaitReady()) - return -EINVAL; - - ssize_t iReturn = m_socket->Write(data, len); - MarkReady(); - - return iReturn; - } - - virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) - { - if (!m_socket || !WaitReady()) - return -EINVAL; - - ssize_t iReturn = m_socket->Read(data, len, iTimeoutMs); - MarkReady(); - - return iReturn; - } - - virtual CStdString GetError(void) - { - CStdString strError; - CLockObject lock(m_mutex); - strError = m_socket ? m_socket->GetError() : ""; - return strError; - } - - virtual int GetErrorNumber(void) - { - CLockObject lock(m_mutex); - return m_socket ? m_socket->GetErrorNumber() : -EINVAL; - } - - virtual CStdString GetName(void) - { - CStdString strName; - CLockObject lock(m_mutex); - strName = m_socket ? m_socket->GetName() : ""; - return strName; - } - - private: - bool WaitReady(void) - { - CLockObject lock(m_mutex); - m_condition.Wait(m_mutex, m_bIsIdle); - m_bIsIdle = false; - return true; - } - - void MarkReady(void) - { - CLockObject lock(m_mutex); - m_bIsIdle = true; - m_condition.Signal(); - } - - _Socket * m_socket; - CMutex m_mutex; - CCondition m_condition; - bool m_bIsIdle; - }; -}; diff -Nru kodiplatform-15.0.0/src/sockets/tcp.h kodiplatform-16.0.0/src/sockets/tcp.h --- kodiplatform-15.0.0/src/sockets/tcp.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/sockets/tcp.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "socket.h" - - -namespace PLATFORM -{ - class CTcpSocket : public CCommonSocket - { - public: - CTcpSocket(const CStdString &strHostname, uint16_t iPort) : - CCommonSocket(INVALID_SOCKET_VALUE, strHostname), - m_iPort(iPort) {} - - virtual ~CTcpSocket(void) { Close(); } - - virtual bool Open(uint64_t iTimeoutMs = 0) - { - bool bReturn(false); - struct addrinfo *address(NULL), *addr(NULL); - m_strError.clear(); - m_iError = 0; - if (!TcpResolveAddress(m_strName.c_str(), m_iPort, &m_iError, &address)) - { - m_strError = strerror(m_iError); - return bReturn; - } - - for(addr = address; !bReturn && addr; addr = addr->ai_next) - { - m_socket = TcpCreateSocket(addr, &m_iError); - if (m_socket != INVALID_SOCKET_VALUE) - { - if (!TcpConnectSocket(m_socket, addr, &m_iError, iTimeoutMs)) - { - TcpSocketClose(m_socket); - m_strError = strerror(m_iError); - m_socket = INVALID_SOCKET_VALUE; - } - else - { - TcpSetNoDelay(m_socket); - bReturn = true; - } - } - else - m_strError = strerror(m_iError); - } - - freeaddrinfo(address); - return bReturn; - } - - virtual void Close(void) - { - TcpSocketClose(m_socket); - m_socket = INVALID_SOCKET_VALUE; - } - - virtual void Shutdown(void) - { - TcpSocketShutdown(m_socket); - TcpSocketClose(m_socket); - m_socket = INVALID_SOCKET_VALUE; - } - - virtual ssize_t Write(void* data, size_t len) - { - return TcpSocketWrite(m_socket, &m_iError, data, len); - } - - virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) - { - return TcpSocketRead(m_socket, &m_iError, data, len, iTimeoutMs); - } - - virtual bool IsOpen(void) - { - return m_socket != INVALID_SOCKET_VALUE; - } - - protected: - virtual tcp_socket_t TcpCreateSocket(struct addrinfo* addr, int* iError) - { - tcp_socket_t fdSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (fdSock == INVALID_SOCKET_VALUE) - { - *iError = errno; - return (tcp_socket_t)INVALID_SOCKET_VALUE; - } - - return fdSock; - } - - uint16_t m_iPort; - }; - - class CTcpConnection : public CProtectedSocket - { - public: - CTcpConnection(const CStdString &strHostname, uint16_t iPort) : - CProtectedSocket (new CTcpSocket(strHostname, iPort)) {} - virtual ~CTcpConnection(void) {} - }; -}; diff -Nru kodiplatform-15.0.0/src/threads/atomics.h kodiplatform-16.0.0/src/threads/atomics.h --- kodiplatform-15.0.0/src/threads/atomics.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/threads/atomics.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,463 +0,0 @@ -#pragma once -/* - * Copyright (C) 2015 Team XBMC - * http://kodi.tv - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "../os.h" - -namespace PLATFORM -{ - /////////////////////////////////////////////////////////////////////////// - // 32-bit atomic compare-and-swap - // Returns previous value of *pAddr - /////////////////////////////////////////////////////////////////////////// - static inline long cas(volatile long *pAddr, long expectedVal, long swapVal) - { -#if defined(HAS_BUILTIN_SYNC_VAL_COMPARE_AND_SWAP) - return(__sync_val_compare_and_swap(pAddr, expectedVal, swapVal)); -#elif defined(__ppc__) || defined(__powerpc__) // PowerPC - unsigned int prev; - __asm__ __volatile__ ( - " 1: lwarx %0,0,%2 \n" /* Load the current value of *pAddr(%2) into prev (%0) and lock pAddr, */ - " cmpw 0,%0,%3 \n" /* Verify that the current value (%2) == old value (%3) */ - " bne- 2f \n" /* Bail if the two values are not equal [not as expected] */ - " stwcx. %4,0,%2 \n" /* Attempt to store swapVal (%4) value into *pAddr (%2) [p must still be reserved] */ - " bne- 1b \n" /* Loop if p was no longer reserved */ - " isync \n" /* Reconcile multiple processors [if present] */ - " 2: \n" - : "=&r" (prev), "+m" (*pAddr) /* Outputs [prev, *pAddr] */ - : "r" (pAddr), "r" (expectedVal), "r" (swapVal) /* Inputs [pAddr, expectedVal, swapVal] */ - : "cc", "memory"); /* Clobbers */ - return prev; - -#elif defined(__arm__) - register long prev; - asm volatile ( - "dmb ish \n" // Memory barrier. Make sure all memory accesses appearing before this complete before any that appear after - "1: \n" - "ldrex %0, [%1] \n" // Load the current value of *pAddr(%1) into prev (%0) and lock pAddr, - "cmp %0, %2 \n" // Verify that the current value (%0) == old value (%2) - "bne 2f \n" // Bail if the two values are not equal [not as expected] - "strex r1, %3, [%1] \n" - "cmp r1, #0 \n" - "bne 1b \n" - "dmb ish \n" // Memory barrier. - "2: \n" - : "=&r" (prev) - : "r"(pAddr), "r"(expectedVal),"r"(swapVal) - : "r1" - ); - return prev; - -#elif defined(__mips__) - // TODO: - unsigned int prev; - #error atomic cas undefined for mips - return prev; - -#elif defined(__WINDOWS__) - long prev; - __asm - { - // Load parameters - mov eax, expectedVal ; - mov ebx, pAddr ; - mov ecx, swapVal ; - - // Do Swap - lock cmpxchg dword ptr [ebx], ecx ; - - // Store the return value - mov prev, eax; - } - return prev; - -#else // Linux / OSX86 (GCC) - long prev; - __asm__ __volatile__ ( - "lock/cmpxchg %1, %2" - : "=a" (prev) - : "r" (swapVal), "m" (*pAddr), "0" (expectedVal) - : "memory" ); - return prev; - -#endif - } - -#if !defined(__ppc__) && !defined(__powerpc__) && !defined(__arm__) - /////////////////////////////////////////////////////////////////////////// - // 64-bit atomic compare-and-swap - // Returns previous value of *pAddr - /////////////////////////////////////////////////////////////////////////// - static inline long long cas2(volatile long long* pAddr, long long expectedVal, long long swapVal) - { - #if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || defined(__mips__) // PowerPC, ARM, and MIPS - // Not available/required - // Hack to allow compilation - throw "cas2 is not implemented"; - - #elif defined(__WINDOWS__) - long long prev; - __asm - { - mov esi, pAddr ; - mov eax, dword ptr [expectedVal] ; - mov edx, dword ptr expectedVal[4] ; - mov ebx, dword ptr [swapVal] ; - mov ecx, dword ptr swapVal[4] ; - lock cmpxchg8b qword ptr [esi] ; - mov dword ptr [prev], eax ; - mov dword ptr prev[4], edx ; - } - return prev; - - #else // Linux / OSX86 (GCC) - #if !defined (__x86_64) - long long prev; - __asm__ volatile ( - " push %%ebx \n" // We have to manually handle ebx, because PIC uses it and the compiler refuses to build anything that touches it - " mov %4, %%ebx \n" - " lock/cmpxchg8b (%%esi) \n" - " pop %%ebx" - : "=A" (prev) - : "c" ((unsigned long)(swapVal >> 32)), "0" (expectedVal), "S" (pAddr), "m" (swapVal) - : "memory"); - return prev; - #else - // Hack to allow compilation on x86_64 - throw "cas2 is not implemented on x86_64!"; - #endif - #endif - } -#endif - - /////////////////////////////////////////////////////////////////////////// - // 32-bit atomic increment - // Returns new value of *pAddr - /////////////////////////////////////////////////////////////////////////// - static inline long atomic_inc(volatile long* pAddr) - { -#if defined(HAS_BUILTIN_SYNC_ADD_AND_FETCH) - return __sync_add_and_fetch(pAddr, 1); - -#elif defined(__ppc__) || defined(__powerpc__) // PowerPC - long val; - __asm__ __volatile__ ( - "sync \n" - "1: lwarx %0, 0, %1 \n" - "addic %0, %0, 1 \n" - "stwcx. %0, 0, %1 \n" - "bne- 1b \n" - "isync" - : "=&r" (val) - : "r" (pAddr) - : "cc", "xer", "memory"); - return val; - -#elif defined(__arm__) && !defined(__ARM_ARCH_5__) - register long val; - asm volatile ( - "dmb ish \n" // Memory barrier. Make sure all memory accesses appearing before this complete before any that appear after - "1: \n" - "ldrex %0, [%1] \n" // (val = *pAddr) - "add %0, #1 \n" // (val += 1) - "strex r1, %0, [%1] \n" - "cmp r1, #0 \n" - "bne 1b \n" - "dmb ish \n" // Memory barrier. - : "=&r" (val) - : "r"(pAddr) - : "r1" - ); - return val; - -#elif defined(__mips__) - // TODO: - long val; - #error AtomicIncrement undefined for mips - return val; - -#elif defined(__WINDOWS__) - long val; - __asm - { - mov eax, pAddr ; - lock inc dword ptr [eax] ; - mov eax, [eax] ; - mov val, eax ; - } - return val; - -#elif defined(__x86_64__) - register long result; - __asm__ __volatile__ ( - "lock/xaddq %q0, %1" - : "=r" (result), "=m" (*pAddr) - : "0" ((long) (1)), "m" (*pAddr)); - return *pAddr; - -#else // Linux / OSX86 (GCC) - register long reg __asm__ ("eax") = 1; - __asm__ __volatile__ ( - "lock/xadd %0, %1 \n" - "inc %%eax" - : "+r" (reg) - : "m" (*pAddr) - : "memory" ); - return reg; - -#endif - } - - /////////////////////////////////////////////////////////////////////////// - // 32-bit atomic decrement - // Returns new value of *pAddr - /////////////////////////////////////////////////////////////////////////// - static inline long atomic_dec(volatile long* pAddr) - { -#if defined(HAS_BUILTIN_SYNC_SUB_AND_FETCH) - return __sync_sub_and_fetch(pAddr, 1); - -#elif defined(__ppc__) || defined(__powerpc__) // PowerPC - long val; - __asm__ __volatile__ ( - "sync \n" - "1: lwarx %0, 0, %1 \n" - "addic %0, %0, -1 \n" - "stwcx. %0, 0, %1 \n" - "bne- 1b \n" - "isync" - : "=&r" (val) - : "r" (pAddr) - : "cc", "xer", "memory"); - return val; - -#elif defined(__arm__) - register long val; - asm volatile ( - "dmb ish \n" // Memory barrier. Make sure all memory accesses appearing before this complete before any that appear after - "1: \n" - "ldrex %0, [%1] \n" // (val = *pAddr) - "sub %0, #1 \n" // (val -= 1) - "strex r1, %0, [%1] \n" - "cmp r1, #0 \n" - "bne 1b \n" - "dmb ish \n" // Memory barrier. - : "=&r" (val) - : "r"(pAddr) - : "r1" - ); - return val; - -#elif defined(__mips__) - // TODO: - long val; - #error AtomicDecrement undefined for mips - return val; - -#elif defined(__WINDOWS__) - long val; - __asm - { - mov eax, pAddr ; - lock dec dword ptr [eax] ; - mov eax, [eax] ; - mov val, eax ; - } - return val; - -#elif defined(__x86_64__) - register long result; - __asm__ __volatile__ ( - "lock/xaddq %q0, %1" - : "=r" (result), "=m" (*pAddr) - : "0" ((long) (-1)), "m" (*pAddr)); - return *pAddr; - -#else // Linux / OSX86 (GCC) - register long reg __asm__ ("eax") = -1; - __asm__ __volatile__ ( - "lock/xadd %0, %1 \n" - "dec %%eax" - : "+r" (reg) - : "m" (*pAddr) - : "memory" ); - return reg; - -#endif - } - - /////////////////////////////////////////////////////////////////////////// - // 32-bit atomic add - // Returns new value of *pAddr - /////////////////////////////////////////////////////////////////////////// - static inline long atomic_add(volatile long* pAddr, long amount) - { -#if defined(HAS_BUILTIN_SYNC_ADD_AND_FETCH) - return __sync_add_and_fetch(pAddr, amount); - -#elif defined(__ppc__) || defined(__powerpc__) // PowerPC - long val; - __asm__ __volatile__ ( - "sync \n" - "1: lwarx %0, 0, %1 \n" - "add %0, %2, %0 \n" - "stwcx. %0, 0, %1 \n" - "bne- 1b \n" - "isync" - : "=&r" (val) - : "r" (pAddr), "r" (amount) - : "cc", "memory"); - return val; - -#elif defined(__arm__) && !defined(__ARM_ARCH_5__) - register long val; - asm volatile ( - "dmb ish \n" // Memory barrier. Make sure all memory accesses appearing before this complete before any that appear after - "1: \n" - "ldrex %0, [%1] \n" // (val = *pAddr) - "add %0, %2 \n" // (val += amount) - "strex r1, %0, [%1] \n" - "cmp r1, #0 \n" - "bne 1b \n" - "dmb ish \n" // Memory barrier. - : "=&r" (val) - : "r"(pAddr), "r"(amount) - : "r1" - ); - return val; - -#elif defined(__mips__) - // TODO: - long val; - #error AtomicAdd undefined for mips - return val; - -#elif defined(__WINDOWS__) - __asm - { - mov eax, amount; - mov ebx, pAddr; - lock xadd dword ptr [ebx], eax; - mov ebx, [ebx]; - mov amount, ebx; - } - return amount; - -#elif defined(__x86_64__) - register long result; - __asm__ __volatile__ ( - "lock/xaddq %q0, %1" - : "=r" (result), "=m" (*pAddr) - : "0" ((long) (amount)), "m" (*pAddr)); - return *pAddr; - -#else // Linux / OSX86 (GCC) - register long reg __asm__ ("eax") = amount; - __asm__ __volatile__ ( - "lock/xadd %0, %1 \n" - "dec %%eax" - : "+r" (reg) - : "m" (*pAddr) - : "memory" ); - return reg; - -#endif - } - - /////////////////////////////////////////////////////////////////////////// - // 32-bit atomic subtract - // Returns new value of *pAddr - /////////////////////////////////////////////////////////////////////////// - static inline long atomic_sub(volatile long* pAddr, long amount) - { -#if defined(HAS_BUILTIN_SYNC_SUB_AND_FETCH) - return __sync_sub_and_fetch(pAddr, amount); - -#elif defined(__ppc__) || defined(__powerpc__) // PowerPC - long val; - amount *= -1; - __asm__ __volatile__ ( - "sync \n" - "1: lwarx %0, 0, %1 \n" - "add %0, %2, %0 \n" - "stwcx. %0, 0, %1 \n" - "bne- 1b \n" - "isync" - : "=&r" (val) - : "r" (pAddr), "r" (amount) - : "cc", "memory"); - return val; - -#elif defined(__arm__) - register long val; - asm volatile ( - "dmb ish \n" // Memory barrier. Make sure all memory accesses appearing before this complete before any that appear after - "1: \n" - "ldrex %0, [%1] \n" // (val = *pAddr) - "sub %0, %2 \n" // (val -= amount) - "strex r1, %0, [%1] \n" - "cmp r1, #0 \n" - "bne 1b \n" - "dmb ish \n" // Memory barrier. - : "=&r" (val) - : "r"(pAddr), "r"(amount) - : "r1" - ); - return val; - -#elif defined(__mips__) - // TODO: - #error AtomicSubtract undefined for mips - return val; - -#elif defined(__WINDOWS__) - amount *= -1; - __asm - { - mov eax, amount; - mov ebx, pAddr; - lock xadd dword ptr [ebx], eax; - mov ebx, [ebx]; - mov amount, ebx; - } - return amount; - -#elif defined(__x86_64__) - register long result; - __asm__ __volatile__ ( - "lock/xaddq %q0, %1" - : "=r" (result), "=m" (*pAddr) - : "0" ((long) (-1 * amount)), "m" (*pAddr)); - return *pAddr; - -#else // Linux / OSX86 (GCC) - register long reg __asm__ ("eax") = -1 * amount; - __asm__ __volatile__ ( - "lock/xadd %0, %1 \n" - "dec %%eax" - : "+r" (reg) - : "m" (*pAddr) - : "memory" ); - return reg; - -#endif - - } -} diff -Nru kodiplatform-15.0.0/src/threads/mutex.h kodiplatform-16.0.0/src/threads/mutex.h --- kodiplatform-15.0.0/src/threads/mutex.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/threads/mutex.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,360 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../os.h" - -#if defined(__WINDOWS__) -#include "../windows/os-threads.h" -#else -#include "../posix/os-threads.h" -#endif - -#include "../util/timeutils.h" - -namespace PLATFORM -{ - class PreventCopy - { - public: - inline PreventCopy(void) {} - inline ~PreventCopy(void) {} - - private: - inline PreventCopy(const PreventCopy &c) { *this = c; } - inline PreventCopy &operator=(const PreventCopy &c){ *this = c; return *this; } - }; - - template - class CCondition; - - class CMutex : public PreventCopy - { - template - friend class CCondition; - public: - inline CMutex(void) : - m_iLockCount(0) - { - MutexCreate(m_mutex); - } - - inline ~CMutex(void) - { - Clear(); - MutexDelete(m_mutex); - } - - inline bool TryLock(void) - { - if (MutexTryLock(m_mutex)) - { - ++m_iLockCount; - return true; - } - return false; - } - - inline bool Lock(void) - { - MutexLock(m_mutex); - ++m_iLockCount; - return true; - } - - inline void Unlock(void) - { - if (Lock()) - { - if (m_iLockCount >= 2) - { - --m_iLockCount; - MutexUnlock(m_mutex); - } - - --m_iLockCount; - MutexUnlock(m_mutex); - } - } - - inline bool Clear(void) - { - bool bReturn(false); - if (TryLock()) - { - unsigned int iLockCount = m_iLockCount; - for (unsigned int iPtr = 0; iPtr < iLockCount; iPtr++) - Unlock(); - bReturn = true; - } - return bReturn; - } - - private: - mutex_t m_mutex; - volatile unsigned int m_iLockCount; - }; - - class CLockObject : public PreventCopy - { - public: - inline CLockObject(CMutex &mutex, bool bClearOnExit = false) : - m_mutex(mutex), - m_bClearOnExit(bClearOnExit) - { - m_mutex.Lock(); - } - - inline ~CLockObject(void) - { - if (m_bClearOnExit) - Clear(); - else - Unlock(); - } - - inline bool TryLock(void) - { - return m_mutex.TryLock(); - } - - inline void Unlock(void) - { - m_mutex.Unlock(); - } - - inline bool Clear(void) - { - return m_mutex.Clear(); - } - - inline bool Lock(void) - { - return m_mutex.Lock(); - } - - private: - CMutex &m_mutex; - bool m_bClearOnExit; - }; - - class CTryLockObject : public PreventCopy - { - public: - inline CTryLockObject(CMutex &mutex, bool bClearOnExit = false) : - m_mutex(mutex), - m_bClearOnExit(bClearOnExit), - m_bIsLocked(m_mutex.TryLock()) - { - } - - inline ~CTryLockObject(void) - { - if (m_bClearOnExit) - Clear(); - else if (m_bIsLocked) - Unlock(); - } - - inline bool TryLock(void) - { - bool bReturn = m_mutex.TryLock(); - m_bIsLocked |= bReturn; - return bReturn; - } - - inline void Unlock(void) - { - if (m_bIsLocked) - { - m_bIsLocked = false; - m_mutex.Unlock(); - } - } - - inline bool Clear(void) - { - m_bIsLocked = false; - return m_mutex.Clear(); - } - - inline bool Lock(void) - { - bool bReturn = m_mutex.Lock(); - m_bIsLocked |= bReturn; - return bReturn; - } - - inline bool IsLocked(void) const - { - return m_bIsLocked; - } - - private: - CMutex & m_mutex; - bool m_bClearOnExit; - volatile bool m_bIsLocked; - }; - - typedef bool (*PredicateCallback) (void *param); - - template - class CCondition : public PreventCopy - { - private: - static bool _PredicateCallbackDefault ( void *param ) - { - _Predicate *p = (_Predicate*)param; - return (*p); - } - public: - inline CCondition(void) {} - inline ~CCondition(void) - { - m_condition.Broadcast(); - } - - inline void Broadcast(void) - { - m_condition.Broadcast(); - } - - inline void Signal(void) - { - m_condition.Signal(); - } - - inline bool Wait(CMutex &mutex, uint32_t iTimeout) - { - return m_condition.Wait(mutex.m_mutex, iTimeout); - } - - inline bool Wait(CMutex &mutex, PredicateCallback callback, void *param, uint32_t iTimeout) - { - bool bReturn(false); - CTimeout timeout(iTimeout); - - while (!bReturn) - { - if ((bReturn = callback(param)) == true) - break; - uint32_t iMsLeft = timeout.TimeLeft(); - if ((iTimeout != 0) && (iMsLeft == 0)) - break; - m_condition.Wait(mutex.m_mutex, iMsLeft); - } - - return bReturn; - } - - inline bool Wait(CMutex &mutex, _Predicate &predicate, uint32_t iTimeout = 0) - { - return Wait(mutex, _PredicateCallbackDefault, (void*)&predicate, iTimeout); - } - - private: - CConditionImpl m_condition; - }; - - class CEvent - { - public: - CEvent(bool bAutoReset = true) : - m_bSignaled(false), - m_bBroadcast(false), - m_iWaitingThreads(0), - m_bAutoReset(bAutoReset) {} - virtual ~CEvent(void) {} - - void Broadcast(void) - { - Set(true); - m_condition.Broadcast(); - } - - void Signal(void) - { - Set(false); - m_condition.Signal(); - } - - bool Wait(void) - { - CLockObject lock(m_mutex); - ++m_iWaitingThreads; - - bool bReturn = m_condition.Wait(m_mutex, m_bSignaled); - return ResetAndReturn() && bReturn; - } - - bool Wait(uint32_t iTimeout) - { - if (iTimeout == 0) - return Wait(); - - CLockObject lock(m_mutex); - ++m_iWaitingThreads; - bool bReturn = m_condition.Wait(m_mutex, m_bSignaled, iTimeout); - return ResetAndReturn() && bReturn; - } - - static void Sleep(uint32_t iTimeout) - { - CEvent event; - event.Wait(iTimeout); - } - - private: - void Set(bool bBroadcast = false) - { - CLockObject lock(m_mutex); - m_bSignaled = true; - m_bBroadcast = bBroadcast; - } - - bool ResetAndReturn(void) - { - CLockObject lock(m_mutex); - bool bReturn(m_bSignaled); - if (bReturn && (--m_iWaitingThreads == 0 || !m_bBroadcast) && m_bAutoReset) - m_bSignaled = false; - return bReturn; - } - - volatile bool m_bSignaled; - CCondition m_condition; - CMutex m_mutex; - volatile bool m_bBroadcast; - unsigned int m_iWaitingThreads; - bool m_bAutoReset; - }; -} diff -Nru kodiplatform-15.0.0/src/threads/threads.h kodiplatform-16.0.0/src/threads/threads.h --- kodiplatform-15.0.0/src/threads/threads.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/threads/threads.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "mutex.h" - -namespace PLATFORM -{ - class CThread - { - public: - CThread(void) : - m_bStop(false), - m_bRunning(false), - m_bStopped(false) {} - - virtual ~CThread(void) - { - StopThread(0); - } - - static void *ThreadHandler(void *_thread) - { - CThread *thread = static_cast(_thread); - void *retVal = NULL; - - if (thread) - { - { - CLockObject lock(thread->m_threadMutex); - thread->m_bRunning = true; - thread->m_bStopped = false; - thread->m_threadCondition.Broadcast(); - } - - retVal = thread->Process(); - - { - CLockObject lock(thread->m_threadMutex); - thread->m_bRunning = false; - thread->m_bStopped = true; - thread->m_threadCondition.Broadcast(); - } - } - - return retVal; - } - - virtual bool IsRunning(void) - { - CLockObject lock(m_threadMutex); - return m_bRunning; - } - - virtual bool IsStopped(void) - { - CLockObject lock(m_threadMutex); - return m_bStop; - } - - virtual bool CreateThread(bool bWait = true) - { - bool bReturn(false); - CLockObject lock(m_threadMutex); - if (!IsRunning()) - { - m_bStop = false; - if (ThreadsCreate(m_thread, CThread::ThreadHandler, ((void*)static_cast(this)))) - { - if (bWait) - m_threadCondition.Wait(m_threadMutex, m_bRunning); - bReturn = true; - } - } - return bReturn; - } - - /*! - * @brief Stop the thread - * @param iWaitMs negative = don't wait, 0 = infinite, or the amount of ms to wait - */ - virtual bool StopThread(int iWaitMs = 5000) - { - bool bReturn(true); - bool bRunning(false); - { - CLockObject lock(m_threadMutex); - bRunning = IsRunning(); - m_bStop = true; - } - - if (bRunning && iWaitMs >= 0) - { - CLockObject lock(m_threadMutex); - bReturn = m_threadCondition.Wait(m_threadMutex, m_bStopped, iWaitMs); - } - else - { - bReturn = true; - } - - return bReturn; - } - - virtual bool Sleep(uint32_t iTimeout) - { - CLockObject lock(m_threadMutex); - return m_bStop ? false : m_threadCondition.Wait(m_threadMutex, m_bStopped, iTimeout); - } - - virtual void *Process(void) = 0; - - protected: - void SetRunning(bool bSetTo); - - private: - bool m_bStop; - bool m_bRunning; - bool m_bStopped; - CCondition m_threadCondition; - CMutex m_threadMutex; - thread_t m_thread; - }; -}; diff -Nru kodiplatform-15.0.0/src/util/atomic.h kodiplatform-16.0.0/src/util/atomic.h --- kodiplatform-15.0.0/src/util/atomic.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/atomic.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2012 Team XBMC - * http://www.kodi.tv - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#ifdef _MSC_VER -#include -#endif - -/////////////////////////////////////////////////////////////////////////// -// 32-bit atomic increment -// Returns new value of *pAddr -/////////////////////////////////////////////////////////////////////////// -static inline long atomic_inc(volatile long* pAddr) -{ -#if defined(HAS_BUILTIN_SYNC_ADD_AND_FETCH) - return __sync_add_and_fetch(pAddr, 1); - -#elif defined(__ppc__) || defined(__powerpc__) // PowerPC - long val; - __asm__ __volatile__ ( - "sync \n" - "1: lwarx %0, 0, %1 \n" - "addic %0, %0, 1 \n" - "stwcx. %0, 0, %1 \n" - "bne- 1b \n" - "isync" - : "=&r" (val) - : "r" (pAddr) - : "cc", "xer", "memory"); - return val; - -#elif defined(__arm__) && !defined(__ARM_ARCH_5__) - register long val; - asm volatile ( - "dmb ish \n" // Memory barrier. Make sure all memory accesses appearing before this complete before any that appear after - "1: \n" - "ldrex %0, [%1] \n" // (val = *pAddr) - "add %0, #1 \n" // (val += 1) - "strex r1, %0, [%1] \n" - "cmp r1, #0 \n" - "bne 1b \n" - "dmb ish \n" // Memory barrier. - : "=&r" (val) - : "r"(pAddr) - : "r1" - ); - return val; - -#elif defined(__mips__) -// TODO: - long val; - #error AtomicIncrement undefined for mips - return val; - -#elif defined(WIN32) - long val; - __asm - { - mov eax, pAddr ; - lock inc dword ptr [eax] ; - mov eax, [eax] ; - mov val, eax ; - } - return val; - -#elif defined(__x86_64__) - register long result; - __asm__ __volatile__ ( - "lock/xaddq %q0, %1" - : "=r" (result), "=m" (*pAddr) - : "0" ((long) (1)), "m" (*pAddr)); - return *pAddr; - -#else // Linux / OSX86 (GCC) - register long reg __asm__ ("eax") = 1; - __asm__ __volatile__ ( - "lock/xadd %0, %1 \n" - "inc %%eax" - : "+r" (reg) - : "m" (*pAddr) - : "memory" ); - return reg; - -#endif -} diff -Nru kodiplatform-15.0.0/src/util/baudrate.h kodiplatform-16.0.0/src/util/baudrate.h --- kodiplatform-15.0.0/src/util/baudrate.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/baudrate.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -//every baudrate I could find is in here in an #ifdef block -//so it should compile on everything - -#ifndef __WINDOWS__ -#include -#endif - -namespace PLATFORM -{ - static struct sbaudrate - { - int32_t rate; - int32_t symbol; - } - - baudrates[] = - { - #ifdef B50 - { 50, B50 }, - #endif - #ifdef B75 - { 75, B75 }, - #endif - #ifdef B110 - { 110, B110 }, - #endif - #ifdef B134 - { 134, B134 }, - #endif - #ifdef B150 - { 150, B150 }, - #endif - #ifdef B200 - { 200, B200 }, - #endif - #ifdef B300 - { 300, B300 }, - #endif - #ifdef B600 - { 600, B600 }, - #endif - #ifdef B1200 - { 1200, B1200 }, - #endif - #ifdef B1800 - { 1800, B1800 }, - #endif - #ifdef B2400 - { 2400, B2400 }, - #endif - #ifdef B4800 - { 4800, B4800 }, - #endif - #ifdef B9600 - { 9600, B9600 }, - #endif - #ifdef B14400 - { 14400, B14400 }, - #endif - #ifdef B19200 - { 19200, B19200 }, - #endif - #ifdef B28800 - { 28800, B28800 }, - #endif - #ifdef B38400 - { 38400, B38400 }, - #endif - #ifdef B57600 - { 57600, B57600 }, - #endif - #ifdef B76800 - { 76800, B76800 }, - #endif - #ifdef B115200 - { 115200, B115200 }, - #endif - #ifdef B230400 - { 230400, B230400 }, - #endif - #ifdef B250000 - { 250000, B250000 }, - #endif - #ifdef B460800 - { 460800, B460800 }, - #endif - #ifdef B500000 - { 500000, B500000 }, - #endif - #ifdef B576000 - { 576000, B576000 }, - #endif - #ifdef B921600 - { 921600, B921600 }, - #endif - #ifdef B1000000 - { 1000000, B1000000 }, - #endif - #ifdef B1152000 - { 1152000, B1152000 }, - #endif - #ifdef B1500000 - { 1500000, B1500000 }, - #endif - #ifdef B2000000 - { 2000000, B2000000 }, - #endif - #ifdef B2500000 - { 2500000, B2500000 }, - #endif - #ifdef B3000000 - { 3000000, B3000000 }, - #endif - #ifdef B3500000 - { 3500000, B3500000 }, - #endif - #ifdef B4000000 - { 4000000, B4000000 }, - #endif - #ifdef CBR_110 - { 110, CBR_110 }, - #endif - #ifdef CBR_300 - { 300, CBR_300 }, - #endif - #ifdef CBR_600 - { 600, CBR_600 }, - #endif - #ifdef CBR_1200 - { 1200, CBR_1200 }, - #endif - #ifdef CBR_2400 - { 2400, CBR_2400 }, - #endif - #ifdef CBR_4800 - { 4800, CBR_4800 }, - #endif - #ifdef CBR_9600 - { 9600, CBR_9600 }, - #endif - #ifdef CBR_11400 - { 11400, CBR_14400 }, - #endif - #ifdef CBR_19200 - { 19200, CBR_19200 }, - #endif - #ifdef CBR_38400 - { 38400, CBR_38400 }, - #endif - #ifdef CBR_56000 - { 56000, CBR_56000 }, - #endif - #ifdef CBR_57600 - { 57600, CBR_57600 }, - #endif - #ifdef CBR_115200 - { 115200, CBR_115200 }, - #endif - #ifdef CBR_128000 - { 128000, CBR_128000 }, - #endif - #ifdef CBR_256000 - { 256000, CBR_256000 }, - #endif - { -1, -1} - }; - - inline int32_t IntToBaudrate(uint32_t baudrate) - { - for (unsigned int i = 0; i < sizeof(baudrates) / sizeof(PLATFORM::sbaudrate) - 1; i++) - { - if (baudrates[i].rate == (int32_t) baudrate) - return baudrates[i].symbol; - } - - return -1; - }; -}; diff -Nru kodiplatform-15.0.0/src/util/buffer.h kodiplatform-16.0.0/src/util/buffer.h --- kodiplatform-15.0.0/src/util/buffer.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/buffer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../threads/mutex.h" -#include - -namespace PLATFORM -{ - template - struct SyncedBuffer - { - public: - SyncedBuffer(size_t iMaxSize = 100) : - m_maxSize(iMaxSize), - m_bHasData(false) {} - - virtual ~SyncedBuffer(void) - { - Clear(); - } - - void Clear(void) - { - CLockObject lock(m_mutex); - while (!m_buffer.empty()) - m_buffer.pop(); - m_bHasData = false; - m_condition.Broadcast(); - } - - size_t Size(void) - { - CLockObject lock(m_mutex); - return m_buffer.size(); - } - - bool IsEmpty(void) - { - CLockObject lock(m_mutex); - return !m_bHasData; - } - - bool Push(_BType entry) - { - CLockObject lock(m_mutex); - if (m_buffer.size() == m_maxSize) - return false; - - m_buffer.push(entry); - m_bHasData = true; - m_condition.Signal(); - return true; - } - - bool Pop(_BType &entry, int32_t iTimeoutMs = 0) - { - CLockObject lock(m_mutex); - if (m_buffer.empty()) - { - if (iTimeoutMs == 0) - return false; - if (!m_condition.Wait(m_mutex, m_bHasData, iTimeoutMs)) - return false; - } - - entry = m_buffer.front(); - m_buffer.pop(); - m_bHasData = !m_buffer.empty(); - return true; - } - - private: - size_t m_maxSize; - std::queue<_BType> m_buffer; - CMutex m_mutex; - bool m_bHasData; - CCondition m_condition; - }; -}; diff -Nru kodiplatform-15.0.0/src/util/fstrcmp.c kodiplatform-16.0.0/src/util/fstrcmp.c --- kodiplatform-15.0.0/src/util/fstrcmp.c 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/fstrcmp.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -/* - * Functions to make fuzzy comparisons between strings. - * - * Derived from PHP 5 similar_text() function - * - * The basic algorithm is described in: - * Oliver [1993] and the complexity is O(N**3) with N == length of longest string - - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2010 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Rasmus Lerdorf | - | Stig Sther Bakken | - | Zeev Suraski | - +----------------------------------------------------------------------+ - */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include - -static int similar_text(const char *str1, const char *str2, int len1, int len2) -{ - int sum; - int pos1 = 0, pos2 = 0; - int max = 0; - - char *p, *q; - char *end1 = (char *)str1 + len1; - char *end2 = (char *)str2 + len2; - int l; - - for (p = (char *)str1; p < end1; p++) - { - for (q = (char *)str2; q < end2; q++) - { - for (l = 0; (p + l < end1) && (q + l < end2) && (p[l] == q[l]); l++) - ; - if (l > max) - { - max = l; - pos1 = p - str1; - pos2 = q - str2; - } - } - } - if ((sum = max)) - { - if (pos1 && pos2) - sum += similar_text(str1, str2, pos1, pos2); - - if ((pos1 + max < len1) && (pos2 + max < len2)) - sum += similar_text(str1 + pos1 + max, str2 + pos2 + max, - len1 - pos1 - max, len2 - pos2 - max); - } - - return sum; -} - -/* NAME - fstrcmp - fuzzy string compare - - SYNOPSIS - double fstrcmp(const char *, const char *, double); - - DESCRIPTION - The fstrcmp function may be used to compare two string for - similarity. It is very useful in reducing "cascade" or - "secondary" errors in compilers or other situations where - symbol tables occur. - - RETURNS - double; 0 if the strings are entirly dissimilar, 1 if the - strings are identical, and a number in between if they are - similar. */ - -double -fstrcmp (const char *string1, const char *string2, double minimum) -{ - int len1, len2, score; - - len1 = (int)strlen(string1); - len2 = (int)strlen(string2); - - /* short-circuit obvious comparisons */ - if (len1 == 0 && len2 == 0) - return 1.0; - if (len1 == 0 || len2 == 0) - return 0.0; - - score = similar_text(string1, string2, len1, len2); - /* The result is - ((number of chars in common) / (average length of the strings)). - This is admittedly biased towards finding that the strings are - similar, however it does produce meaningful results. */ - return ((double)score * 2.0 / (len1 + len2)); -} - -#ifdef __cplusplus -} // extern "C" -#endif diff -Nru kodiplatform-15.0.0/src/util/fstrcmp.h kodiplatform-16.0.0/src/util/fstrcmp.h --- kodiplatform-15.0.0/src/util/fstrcmp.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/fstrcmp.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -#ifndef _FSTRCMP_H -#define _FSTRCMP_H - - /* GNU gettext - internationalization aids - Copyright (C) 1995 Free Software Foundation, Inc. - - This file was written by Peter Miller - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with XBMC; see the file COPYING. If not, see -. -*/ -#define PARAMS(proto) proto - -#ifdef __cplusplus -extern "C" -{ -#endif - -double fstrcmp (const char *__s1, const char *__s2, double __minimum); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff -Nru kodiplatform-15.0.0/src/util/StdString.h kodiplatform-16.0.0/src/util/StdString.h --- kodiplatform-15.0.0/src/util/StdString.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/StdString.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,4337 +0,0 @@ -#pragma once -#include "../os.h" -#include -#include -#include - -#if defined(_WIN32) && !defined(va_copy) -#define va_copy(dst, src) ((dst) = (src)) -#endif - -// ============================================================================= -// FILE: StdString.h -// AUTHOR: Joe O'Leary (with outside help noted in comments) -// -// If you find any bugs in this code, please let me know: -// -// jmoleary@earthlink.net -// http://www.joeo.net/stdstring.htm (a bit outdated) -// -// The latest version of this code should always be available at the -// following link: -// -// http://www.joeo.net/code/StdString.zip (Dec 6, 2003) -// -// -// REMARKS: -// This header file declares the CStdStr template. This template derives -// the Standard C++ Library basic_string<> template and add to it the -// the following conveniences: -// - The full MFC CString set of functions (including implicit cast) -// - writing to/reading from COM IStream interfaces -// - Functional objects for use in STL algorithms -// -// From this template, we intstantiate two classes: CStdStringA and -// CStdStringW. The name "CStdString" is just a #define of one of these, -// based upone the UNICODE macro setting -// -// This header also declares our own version of the MFC/ATL UNICODE-MBCS -// conversion macros. Our version looks exactly like the Microsoft's to -// facilitate portability. -// -// NOTE: -// If you you use this in an MFC or ATL build, you should include either -// afx.h or atlbase.h first, as appropriate. -// -// PEOPLE WHO HAVE CONTRIBUTED TO THIS CLASS: -// -// Several people have helped me iron out problems and othewise improve -// this class. OK, this is a long list but in my own defense, this code -// has undergone two major rewrites. Many of the improvements became -// necessary after I rewrote the code as a template. Others helped me -// improve the CString facade. -// -// Anyway, these people are (in chronological order): -// -// - Pete the Plumber (???) -// - Julian Selman -// - Chris (of Melbsys) -// - Dave Plummer -// - John C Sipos -// - Chris Sells -// - Nigel Nunn -// - Fan Xia -// - Matthew Williams -// - Carl Engman -// - Mark Zeren -// - Craig Watson -// - Rich Zuris -// - Karim Ratib -// - Chris Conti -// - Baptiste Lepilleur -// - Greg Pickles -// - Jim Cline -// - Jeff Kohn -// - Todd Heckel -// - Ullrich Poll�hne -// - Joe Vitaterna -// - Joe Woodbury -// - Aaron (no last name) -// - Joldakowski (???) -// - Scott Hathaway -// - Eric Nitzche -// - Pablo Presedo -// - Farrokh Nejadlotfi -// - Jason Mills -// - Igor Kholodov -// - Mike Crusader -// - John James -// - Wang Haifeng -// - Tim Dowty -// - Arnt Witteveen -// - Glen Maynard -// - Paul DeMarco -// - Bagira (full name?) -// - Ronny Schulz -// - Jakko Van Hunen -// - Charles Godwin -// - Henk Demper -// - Greg Marr -// - Bill Carducci -// - Brian Groose -// - MKingman -// - Don Beusee -// -// REVISION HISTORY -// -// 2005-JAN-10 - Thanks to Don Beusee for pointing out the danger in mapping -// length-checked formatting functions to non-length-checked -// CRT equivalents. Also thanks to him for motivating me to -// optimize my implementation of Replace() -// -// 2004-APR-22 - A big, big thank you to "MKingman" (whoever you are) for -// finally spotting a silly little error in StdCodeCvt that -// has been causing me (and users of CStdString) problems for -// years in some relatively rare conversions. I had reversed -// two length arguments. -// -// 2003-NOV-24 - Thanks to a bunch of people for helping me clean up many -// compiler warnings (and yes, even a couple of actual compiler -// errors). These include Henk Demper for figuring out how -// to make the Intellisense work on with CStdString on VC6, -// something I was never able to do. Greg Marr pointed out -// a compiler warning about an unreferenced symbol and a -// problem with my version of Load in MFC builds. Bill -// Carducci took a lot of time with me to help me figure out -// why some implementations of the Standard C++ Library were -// returning error codes for apparently successful conversions -// between ASCII and UNICODE. Finally thanks to Brian Groose -// for helping me fix compiler signed unsigned warnings in -// several functions. -// -// 2003-JUL-10 - Thanks to Charles Godwin for making me realize my 'FmtArg' -// fixes had inadvertently broken the DLL-export code (which is -// normally commented out. I had to move it up higher. Also -// this helped me catch a bug in ssicoll that would prevent -// compilation, otherwise. -// -// 2003-MAR-14 - Thanks to Jakko Van Hunen for pointing out a copy-and-paste -// bug in one of the overloads of FmtArg. -// -// 2003-MAR-10 - Thanks to Ronny Schulz for (twice!) sending me some changes -// to help CStdString build on SGI and for pointing out an -// error in placement of my preprocessor macros for ssfmtmsg. -// -// 2002-NOV-26 - Thanks to Bagira for pointing out that my implementation of -// SpanExcluding was not properly handling the case in which -// the string did NOT contain any of the given characters -// -// 2002-OCT-21 - Many thanks to Paul DeMarco who was invaluable in helping me -// get this code working with Borland's free compiler as well -// as the Dev-C++ compiler (available free at SourceForge). -// -// 2002-SEP-13 - Thanks to Glen Maynard who helped me get rid of some loud -// but harmless warnings that were showing up on g++. Glen -// also pointed out that some pre-declarations of FmtArg<> -// specializations were unnecessary (and no good on G++) -// -// 2002-JUN-26 - Thanks to Arnt Witteveen for pointing out that I was using -// static_cast<> in a place in which I should have been using -// reinterpret_cast<> (the ctor for unsigned char strings). -// That's what happens when I don't unit-test properly! -// Arnt also noticed that CString was silently correcting the -// 'nCount' argument to Left() and Right() where CStdString was -// not (and crashing if it was bad). That is also now fixed! -// -// 2002-FEB-25 - Thanks to Tim Dowty for pointing out (and giving me the fix -// for) a conversion problem with non-ASCII MBCS characters. -// CStdString is now used in my favorite commercial MP3 player! -// -// 2001-DEC-06 - Thanks to Wang Haifeng for spotting a problem in one of the -// assignment operators (for _bstr_t) that would cause compiler -// errors when refcounting protection was turned off. -// -// 2001-NOV-27 - Remove calls to operator!= which involve reverse_iterators -// due to a conflict with the rel_ops operator!=. Thanks to -// John James for pointing this out. -// -// 2001-OCT-29 - Added a minor range checking fix for the Mid function to -// make it as forgiving as CString's version is. Thanks to -// Igor Kholodov for noticing this. -// - Added a specialization of std::swap for CStdString. Thanks -// to Mike Crusader for suggesting this! It's commented out -// because you're not supposed to inject your own code into the -// 'std' namespace. But if you don't care about that, it's -// there if you want it -// - Thanks to Jason Mills for catching a case where CString was -// more forgiving in the Delete() function than I was. -// -// 2001-JUN-06 - I was violating the Standard name lookup rules stated -// in [14.6.2(3)]. None of the compilers I've tried so -// far apparently caught this but HP-UX aCC 3.30 did. The -// fix was to add 'this->' prefixes in many places. -// Thanks to Farrokh Nejadlotfi for this! -// -// 2001-APR-27 - StreamLoad was calculating the number of BYTES in one -// case, not characters. Thanks to Pablo Presedo for this. -// -// 2001-FEB-23 - Replace() had a bug which caused infinite loops if the -// source string was empty. Fixed thanks to Eric Nitzsche. -// -// 2001-FEB-23 - Scott Hathaway was a huge help in providing me with the -// ability to build CStdString on Sun Unix systems. He -// sent me detailed build reports about what works and what -// does not. If CStdString compiles on your Unix box, you -// can thank Scott for it. -// -// 2000-DEC-29 - Joldakowski noticed one overload of Insert failed to do a -// range check as CString's does. Now fixed -- thanks! -// -// 2000-NOV-07 - Aaron pointed out that I was calling static member -// functions of char_traits via a temporary. This was not -// technically wrong, but it was unnecessary and caused -// problems for poor old buggy VC5. Thanks Aaron! -// -// 2000-JUL-11 - Joe Woodbury noted that the CString::Find docs don't match -// what the CString::Find code really ends up doing. I was -// trying to match the docs. Now I match the CString code -// - Joe also caught me truncating strings for GetBuffer() calls -// when the supplied length was less than the current length. -// -// 2000-MAY-25 - Better support for STLPORT's Standard library distribution -// - Got rid of the NSP macro - it interfered with Koenig lookup -// - Thanks to Joe Woodbury for catching a TrimLeft() bug that -// I introduced in January. Empty strings were not getting -// trimmed -// -// 2000-APR-17 - Thanks to Joe Vitaterna for pointing out that ReverseFind -// is supposed to be a const function. -// -// 2000-MAR-07 - Thanks to Ullrich Poll�hne for catching a range bug in one -// of the overloads of assign. -// -// 2000-FEB-01 - You can now use CStdString on the Mac with CodeWarrior! -// Thanks to Todd Heckel for helping out with this. -// -// 2000-JAN-23 - Thanks to Jim Cline for pointing out how I could make the -// Trim() function more efficient. -// - Thanks to Jeff Kohn for prompting me to find and fix a typo -// in one of the addition operators that takes _bstr_t. -// - Got rid of the .CPP file - you only need StdString.h now! -// -// 1999-DEC-22 - Thanks to Greg Pickles for helping me identify a problem -// with my implementation of CStdString::FormatV in which -// resulting string might not be properly NULL terminated. -// -// 1999-DEC-06 - Chris Conti pointed yet another basic_string<> assignment -// bug that MS has not fixed. CStdString did nothing to fix -// it either but it does now! The bug was: create a string -// longer than 31 characters, get a pointer to it (via c_str()) -// and then assign that pointer to the original string object. -// The resulting string would be empty. Not with CStdString! -// -// 1999-OCT-06 - BufferSet was erasing the string even when it was merely -// supposed to shrink it. Fixed. Thanks to Chris Conti. -// - Some of the Q172398 fixes were not checking for assignment- -// to-self. Fixed. Thanks to Baptiste Lepilleur. -// -// 1999-AUG-20 - Improved Load() function to be more efficient by using -// SizeOfResource(). Thanks to Rich Zuris for this. -// - Corrected resource ID constructor, again thanks to Rich. -// - Fixed a bug that occurred with UNICODE characters above -// the first 255 ANSI ones. Thanks to Craig Watson. -// - Added missing overloads of TrimLeft() and TrimRight(). -// Thanks to Karim Ratib for pointing them out -// -// 1999-JUL-21 - Made all calls to GetBuf() with no args check length first. -// -// 1999-JUL-10 - Improved MFC/ATL independence of conversion macros -// - Added SS_NO_REFCOUNT macro to allow you to disable any -// reference-counting your basic_string<> impl. may do. -// - Improved ReleaseBuffer() to be as forgiving as CString. -// Thanks for Fan Xia for helping me find this and to -// Matthew Williams for pointing it out directly. -// -// 1999-JUL-06 - Thanks to Nigel Nunn for catching a very sneaky bug in -// ToLower/ToUpper. They should call GetBuf() instead of -// data() in order to ensure the changed string buffer is not -// reference-counted (in those implementations that refcount). -// -// 1999-JUL-01 - Added a true CString facade. Now you can use CStdString as -// a drop-in replacement for CString. If you find this useful, -// you can thank Chris Sells for finally convincing me to give -// in and implement it. -// - Changed operators << and >> (for MFC CArchive) to serialize -// EXACTLY as CString's do. So now you can send a CString out -// to a CArchive and later read it in as a CStdString. I have -// no idea why you would want to do this but you can. -// -// 1999-JUN-21 - Changed the CStdString class into the CStdStr template. -// - Fixed FormatV() to correctly decrement the loop counter. -// This was harmless bug but a bug nevertheless. Thanks to -// Chris (of Melbsys) for pointing it out -// - Changed Format() to try a normal stack-based array before -// using to _alloca(). -// - Updated the text conversion macros to properly use code -// pages and to fit in better in MFC/ATL builds. In other -// words, I copied Microsoft's conversion stuff again. -// - Added equivalents of CString::GetBuffer, GetBufferSetLength -// - new sscpy() replacement of CStdString::CopyString() -// - a Trim() function that combines TrimRight() and TrimLeft(). -// -// 1999-MAR-13 - Corrected the "NotSpace" functional object to use _istpace() -// instead of _isspace() Thanks to Dave Plummer for this. -// -// 1999-FEB-26 - Removed errant line (left over from testing) that #defined -// _MFC_VER. Thanks to John C Sipos for noticing this. -// -// 1999-FEB-03 - Fixed a bug in a rarely-used overload of operator+() that -// caused infinite recursion and stack overflow -// - Added member functions to simplify the process of -// persisting CStdStrings to/from DCOM IStream interfaces -// - Added functional objects (e.g. StdStringLessNoCase) that -// allow CStdStrings to be used as keys STL map objects with -// case-insensitive comparison -// - Added array indexing operators (i.e. operator[]). I -// originally assumed that these were unnecessary and would be -// inherited from basic_string. However, without them, Visual -// C++ complains about ambiguous overloads when you try to use -// them. Thanks to Julian Selman to pointing this out. -// -// 1998-FEB-?? - Added overloads of assign() function to completely account -// for Q172398 bug. Thanks to "Pete the Plumber" for this -// -// 1998-FEB-?? - Initial submission -// -// COPYRIGHT: -// 2002 Joseph M. O'Leary. This code is 100% free. Use it anywhere you -// want. Rewrite it, restructure it, whatever. If you can write software -// that makes money off of it, good for you. I kinda like capitalism. -// Please don't blame me if it causes your $30 billion dollar satellite -// explode in orbit. If you redistribute it in any form, I'd appreciate it -// if you would leave this notice here. -// ============================================================================= - -// Avoid multiple inclusion - -#ifndef STDSTRING_H -#define STDSTRING_H - -// When using VC, turn off browser references -// Turn off unavoidable compiler warnings - -#if defined(_MSC_VER) && (_MSC_VER > 1100) - #pragma component(browser, off, references, "CStdString") - #pragma warning (disable : 4290) // C++ Exception Specification ignored - #pragma warning (disable : 4127) // Conditional expression is constant - #pragma warning (disable : 4097) // typedef name used as synonym for class name -#endif - -// Borland warnings to turn off - -#ifdef __BORLANDC__ - #pragma option push -w-inl -// #pragma warn -inl // Turn off inline function warnings -#endif - -// SS_IS_INTRESOURCE -// ----------------- -// A copy of IS_INTRESOURCE from VC7. Because old VC6 version of winuser.h -// doesn't have this. - -#define SS_IS_INTRESOURCE(_r) (false) - -#if !defined (SS_ANSI) && defined(_MSC_VER) - #undef SS_IS_INTRESOURCE - #if defined(_WIN64) - #define SS_IS_INTRESOURCE(_r) (((unsigned __int64)(_r) >> 16) == 0) - #else - #define SS_IS_INTRESOURCE(_r) (((unsigned long)(_r) >> 16) == 0) - #endif -#endif - - -// MACRO: SS_UNSIGNED -// ------------------ -// This macro causes the addition of a constructor and assignment operator -// which take unsigned characters. CString has such functions and in order -// to provide maximum CString-compatability, this code needs them as well. -// In practice you will likely never need these functions... - -//#define SS_UNSIGNED - -#ifdef SS_ALLOW_UNSIGNED_CHARS - #define SS_UNSIGNED -#endif - -// MACRO: SS_SAFE_FORMAT -// --------------------- -// This macro provides limited compatability with a questionable CString -// "feature". You can define it in order to avoid a common problem that -// people encounter when switching from CString to CStdString. -// -// To illustrate the problem -- With CString, you can do this: -// -// CString sName("Joe"); -// CString sTmp; -// sTmp.Format("My name is %s", sName); // WORKS! -// -// However if you were to try this with CStdString, your program would -// crash. -// -// CStdString sName("Joe"); -// CStdString sTmp; -// sTmp.Format("My name is %s", sName); // CRASHES! -// -// You must explicitly call c_str() or cast the object to the proper type -// -// sTmp.Format("My name is %s", sName.c_str()); // WORKS! -// sTmp.Format("My name is %s", static_cast(sName));// WORKS! -// sTmp.Format("My name is %s", (PCSTR)sName); // WORKS! -// -// This is because it is illegal to pass anything but a POD type as a -// variadic argument to a variadic function (i.e. as one of the "..." -// arguments). The type const char* is a POD type. The type CStdString -// is not. Of course, neither is the type CString, but CString lets you do -// it anyway due to the way they laid out the class in binary. I have no -// control over this in CStdString since I derive from whatever -// implementation of basic_string is available. -// -// However if you have legacy code (which does this) that you want to take -// out of the MFC world and you don't want to rewrite all your calls to -// Format(), then you can define this flag and it will no longer crash. -// -// Note however that this ONLY works for Format(), not sprintf, fprintf, -// etc. If you pass a CStdString object to one of those functions, your -// program will crash. Not much I can do to get around this, short of -// writing substitutes for those functions as well. - -#define SS_SAFE_FORMAT // use new template style Format() function - - -// MACRO: SS_NO_IMPLICIT_CAST -// -------------------------- -// Some people don't like the implicit cast to const char* (or rather to -// const CT*) that CStdString (and MFC's CString) provide. That was the -// whole reason I created this class in the first place, but hey, whatever -// bakes your cake. Just #define this macro to get rid of the the implicit -// cast. - -//#define SS_NO_IMPLICIT_CAST // gets rid of operator const CT*() - - -// MACRO: SS_NO_REFCOUNT -// --------------------- -// turns off reference counting at the assignment level. Only needed -// for the version of basic_string<> that comes with Visual C++ versions -// 6.0 or earlier, and only then in some heavily multithreaded scenarios. -// Uncomment it if you feel you need it. - -//#define SS_NO_REFCOUNT - -// MACRO: SS_WIN32 -// --------------- -// When this flag is set, we are building code for the Win32 platform and -// may use Win32 specific functions (such as LoadString). This gives us -// a couple of nice extras for the code. -// -// Obviously, Microsoft's is not the only compiler available for Win32 out -// there. So I can't just check to see if _MSC_VER is defined to detect -// if I'm building on Win32. So for now, if you use MS Visual C++ or -// Borland's compiler, I turn this on. Otherwise you may turn it on -// yourself, if you prefer - -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WIN32) - #define SS_WIN32 -#endif - -// MACRO: SS_ANSI -// -------------- -// When this macro is defined, the code attempts only to use ANSI/ISO -// standard library functions to do it's work. It will NOT attempt to use -// any Win32 of Visual C++ specific functions -- even if they are -// available. You may define this flag yourself to prevent any Win32 -// of VC++ specific functions from being called. - -// If we're not on Win32, we MUST use an ANSI build - -#ifndef SS_WIN32 - #if !defined(SS_NO_ANSI) - #define SS_ANSI - #endif -#endif - -// MACRO: SS_ALLOCA -// ---------------- -// Some implementations of the Standard C Library have a non-standard -// function known as alloca(). This functions allows one to allocate a -// variable amount of memory on the stack. It is needed to implement -// the ASCII/MBCS conversion macros. -// -// I wanted to find some way to determine automatically if alloca() is -// available on this platform via compiler flags but that is asking for -// trouble. The crude test presented here will likely need fixing on -// other platforms. Therefore I'll leave it up to you to fiddle with -// this test to determine if it exists. Just make sure SS_ALLOCA is or -// is not defined as appropriate and you control this feature. - -#if defined(_MSC_VER) && !defined(SS_ANSI) - #define SS_ALLOCA -#endif - - -// MACRO: SS_MBCS -// -------------- -// Setting this macro means you are using MBCS characters. In MSVC builds, -// this macro gets set automatically by detection of the preprocessor flag -// _MBCS. For other platforms you may set it manually if you wish. The -// only effect it currently has is to cause the allocation of more space -// for wchar_t --> char conversions. -// Note that MBCS does not mean UNICODE. -// -// #define SS_MBCS -// - -#ifdef _MBCS - #define SS_MBCS -#endif - - -// MACRO SS_NO_LOCALE -// ------------------ -// If your implementation of the Standard C++ Library lacks the header, -// you can #define this macro to make your code build properly. Note that this -// is some of my newest code and frankly I'm not very sure of it, though it does -// pass my unit tests. - -// #define SS_NO_LOCALE - - -// Compiler Error regarding _UNICODE and UNICODE -// ----------------------------------------------- -// Microsoft header files are screwy. Sometimes they depend on a preprocessor -// flag named "_UNICODE". Other times they check "UNICODE" (note the lack of -// leading underscore in the second version". In several places, they silently -// "synchronize" these two flags this by defining one of the other was defined. -// In older version of this header, I used to try to do the same thing. -// -// However experience has taught me that this is a bad idea. You get weird -// compiler errors that seem to indicate things like LPWSTR and LPTSTR not being -// equivalent in UNICODE builds, stuff like that (when they MUST be in a proper -// UNICODE build). You end up scratching your head and saying, "But that HAS -// to compile!". -// -// So what should you do if you get this error? -// -// Make sure that both macros (_UNICODE and UNICODE) are defined before this -// file is included. You can do that by either -// -// a) defining both yourself before any files get included -// b) including the proper MS headers in the proper order -// c) including this file before any other file, uncommenting -// the #defines below, and commenting out the #errors -// -// Personally I recommend solution a) but it's your call. - -#ifdef _MSC_VER - #if defined (_UNICODE) && !defined (UNICODE) - #error UNICODE defined but not UNICODE - // #define UNICODE // no longer silently fix this - #endif - #if defined (UNICODE) && !defined (_UNICODE) - #error Warning, UNICODE defined but not _UNICODE - // #define _UNICODE // no longer silently fix this - #endif -#endif - - -// ----------------------------------------------------------------------------- -// MIN and MAX. The Standard C++ template versions go by so many names (at -// at least in the MS implementation) that you never know what's available -// ----------------------------------------------------------------------------- -template -inline const Type& SSMIN(const Type& arg1, const Type& arg2) -{ - return arg2 < arg1 ? arg2 : arg1; -} -template -inline const Type& SSMAX(const Type& arg1, const Type& arg2) -{ - return arg2 > arg1 ? arg2 : arg1; -} - -// If they have not #included W32Base.h (part of my W32 utility library) then -// we need to define some stuff. Otherwise, this is all defined there. - -#if !defined(W32BASE_H) - - // If they want us to use only standard C++ stuff (no Win32 stuff) - - #ifdef SS_ANSI - - // On Win32 we have TCHAR.H so just include it. This is NOT violating - // the spirit of SS_ANSI as we are not calling any Win32 functions here. - - #ifdef SS_WIN32 - - #include - #include - #ifndef STRICT - #define STRICT - #endif - - // ... but on non-Win32 platforms, we must #define the types we need. - - #else - - typedef const char* PCSTR; - typedef char* PSTR; - typedef const wchar_t* PCWSTR; - typedef wchar_t* PWSTR; - #ifdef UNICODE - typedef wchar_t TCHAR; - #else - typedef char TCHAR; - #endif - typedef wchar_t OLECHAR; - - #endif // #ifndef _WIN32 - - - // Make sure ASSERT and verify are defined using only ANSI stuff - - #ifndef ASSERT - #include - #define ASSERT(f) assert((f)) - #endif - #ifndef VERIFY - #ifdef _DEBUG - #define VERIFY(x) ASSERT((x)) - #else - #define VERIFY(x) x - #endif - #endif - - #else // ...else SS_ANSI is NOT defined - - #include - #include - #ifndef STRICT - #define STRICT - #endif - - // Make sure ASSERT and verify are defined - - #ifndef ASSERT - #include - #define ASSERT(f) _ASSERTE((f)) - #endif - #ifndef VERIFY - #ifdef _DEBUG - #define VERIFY(x) ASSERT((x)) - #else - #define VERIFY(x) x - #endif - #endif - - #endif // #ifdef SS_ANSI - - #ifndef UNUSED - #define UNUSED(x) x - #endif - -#endif // #ifndef W32BASE_H - -// Standard headers needed - -#include // basic_string -#include // for_each, etc. -#include // for StdStringLessNoCase, et al -#ifndef SS_NO_LOCALE - #include // for various facets -#endif - -// If this is a recent enough version of VC include comdef.h, so we can write -// member functions to deal with COM types & compiler support classes e.g. -// _bstr_t - -#if defined (_MSC_VER) && (_MSC_VER >= 1100) - #include - #define SS_INC_COMDEF // signal that we #included MS comdef.h file - #define STDSTRING_INC_COMDEF - #define SS_NOTHROW __declspec(nothrow) -#else - #define SS_NOTHROW -#endif - -#ifndef TRACE - #define TRACE_DEFINED_HERE - #define TRACE -#endif - -// Microsoft defines PCSTR, PCWSTR, etc, but no PCTSTR. I hate to use the -// versions with the "L" in front of them because that's a leftover from Win 16 -// days, even though it evaluates to the same thing. Therefore, Define a PCSTR -// as an LPCTSTR. - -#if !defined(PCTSTR) && !defined(PCTSTR_DEFINED) - typedef const TCHAR* PCTSTR; - #define PCTSTR_DEFINED -#endif - -#if !defined(PCOLESTR) && !defined(PCOLESTR_DEFINED) - typedef const OLECHAR* PCOLESTR; - #define PCOLESTR_DEFINED -#endif - -#if !defined(POLESTR) && !defined(POLESTR_DEFINED) - typedef OLECHAR* POLESTR; - #define POLESTR_DEFINED -#endif - -#if !defined(PCUSTR) && !defined(PCUSTR_DEFINED) - typedef const unsigned char* PCUSTR; - typedef unsigned char* PUSTR; - #define PCUSTR_DEFINED -#endif - - -// SGI compiler 7.3 doesnt know these types - oh and btw, remember to use -// -LANG:std in the CXX Flags -#if defined(__sgi) - typedef unsigned long DWORD; - typedef void * LPCVOID; -#endif - - -// SS_USE_FACET macro and why we need it: -// -// Since I'm a good little Standard C++ programmer, I use locales. Thus, I -// need to make use of the use_facet<> template function here. Unfortunately, -// this need is complicated by the fact the MS' implementation of the Standard -// C++ Library has a non-standard version of use_facet that takes more -// arguments than the standard dictates. Since I'm trying to write CStdString -// to work with any version of the Standard library, this presents a problem. -// -// The upshot of this is that I can't do 'use_facet' directly. The MS' docs -// tell me that I have to use a macro, _USE() instead. Since _USE obviously -// won't be available in other implementations, this means that I have to write -// my OWN macro -- SS_USE_FACET -- that evaluates either to _USE or to the -// standard, use_facet. -// -// If you are having trouble with the SS_USE_FACET macro, in your implementation -// of the Standard C++ Library, you can define your own version of SS_USE_FACET. - -#ifndef schMSG - #define schSTR(x) #x - #define schSTR2(x) schSTR(x) - #define schMSG(desc) message(__FILE__ "(" schSTR2(__LINE__) "):" #desc) -#endif - -#ifndef SS_USE_FACET - - // STLPort #defines a macro (__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) for - // all MSVC builds, erroneously in my opinion. It causes problems for - // my SS_ANSI builds. In my code, I always comment out that line. You'll - // find it in \stlport\config\stl_msvc.h - - #if defined(__SGI_STL_PORT) && (__SGI_STL_PORT >= 0x400 ) - - #if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) && defined(_MSC_VER) - #ifdef SS_ANSI - #pragma schMSG(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS defined!!) - #endif - #endif - #define SS_USE_FACET(loc, fac) std::use_facet(loc) - - #elif defined(_MSC_VER ) - - #define SS_USE_FACET(loc, fac) std::_USE(loc, fac) - - // ...and - #elif defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) - - #define SS_USE_FACET(loc, fac) std::use_facet(loc, (fac*)0) - - #else - - #define SS_USE_FACET(loc, fac) std::use_facet(loc) - - #endif - -#endif - -// ============================================================================= -// UNICODE/MBCS conversion macros. Made to work just like the MFC/ATL ones. -// ============================================================================= - -#include // Added to Std Library with Amendment #1. - -// First define the conversion helper functions. We define these regardless of -// any preprocessor macro settings since their names won't collide. - -// Not sure if we need all these headers. I believe ANSI says we do. - -#include -#include -#include -#include -#include -#ifndef va_start - #include -#endif - - -#ifdef SS_NO_LOCALE - - #if defined(_WIN32) || defined (_WIN32_WCE) - - inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc, - UINT acp=CP_ACP) - { - ASSERT(0 != pSrcA); - ASSERT(0 != pDstW); - pDstW[0] = '\0'; - MultiByteToWideChar(acp, 0, pSrcA, nSrc, pDstW, nDst); - return pDstW; - } - inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCUSTR pSrcA, int nSrc, - UINT acp=CP_ACP) - { - return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, acp); - } - - inline PSTR StdCodeCvt(PSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc, - UINT acp=CP_ACP) - { - ASSERT(0 != pDstA); - ASSERT(0 != pSrcW); - pDstA[0] = '\0'; - WideCharToMultiByte(acp, 0, pSrcW, nSrc, pDstA, nDst, 0, 0); - return pDstA; - } - inline PUSTR StdCodeCvt(PUSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc, - UINT acp=CP_ACP) - { - return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, acp); - } - #else - #endif - -#else - - // StdCodeCvt - made to look like Win32 functions WideCharToMultiByte - // and MultiByteToWideChar but uses locales in SS_ANSI - // builds. There are a number of overloads. - // First argument is the destination buffer. - // Second argument is the source buffer - //#if defined (SS_ANSI) || !defined (SS_WIN32) - - // 'SSCodeCvt' - shorthand name for the codecvt facet we use - - typedef std::codecvt SSCodeCvt; - - inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc, - const std::locale& loc=std::locale()) - { - ASSERT(0 != pSrcA); - ASSERT(0 != pDstW); - - pDstW[0] = '\0'; - - if ( nSrc > 0 ) - { - PCSTR pNextSrcA = pSrcA; - PWSTR pNextDstW = pDstW; - SSCodeCvt::result res = SSCodeCvt::ok; - const SSCodeCvt& conv = SS_USE_FACET(loc, SSCodeCvt); - SSCodeCvt::state_type st= { 0 }; - res = conv.in(st, - pSrcA, pSrcA + nSrc, pNextSrcA, - pDstW, pDstW + nDst, pNextDstW); -#ifdef _LINUX -#define ASSERT2(a) if (!(a)) {fprintf(stderr, "StdString: Assertion Failed on line %d\n", __LINE__);} -#else -#define ASSERT2 ASSERT -#endif - ASSERT2(SSCodeCvt::ok == res); - ASSERT2(SSCodeCvt::error != res); - ASSERT2(pNextDstW >= pDstW); - ASSERT2(pNextSrcA >= pSrcA); -#undef ASSERT2 - // Null terminate the converted string - - if ( pNextDstW - pDstW > nDst ) - *(pDstW + nDst) = '\0'; - else - *pNextDstW = '\0'; - } - return pDstW; - } - inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCUSTR pSrcA, int nSrc, - const std::locale& loc=std::locale()) - { - return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, loc); - } - - inline PSTR StdCodeCvt(PSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc, - const std::locale& loc=std::locale()) - { - ASSERT(0 != pDstA); - ASSERT(0 != pSrcW); - - pDstA[0] = '\0'; - - if ( nSrc > 0 ) - { - PSTR pNextDstA = pDstA; - PCWSTR pNextSrcW = pSrcW; - SSCodeCvt::result res = SSCodeCvt::ok; - const SSCodeCvt& conv = SS_USE_FACET(loc, SSCodeCvt); - SSCodeCvt::state_type st= { 0 }; - res = conv.out(st, - pSrcW, pSrcW + nSrc, pNextSrcW, - pDstA, pDstA + nDst, pNextDstA); -#ifdef _LINUX -#define ASSERT2(a) if (!(a)) {fprintf(stderr, "StdString: Assertion Failed on line %d\n", __LINE__);} -#else -#define ASSERT2 ASSERT -#endif - ASSERT2(SSCodeCvt::error != res); - ASSERT2(SSCodeCvt::ok == res); // strict, comment out for sanity - ASSERT2(pNextDstA >= pDstA); - ASSERT2(pNextSrcW >= pSrcW); -#undef ASSERT2 - - // Null terminate the converted string - - if ( pNextDstA - pDstA > nDst ) - *(pDstA + nDst) = '\0'; - else - *pNextDstA = '\0'; - } - return pDstA; - } - - inline PUSTR StdCodeCvt(PUSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc, - const std::locale& loc=std::locale()) - { - return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, loc); - } - -#endif - - - -// Unicode/MBCS conversion macros are only available on implementations of -// the "C" library that have the non-standard _alloca function. As far as I -// know that's only Microsoft's though I've heard that the function exists -// elsewhere. - -#if defined(SS_ALLOCA) && !defined SS_NO_CONVERSION - - #include // needed for _alloca - - // Define our conversion macros to look exactly like Microsoft's to - // facilitate using this stuff both with and without MFC/ATL - - #ifdef _CONVERSION_USES_THREAD_LOCALE - - #ifndef _DEBUG - #define SSCVT int _cvt; _cvt; UINT _acp=GetACP(); \ - _acp; PCWSTR _pw; _pw; PCSTR _pa; _pa - #else - #define SSCVT int _cvt = 0; _cvt; UINT _acp=GetACP();\ - _acp; PCWSTR _pw=0; _pw; PCSTR _pa=0; _pa - #endif - #define SSA2W(pa) (\ - ((_pa = pa) == 0) ? 0 : (\ - _cvt = (sslen(_pa)),\ - StdCodeCvt((PWSTR) _alloca((_cvt+1)*2), (_cvt+1)*2, \ - _pa, _cvt, _acp))) - #define SSW2A(pw) (\ - ((_pw = pw) == 0) ? 0 : (\ - _cvt = sslen(_pw), \ - StdCodeCvt((LPSTR) _alloca((_cvt+1)*2), (_cvt+1)*2, \ - _pw, _cvt, _acp))) - #else - - #ifndef _DEBUG - #define SSCVT int _cvt; _cvt; UINT _acp=CP_ACP; _acp;\ - PCWSTR _pw; _pw; PCSTR _pa; _pa - #else - #define SSCVT int _cvt = 0; _cvt; UINT _acp=CP_ACP; \ - _acp; PCWSTR _pw=0; _pw; PCSTR _pa=0; _pa - #endif - #define SSA2W(pa) (\ - ((_pa = pa) == 0) ? 0 : (\ - _cvt = (sslen(_pa)),\ - StdCodeCvt((PWSTR) _alloca((_cvt+1)*2), (_cvt+1)*2, \ - _pa, _cvt))) - #define SSW2A(pw) (\ - ((_pw = pw) == 0) ? 0 : (\ - _cvt = (sslen(_pw)),\ - StdCodeCvt((LPSTR) _alloca((_cvt+1)*2), (_cvt+1)*2, \ - _pw, _cvt))) - #endif - - #define SSA2CW(pa) ((PCWSTR)SSA2W((pa))) - #define SSW2CA(pw) ((PCSTR)SSW2A((pw))) - - #ifdef UNICODE - #define SST2A SSW2A - #define SSA2T SSA2W - #define SST2CA SSW2CA - #define SSA2CT SSA2CW - // (Did you get a compiler error here about not being able to convert - // PTSTR into PWSTR? Then your _UNICODE and UNICODE flags are messed - // up. Best bet: #define BOTH macros before including any MS headers.) - inline PWSTR SST2W(PTSTR p) { return p; } - inline PTSTR SSW2T(PWSTR p) { return p; } - inline PCWSTR SST2CW(PCTSTR p) { return p; } - inline PCTSTR SSW2CT(PCWSTR p) { return p; } - #else - #define SST2W SSA2W - #define SSW2T SSW2A - #define SST2CW SSA2CW - #define SSW2CT SSW2CA - inline PSTR SST2A(PTSTR p) { return p; } - inline PTSTR SSA2T(PSTR p) { return p; } - inline PCSTR SST2CA(PCTSTR p) { return p; } - inline PCTSTR SSA2CT(PCSTR p) { return p; } - #endif // #ifdef UNICODE - - #if defined(UNICODE) - // in these cases the default (TCHAR) is the same as OLECHAR - inline PCOLESTR SST2COLE(PCTSTR p) { return p; } - inline PCTSTR SSOLE2CT(PCOLESTR p) { return p; } - inline POLESTR SST2OLE(PTSTR p) { return p; } - inline PTSTR SSOLE2T(POLESTR p) { return p; } - #elif defined(OLE2ANSI) - // in these cases the default (TCHAR) is the same as OLECHAR - inline PCOLESTR SST2COLE(PCTSTR p) { return p; } - inline PCTSTR SSOLE2CT(PCOLESTR p) { return p; } - inline POLESTR SST2OLE(PTSTR p) { return p; } - inline PTSTR SSOLE2T(POLESTR p) { return p; } - #else - //CharNextW doesn't work on Win95 so we use this - #define SST2COLE(pa) SSA2CW((pa)) - #define SST2OLE(pa) SSA2W((pa)) - #define SSOLE2CT(po) SSW2CA((po)) - #define SSOLE2T(po) SSW2A((po)) - #endif - - #ifdef OLE2ANSI - #define SSW2OLE SSW2A - #define SSOLE2W SSA2W - #define SSW2COLE SSW2CA - #define SSOLE2CW SSA2CW - inline POLESTR SSA2OLE(PSTR p) { return p; } - inline PSTR SSOLE2A(POLESTR p) { return p; } - inline PCOLESTR SSA2COLE(PCSTR p) { return p; } - inline PCSTR SSOLE2CA(PCOLESTR p){ return p; } - #else - #define SSA2OLE SSA2W - #define SSOLE2A SSW2A - #define SSA2COLE SSA2CW - #define SSOLE2CA SSW2CA - inline POLESTR SSW2OLE(PWSTR p) { return p; } - inline PWSTR SSOLE2W(POLESTR p) { return p; } - inline PCOLESTR SSW2COLE(PCWSTR p) { return p; } - inline PCWSTR SSOLE2CW(PCOLESTR p){ return p; } - #endif - - // Above we've defined macros that look like MS' but all have - // an 'SS' prefix. Now we need the real macros. We'll either - // get them from the macros above or from MFC/ATL. - - #if defined (USES_CONVERSION) - - #define _NO_STDCONVERSION // just to be consistent - - #else - - #ifdef _MFC_VER - - #include - #define _NO_STDCONVERSION // just to be consistent - - #else - - #define USES_CONVERSION SSCVT - #define A2CW SSA2CW - #define W2CA SSW2CA - #define T2A SST2A - #define A2T SSA2T - #define T2W SST2W - #define W2T SSW2T - #define T2CA SST2CA - #define A2CT SSA2CT - #define T2CW SST2CW - #define W2CT SSW2CT - #define ocslen sslen - #define ocscpy sscpy - #define T2COLE SST2COLE - #define OLE2CT SSOLE2CT - #define T2OLE SST2COLE - #define OLE2T SSOLE2CT - #define A2OLE SSA2OLE - #define OLE2A SSOLE2A - #define W2OLE SSW2OLE - #define OLE2W SSOLE2W - #define A2COLE SSA2COLE - #define OLE2CA SSOLE2CA - #define W2COLE SSW2COLE - #define OLE2CW SSOLE2CW - - #endif // #ifdef _MFC_VER - #endif // #ifndef USES_CONVERSION -#endif // #ifndef SS_NO_CONVERSION - -// Define ostring - generic name for std::basic_string - -#if !defined(ostring) && !defined(OSTRING_DEFINED) - typedef std::basic_string ostring; - #define OSTRING_DEFINED -#endif - -// StdCodeCvt when there's no conversion to be done -template -inline T* StdCodeCvt(T* pDst, int nDst, const T* pSrc, int nSrc) -{ - int nChars = SSMIN(nSrc, nDst); - - if ( nChars > 0 ) - { - pDst[0] = '\0'; - std::basic_string::traits_type::copy(pDst, pSrc, nChars); -// std::char_traits::copy(pDst, pSrc, nChars); - pDst[nChars] = '\0'; - } - - return pDst; -} -inline PSTR StdCodeCvt(PSTR pDst, int nDst, PCUSTR pSrc, int nSrc) -{ - return StdCodeCvt(pDst, nDst, (PCSTR)pSrc, nSrc); -} -inline PUSTR StdCodeCvt(PUSTR pDst, int nDst, PCSTR pSrc, int nSrc) -{ - return (PUSTR)StdCodeCvt((PSTR)pDst, nDst, pSrc, nSrc); -} - -// Define tstring -- generic name for std::basic_string - -#if !defined(tstring) && !defined(TSTRING_DEFINED) - typedef std::basic_string tstring; - #define TSTRING_DEFINED -#endif - -// a very shorthand way of applying the fix for KB problem Q172398 -// (basic_string assignment bug) - -#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) - #define Q172398(x) (x).erase() -#else - #define Q172398(x) -#endif - -// ============================================================================= -// INLINE FUNCTIONS ON WHICH CSTDSTRING RELIES -// -// Usually for generic text mapping, we rely on preprocessor macro definitions -// to map to string functions. However the CStdStr<> template cannot use -// macro-based generic text mappings because its character types do not get -// resolved until template processing which comes AFTER macro processing. In -// other words, the preprocessor macro UNICODE is of little help to us in the -// CStdStr template -// -// Therefore, to keep the CStdStr declaration simple, we have these inline -// functions. The template calls them often. Since they are inline (and NOT -// exported when this is built as a DLL), they will probably be resolved away -// to nothing. -// -// Without these functions, the CStdStr<> template would probably have to broken -// out into two, almost identical classes. Either that or it would be a huge, -// convoluted mess, with tons of "if" statements all over the place checking the -// size of template parameter CT. -// ============================================================================= - -#ifdef SS_NO_LOCALE - - // -------------------------------------------------------------------------- - // Win32 GetStringTypeEx wrappers - // -------------------------------------------------------------------------- - inline bool wsGetStringType(LCID lc, DWORD dwT, PCSTR pS, int nSize, - WORD* pWd) - { - return FALSE != GetStringTypeExA(lc, dwT, pS, nSize, pWd); - } - inline bool wsGetStringType(LCID lc, DWORD dwT, PCWSTR pS, int nSize, - WORD* pWd) - { - return FALSE != GetStringTypeExW(lc, dwT, pS, nSize, pWd); - } - - - template - inline bool ssisspace (CT t) - { - WORD toYourMother; - return wsGetStringType(GetThreadLocale(), CT_CTYPE1, &t, 1, &toYourMother) - && 0 != (C1_BLANK & toYourMother); - } - -#endif - -// If they defined SS_NO_REFCOUNT, then we must convert all assignments - -#if defined (_MSC_VER) && (_MSC_VER < 1300) - #ifdef SS_NO_REFCOUNT - #define SSREF(x) (x).c_str() - #else - #define SSREF(x) (x) - #endif -#else - #define SSREF(x) (x) -#endif - -// ----------------------------------------------------------------------------- -// sslen: strlen/wcslen wrappers -// ----------------------------------------------------------------------------- -template inline int sslen(const CT* pT) -{ - return 0 == pT ? 0 : (int)std::basic_string::traits_type::length(pT); -// return 0 == pT ? 0 : std::char_traits::length(pT); -} -inline SS_NOTHROW int sslen(const std::string& s) -{ - return static_cast(s.length()); -} -inline SS_NOTHROW int sslen(const std::wstring& s) -{ - return static_cast(s.length()); -} - -// ----------------------------------------------------------------------------- -// sstolower/sstoupper -- convert characters to upper/lower case -// ----------------------------------------------------------------------------- - -#ifdef SS_NO_LOCALE - inline char sstoupper(char ch) { return (char)::toupper(ch); } - inline wchar_t sstoupper(wchar_t ch){ return (wchar_t)::towupper(ch); } - inline char sstolower(char ch) { return (char)::tolower(ch); } - inline wchar_t sstolower(wchar_t ch){ return (wchar_t)::tolower(ch); } -#else - template - inline CT sstolower(const CT& t, const std::locale& loc = std::locale()) - { - return std::tolower(t, loc); - } - template - inline CT sstoupper(const CT& t, const std::locale& loc = std::locale()) - { - return std::toupper(t, loc); - } -#endif - -// ----------------------------------------------------------------------------- -// ssasn: assignment functions -- assign "sSrc" to "sDst" -// ----------------------------------------------------------------------------- -typedef std::string::size_type SS_SIZETYPE; // just for shorthand, really -typedef std::string::pointer SS_PTRTYPE; -typedef std::wstring::size_type SW_SIZETYPE; -typedef std::wstring::pointer SW_PTRTYPE; - - -template -inline void ssasn(std::basic_string& sDst, const std::basic_string& sSrc) -{ - if ( sDst.c_str() != sSrc.c_str() ) - { - sDst.erase(); - sDst.assign(SSREF(sSrc)); - } -} -template -inline void ssasn(std::basic_string& sDst, const T *pA) -{ - // Watch out for NULLs, as always. - - if ( 0 == pA ) - { - sDst.erase(); - } - - // If pA actually points to part of sDst, we must NOT erase(), but - // rather take a substring - - else if ( pA >= sDst.c_str() && pA <= sDst.c_str() + sDst.size() ) - { - sDst =sDst.substr(static_cast::size_type>(pA-sDst.c_str())); - } - - // Otherwise (most cases) apply the assignment bug fix, if applicable - // and do the assignment - - else - { - Q172398(sDst); - sDst.assign(pA); - } -} -inline void ssasn(std::string& sDst, const std::wstring& sSrc) -{ - if ( sSrc.empty() ) - { - sDst.erase(); - } - else - { - int nDst = static_cast(sSrc.size()); - - // In MBCS builds, pad the buffer to account for the possibility of - // some 3 byte characters. Not perfect but should get most cases. - -#ifdef SS_MBCS - // In MBCS builds, we don't know how long the destination string will be. - nDst = static_cast(static_cast(nDst) * 1.3); - sDst.resize(nDst+1); - PCSTR szCvt = StdCodeCvt(const_cast(sDst.data()), nDst, - sSrc.c_str(), static_cast(sSrc.size())); - sDst.resize(sslen(szCvt)); -#else - sDst.resize(nDst+1); - StdCodeCvt(const_cast(sDst.data()), nDst, - sSrc.c_str(), static_cast(sSrc.size())); - sDst.resize(sSrc.size()); -#endif - } -} -inline void ssasn(std::string& sDst, PCWSTR pW) -{ - int nSrc = sslen(pW); - if ( nSrc > 0 ) - { - int nSrc = sslen(pW); - int nDst = nSrc; - - // In MBCS builds, pad the buffer to account for the possibility of - // some 3 byte characters. Not perfect but should get most cases. - -#ifdef SS_MBCS - nDst = static_cast(static_cast(nDst) * 1.3); - // In MBCS builds, we don't know how long the destination string will be. - sDst.resize(nDst + 1); - PCSTR szCvt = StdCodeCvt(const_cast(sDst.data()), nDst, - pW, nSrc); - sDst.resize(sslen(szCvt)); -#else - sDst.resize(nDst + 1); - StdCodeCvt(const_cast(sDst.data()), nDst, pW, nSrc); - sDst.resize(nDst); -#endif - } - else - { - sDst.erase(); - } -} -inline void ssasn(std::string& sDst, const int nNull) -{ - //UNUSED(nNull); - ASSERT(nNull==0); - sDst.assign(""); -} -#undef StrSizeType -inline void ssasn(std::wstring& sDst, const std::string& sSrc) -{ - if ( sSrc.empty() ) - { - sDst.erase(); - } - else - { - int nSrc = static_cast(sSrc.size()); - int nDst = nSrc; - - sDst.resize(nSrc+1); - PCWSTR szCvt = StdCodeCvt(const_cast(sDst.data()), nDst, - sSrc.c_str(), nSrc); - - sDst.resize(sslen(szCvt)); - } -} -inline void ssasn(std::wstring& sDst, PCSTR pA) -{ - int nSrc = sslen(pA); - - if ( 0 == nSrc ) - { - sDst.erase(); - } - else - { - int nDst = nSrc; - sDst.resize(nDst+1); - PCWSTR szCvt = StdCodeCvt(const_cast(sDst.data()), nDst, pA, - nSrc); - - sDst.resize(sslen(szCvt)); - } -} -inline void ssasn(std::wstring& sDst, const int nNull) -{ - //UNUSED(nNull); - ASSERT(nNull==0); - sDst.assign(L""); -} - -// ----------------------------------------------------------------------------- -// ssadd: string object concatenation -- add second argument to first -// ----------------------------------------------------------------------------- -inline void ssadd(std::string& sDst, const std::wstring& sSrc) -{ - int nSrc = static_cast(sSrc.size()); - - if ( nSrc > 0 ) - { - int nDst = static_cast(sDst.size()); - int nAdd = nSrc; - - // In MBCS builds, pad the buffer to account for the possibility of - // some 3 byte characters. Not perfect but should get most cases. - -#ifdef SS_MBCS - nAdd = static_cast(static_cast(nAdd) * 1.3); - sDst.resize(nDst+nAdd+1); - PCSTR szCvt = StdCodeCvt(const_cast(sDst.data()+nDst), - nAdd, sSrc.c_str(), nSrc); - sDst.resize(nDst + sslen(szCvt)); -#else - sDst.resize(nDst+nAdd+1); - StdCodeCvt(const_cast(sDst.data()+nDst), nAdd, sSrc.c_str(), nSrc); - sDst.resize(nDst + nAdd); -#endif - } -} -template -inline void ssadd(typename std::basic_string& sDst, const typename std::basic_string& sSrc) -{ - sDst += sSrc; -} -inline void ssadd(std::string& sDst, PCWSTR pW) -{ - int nSrc = sslen(pW); - if ( nSrc > 0 ) - { - int nDst = static_cast(sDst.size()); - int nAdd = nSrc; - -#ifdef SS_MBCS - nAdd = static_cast(static_cast(nAdd) * 1.3); - sDst.resize(nDst + nAdd + 1); - PCSTR szCvt = StdCodeCvt(const_cast(sDst.data()+nDst), - nAdd, pW, nSrc); - sDst.resize(nDst + sslen(szCvt)); -#else - sDst.resize(nDst + nAdd + 1); - StdCodeCvt(const_cast(sDst.data()+nDst), nAdd, pW, nSrc); - sDst.resize(nDst + nSrc); -#endif - } -} -template -inline void ssadd(typename std::basic_string& sDst, const T *pA) -{ - if ( pA ) - { - // If the string being added is our internal string or a part of our - // internal string, then we must NOT do any reallocation without - // first copying that string to another object (since we're using a - // direct pointer) - - if ( pA >= sDst.c_str() && pA <= sDst.c_str()+sDst.length()) - { - if ( sDst.capacity() <= sDst.size()+sslen(pA) ) - sDst.append(std::basic_string(pA)); - else - sDst.append(pA); - } - else - { - sDst.append(pA); - } - } -} -inline void ssadd(std::wstring& sDst, const std::string& sSrc) -{ - if ( !sSrc.empty() ) - { - int nSrc = static_cast(sSrc.size()); - int nDst = static_cast(sDst.size()); - - sDst.resize(nDst + nSrc + 1); -#ifdef SS_MBCS - PCWSTR szCvt = StdCodeCvt(const_cast(sDst.data()+nDst), - nSrc, sSrc.c_str(), nSrc+1); - sDst.resize(nDst + sslen(szCvt)); -#else - StdCodeCvt(const_cast(sDst.data()+nDst), nSrc, sSrc.c_str(), nSrc+1); - sDst.resize(nDst + nSrc); -#endif - } -} -inline void ssadd(std::wstring& sDst, PCSTR pA) -{ - int nSrc = sslen(pA); - - if ( nSrc > 0 ) - { - int nDst = static_cast(sDst.size()); - - sDst.resize(nDst + nSrc + 1); -#ifdef SS_MBCS - PCWSTR szCvt = StdCodeCvt(const_cast(sDst.data()+nDst), - nSrc, pA, nSrc+1); - sDst.resize(nDst + sslen(szCvt)); -#else - StdCodeCvt(const_cast(sDst.data()+nDst), nSrc, pA, nSrc+1); - sDst.resize(nDst + nSrc); -#endif - } -} - -// ----------------------------------------------------------------------------- -// sscmp: comparison (case sensitive, not affected by locale) -// ----------------------------------------------------------------------------- -template -inline int sscmp(const CT* pA1, const CT* pA2) -{ - CT f; - CT l; - - do - { - f = *(pA1++); - l = *(pA2++); - } while ( (f) && (f == l) ); - - return (int)(f - l); -} - -// ----------------------------------------------------------------------------- -// ssicmp: comparison (case INsensitive, not affected by locale) -// ----------------------------------------------------------------------------- -template -inline int ssicmp(const CT* pA1, const CT* pA2) -{ - // Using the "C" locale = "not affected by locale" - - std::locale loc = std::locale::classic(); - const std::ctype& ct = SS_USE_FACET(loc, std::ctype); - CT f; - CT l; - - do - { - f = ct.tolower(*(pA1++)); - l = ct.tolower(*(pA2++)); - } while ( (f) && (f == l) ); - - return (int)(f - l); -} - -// ----------------------------------------------------------------------------- -// ssupr/sslwr: Uppercase/Lowercase conversion functions -// ----------------------------------------------------------------------------- - -template -inline void sslwr(CT* pT, size_t nLen, const std::locale& loc=std::locale()) -{ - SS_USE_FACET(loc, std::ctype).tolower(pT, pT+nLen); -} -template -inline void ssupr(CT* pT, size_t nLen, const std::locale& loc=std::locale()) -{ - SS_USE_FACET(loc, std::ctype).toupper(pT, pT+nLen); -} - -// ----------------------------------------------------------------------------- -// vsprintf/vswprintf or _vsnprintf/_vsnwprintf equivalents. In standard -// builds we can't use _vsnprintf/_vsnwsprintf because they're MS extensions. -// -// ----------------------------------------------------------------------------- -// Borland's headers put some ANSI "C" functions in the 'std' namespace. -// Promote them to the global namespace so we can use them here. - -#if defined(__BORLANDC__) - using std::vsprintf; - using std::vswprintf; -#endif - - // GNU is supposed to have vsnprintf and vsnwprintf. But only the newer - // distributions do. - -#if defined(__GNUC__) - - inline int ssvsprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) - { - return vsnprintf(pA, nCount, pFmtA, vl); - } - inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) - { - return vswprintf(pW, nCount, pFmtW, vl); - } - - // Microsofties can use -#elif defined(_MSC_VER) && !defined(SS_ANSI) - - inline int ssvsprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) - { - return _vsnprintf(pA, nCount, pFmtA, vl); - } - inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) - { - return _vsnwprintf(pW, nCount, pFmtW, vl); - } - -#elif defined (SS_DANGEROUS_FORMAT) // ignore buffer size parameter if needed? - - inline int ssvsprintf(PSTR pA, size_t /*nCount*/, PCSTR pFmtA, va_list vl) - { - return vsprintf(pA, pFmtA, vl); - } - - inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) - { - // JMO: Some distributions of the "C" have a version of vswprintf that - // takes 3 arguments (e.g. Microsoft, Borland, GNU). Others have a - // version which takes 4 arguments (an extra "count" argument in the - // second position. The best stab I can take at this so far is that if - // you are NOT running with MS, Borland, or GNU, then I'll assume you - // have the version that takes 4 arguments. - // - // I'm sure that these checks don't catch every platform correctly so if - // you get compiler errors on one of the lines immediately below, it's - // probably because your implemntation takes a different number of - // arguments. You can comment out the offending line (and use the - // alternate version) or you can figure out what compiler flag to check - // and add that preprocessor check in. Regardless, if you get an error - // on these lines, I'd sure like to hear from you about it. - // - // Thanks to Ronny Schulz for the SGI-specific checks here. - -// #if !defined(__MWERKS__) && !defined(__SUNPRO_CC_COMPAT) && !defined(__SUNPRO_CC) - #if !defined(_MSC_VER) \ - && !defined (__BORLANDC__) \ - && !defined(__GNUC__) \ - && !defined(__sgi) - - return vswprintf(pW, nCount, pFmtW, vl); - - // suddenly with the current SGI 7.3 compiler there is no such function as - // vswprintf and the substitute needs explicit casts to compile - - #elif defined(__sgi) - - nCount; - return vsprintf( (char *)pW, (char *)pFmtW, vl); - - #else - - nCount; - return vswprintf(pW, pFmtW, vl); - - #endif - - } - -#endif - - // GOT COMPILER PROBLEMS HERE? - // --------------------------- - // Does your compiler choke on one or more of the following 2 functions? It - // probably means that you don't have have either vsnprintf or vsnwprintf in - // your version of the CRT. This is understandable since neither is an ANSI - // "C" function. However it still leaves you in a dilemma. In order to make - // this code build, you're going to have to to use some non-length-checked - // formatting functions that every CRT has: vsprintf and vswprintf. - // - // This is very dangerous. With the proper erroneous (or malicious) code, it - // can lead to buffer overlows and crashing your PC. Use at your own risk - // In order to use them, just #define SS_DANGEROUS_FORMAT at the top of - // this file. - // - // Even THEN you might not be all the way home due to some non-conforming - // distributions. More on this in the comments below. - - inline int ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) - { - #ifdef _MSC_VER - return _vsnprintf(pA, nCount, pFmtA, vl); - #else - return vsnprintf(pA, nCount, pFmtA, vl); - #endif - } - inline int ssnprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) - { - #ifdef _MSC_VER - return _vsnwprintf(pW, nCount, pFmtW, vl); - #else - return vswprintf(pW, nCount, pFmtW, vl); - #endif - } - - - - -// ----------------------------------------------------------------------------- -// ssload: Type safe, overloaded ::LoadString wrappers -// There is no equivalent of these in non-Win32-specific builds. However, I'm -// thinking that with the message facet, there might eventually be one -// ----------------------------------------------------------------------------- -#if defined (SS_WIN32) && !defined(SS_ANSI) - inline int ssload(HMODULE hInst, UINT uId, PSTR pBuf, int nMax) - { - return ::LoadStringA(hInst, uId, pBuf, nMax); - } - inline int ssload(HMODULE hInst, UINT uId, PWSTR pBuf, int nMax) - { - return ::LoadStringW(hInst, uId, pBuf, nMax); - } -#if defined ( _MSC_VER ) && ( _MSC_VER >= 1500 ) - inline int ssload(HMODULE hInst, UINT uId, uint16_t *pBuf, int nMax) - { - return 0; - } - inline int ssload(HMODULE hInst, UINT uId, uint32_t *pBuf, int nMax) - { - return 0; - } -#endif -#endif - - -// ----------------------------------------------------------------------------- -// sscoll/ssicoll: Collation wrappers -// Note -- with MSVC I have reversed the arguments order here because the -// functions appear to return the opposite of what they should -// ----------------------------------------------------------------------------- -#ifndef SS_NO_LOCALE -template -inline int sscoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2) -{ - const std::collate& coll = - SS_USE_FACET(std::locale(), std::collate); - - return coll.compare(sz2, sz2+nLen2, sz1, sz1+nLen1); -} -template -inline int ssicoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2) -{ - const std::locale loc; - const std::collate& coll = SS_USE_FACET(loc, std::collate); - - // Some implementations seem to have trouble using the collate<> - // facet typedefs so we'll just default to basic_string and hope - // that's what the collate facet uses (which it generally should) - -// std::collate::string_type s1(sz1); -// std::collate::string_type s2(sz2); - const std::basic_string sEmpty; - std::basic_string s1(sz1 ? sz1 : sEmpty.c_str()); - std::basic_string s2(sz2 ? sz2 : sEmpty.c_str()); - - sslwr(const_cast(s1.c_str()), nLen1, loc); - sslwr(const_cast(s2.c_str()), nLen2, loc); - return coll.compare(s2.c_str(), s2.c_str()+nLen2, - s1.c_str(), s1.c_str()+nLen1); -} -#endif - - -// ----------------------------------------------------------------------------- -// ssfmtmsg: FormatMessage equivalents. Needed because I added a CString facade -// Again -- no equivalent of these on non-Win32 builds but their might one day -// be one if the message facet gets implemented -// ----------------------------------------------------------------------------- -#if defined (SS_WIN32) && !defined(SS_ANSI) - inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId, - DWORD dwLangId, PSTR pBuf, DWORD nSize, - va_list* vlArgs) - { - return FormatMessageA(dwFlags, pSrc, dwMsgId, dwLangId, - pBuf, nSize,vlArgs); - } - inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId, - DWORD dwLangId, PWSTR pBuf, DWORD nSize, - va_list* vlArgs) - { - return FormatMessageW(dwFlags, pSrc, dwMsgId, dwLangId, - pBuf, nSize,vlArgs); - } -#else -#endif - - - -// FUNCTION: sscpy. Copies up to 'nMax' characters from pSrc to pDst. -// ----------------------------------------------------------------------------- -// FUNCTION: sscpy -// inline int sscpy(PSTR pDst, PCSTR pSrc, int nMax=-1); -// inline int sscpy(PUSTR pDst, PCSTR pSrc, int nMax=-1) -// inline int sscpy(PSTR pDst, PCWSTR pSrc, int nMax=-1); -// inline int sscpy(PWSTR pDst, PCWSTR pSrc, int nMax=-1); -// inline int sscpy(PWSTR pDst, PCSTR pSrc, int nMax=-1); -// -// DESCRIPTION: -// This function is very much (but not exactly) like strcpy. These -// overloads simplify copying one C-style string into another by allowing -// the caller to specify two different types of strings if necessary. -// -// The strings must NOT overlap -// -// "Character" is expressed in terms of the destination string, not -// the source. If no 'nMax' argument is supplied, then the number of -// characters copied will be sslen(pSrc). A NULL terminator will -// also be added so pDst must actually be big enough to hold nMax+1 -// characters. The return value is the number of characters copied, -// not including the NULL terminator. -// -// PARAMETERS: -// pSrc - the string to be copied FROM. May be a char based string, an -// MBCS string (in Win32 builds) or a wide string (wchar_t). -// pSrc - the string to be copied TO. Also may be either MBCS or wide -// nMax - the maximum number of characters to be copied into szDest. Note -// that this is expressed in whatever a "character" means to pDst. -// If pDst is a wchar_t type string than this will be the maximum -// number of wchar_ts that my be copied. The pDst string must be -// large enough to hold least nMaxChars+1 characters. -// If the caller supplies no argument for nMax this is a signal to -// the routine to copy all the characters in pSrc, regardless of -// how long it is. -// -// RETURN VALUE: none -// ----------------------------------------------------------------------------- - -template -inline int sscpycvt(CT1* pDst, const CT2* pSrc, int nMax) -{ - // Note -- we assume pDst is big enough to hold pSrc. If not, we're in - // big trouble. No bounds checking. Caveat emptor. - - int nSrc = sslen(pSrc); - - const CT1* szCvt = StdCodeCvt(pDst, nMax, pSrc, nSrc); - - // If we're copying the same size characters, then all the "code convert" - // just did was basically memcpy so the #of characters copied is the same - // as the number requested. I should probably specialize this function - // template to achieve this purpose as it is silly to do a runtime check - // of a fact known at compile time. I'll get around to it. - - return sslen(szCvt); -} - -template -inline int sscpycvt(T* pDst, const T* pSrc, int nMax) -{ - int nCount = nMax; - for (; nCount > 0 && *pSrc; ++pSrc, ++pDst, --nCount) - std::basic_string::traits_type::assign(*pDst, *pSrc); - - *pDst = 0; - return nMax - nCount; -} - -inline int sscpycvt(PWSTR pDst, PCSTR pSrc, int nMax) -{ - // Note -- we assume pDst is big enough to hold pSrc. If not, we're in - // big trouble. No bounds checking. Caveat emptor. - - const PWSTR szCvt = StdCodeCvt(pDst, nMax, pSrc, nMax); - return sslen(szCvt); -} - -template -inline int sscpy(CT1* pDst, const CT2* pSrc, int nMax, int nLen) -{ - return sscpycvt(pDst, pSrc, SSMIN(nMax, nLen)); -} -template -inline int sscpy(CT1* pDst, const CT2* pSrc, int nMax) -{ - return sscpycvt(pDst, pSrc, SSMIN(nMax, sslen(pSrc))); -} -template -inline int sscpy(CT1* pDst, const CT2* pSrc) -{ - return sscpycvt(pDst, pSrc, sslen(pSrc)); -} -template -inline int sscpy(CT1* pDst, const std::basic_string& sSrc, int nMax) -{ - return sscpycvt(pDst, sSrc.c_str(), SSMIN(nMax, (int)sSrc.length())); -} -template -inline int sscpy(CT1* pDst, const std::basic_string& sSrc) -{ - return sscpycvt(pDst, sSrc.c_str(), (int)sSrc.length()); -} - -#ifdef SS_INC_COMDEF - template - inline int sscpy(CT1* pDst, const _bstr_t& bs, int nMax) - { - return sscpycvt(pDst, static_cast(bs), - SSMIN(nMax, static_cast(bs.length()))); - } - template - inline int sscpy(CT1* pDst, const _bstr_t& bs) - { - return sscpy(pDst, bs, static_cast(bs.length())); - } -#endif - - -// ----------------------------------------------------------------------------- -// Functional objects for changing case. They also let you pass locales -// ----------------------------------------------------------------------------- - -#ifdef SS_NO_LOCALE - template - struct SSToUpper : public std::unary_function - { - inline CT operator()(const CT& t) const - { - return sstoupper(t); - } - }; - template - struct SSToLower : public std::unary_function - { - inline CT operator()(const CT& t) const - { - return sstolower(t); - } - }; -#else - template - struct SSToUpper : public std::binary_function - { - inline CT operator()(const CT& t, const std::locale& loc) const - { - return sstoupper(t, loc); - } - }; - template - struct SSToLower : public std::binary_function - { - inline CT operator()(const CT& t, const std::locale& loc) const - { - return sstolower(t, loc); - } - }; -#endif - -// This struct is used for TrimRight() and TrimLeft() function implementations. -//template -//struct NotSpace : public std::unary_function -//{ -// const std::locale& loc; -// inline NotSpace(const std::locale& locArg) : loc(locArg) {} -// inline bool operator() (CT t) { return !std::isspace(t, loc); } -//}; -template -struct NotSpace : public std::unary_function -{ - // DINKUMWARE BUG: - // Note -- using std::isspace in a COM DLL gives us access violations - // because it causes the dynamic addition of a function to be called - // when the library shuts down. Unfortunately the list is maintained - // in DLL memory but the function is in static memory. So the COM DLL - // goes away along with the function that was supposed to be called, - // and then later when the DLL CRT shuts down it unloads the list and - // tries to call the long-gone function. - // This is DinkumWare's implementation problem. If you encounter this - // problem, you may replace the calls here with good old isspace() and - // iswspace() from the CRT unless they specify SS_ANSI - -#ifdef SS_NO_LOCALE - - bool operator() (CT t) const { return !ssisspace(t); } - -#else - const std::locale loc; - NotSpace(const std::locale& locArg=std::locale()) : loc(locArg) {} - bool operator() (CT t) const { return !std::isspace(t, loc); } -#endif -}; - - - - -// Now we can define the template (finally!) -// ============================================================================= -// TEMPLATE: CStdStr -// template class CStdStr : public std::basic_string -// -// REMARKS: -// This template derives from basic_string and adds some MFC CString- -// like functionality -// -// Basically, this is my attempt to make Standard C++ library strings as -// easy to use as the MFC CString class. -// -// Note that although this is a template, it makes the assumption that the -// template argument (CT, the character type) is either char or wchar_t. -// ============================================================================= - -//#define CStdStr _SS // avoid compiler warning 4786 - -// template ARG& FmtArg(ARG& arg) { return arg; } -// PCSTR FmtArg(const std::string& arg) { return arg.c_str(); } -// PCWSTR FmtArg(const std::wstring& arg) { return arg.c_str(); } - -template -struct FmtArg -{ - explicit FmtArg(const ARG& arg) : a_(arg) {} - const ARG& operator()() const { return a_; } - const ARG& a_; -private: - FmtArg& operator=(const FmtArg&) { return *this; } -}; - -template -class CStdStr : public std::basic_string -{ - // Typedefs for shorter names. Using these names also appears to help - // us avoid some ambiguities that otherwise arise on some platforms - - #define MYBASE std::basic_string // my base class - //typedef typename std::basic_string MYBASE; // my base class - typedef CStdStr MYTYPE; // myself - typedef typename MYBASE::const_pointer PCMYSTR; // PCSTR or PCWSTR - typedef typename MYBASE::pointer PMYSTR; // PSTR or PWSTR - typedef typename MYBASE::iterator MYITER; // my iterator type - typedef typename MYBASE::const_iterator MYCITER; // you get the idea... - typedef typename MYBASE::reverse_iterator MYRITER; - typedef typename MYBASE::size_type MYSIZE; - typedef typename MYBASE::value_type MYVAL; - typedef typename MYBASE::allocator_type MYALLOC; - -public: - // shorthand conversion from PCTSTR to string resource ID - #define SSRES(pctstr) LOWORD(reinterpret_cast(pctstr)) - - bool TryLoad(const void* pT) - { - bool bLoaded = false; - -#if defined(SS_WIN32) && !defined(SS_ANSI) - if ( ( pT != NULL ) && SS_IS_INTRESOURCE(pT) ) - { - UINT nId = LOWORD(reinterpret_cast(pT)); - if ( !LoadString(nId) ) - { - TRACE(_T("Can't load string %u\n"), SSRES(pT)); - } - bLoaded = true; - } -#endif - - return bLoaded; - } - - - // CStdStr inline constructors - CStdStr() - { - } - - CStdStr(const MYTYPE& str) : MYBASE(SSREF(str)) - { - } - - CStdStr(const std::string& str) - { - ssasn(*this, SSREF(str)); - } - - CStdStr(const std::wstring& str) - { - ssasn(*this, SSREF(str)); - } - - CStdStr(PCMYSTR pT, MYSIZE n) : MYBASE(pT, n) - { - } - -#ifdef SS_UNSIGNED - CStdStr(PCUSTR pU) - { - *this = reinterpret_cast(pU); - } -#endif - - CStdStr(PCSTR pA) - { - #ifdef SS_ANSI - *this = pA; - #else - if ( !TryLoad(pA) ) - *this = pA; - #endif - } - - CStdStr(PCWSTR pW) - { - #ifdef SS_ANSI - *this = pW; - #else - if ( !TryLoad(pW) ) - *this = pW; - #endif - } - - CStdStr(uint16_t* pW) - { - #ifdef SS_ANSI - *this = pW; - #else - if ( !TryLoad(pW) ) - *this = pW; - #endif - } - - CStdStr(uint32_t* pW) - { - #ifdef SS_ANSI - *this = pW; - #else - if ( !TryLoad(pW) ) - *this = pW; - #endif - } - - CStdStr(MYCITER first, MYCITER last) - : MYBASE(first, last) - { - } - - CStdStr(MYSIZE nSize, MYVAL ch, const MYALLOC& al=MYALLOC()) - : MYBASE(nSize, ch, al) - { - } - - #ifdef SS_INC_COMDEF - CStdStr(const _bstr_t& bstr) - { - if ( bstr.length() > 0 ) - this->append(static_cast(bstr), bstr.length()); - } - #endif - - // CStdStr inline assignment operators -- the ssasn function now takes care - // of fixing the MSVC assignment bug (see knowledge base article Q172398). - MYTYPE& operator=(const MYTYPE& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& operator=(const std::string& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& operator=(const std::wstring& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& operator=(PCSTR pA) - { - ssasn(*this, pA); - return *this; - } - - MYTYPE& operator=(PCWSTR pW) - { - ssasn(*this, pW); - return *this; - } - -#ifdef SS_UNSIGNED - MYTYPE& operator=(PCUSTR pU) - { - ssasn(*this, reinterpret_cast(pU)); - return *this; - } -#endif - - MYTYPE& operator=(uint16_t* pA) - { - ssasn(*this, pA); - return *this; - } - - MYTYPE& operator=(uint32_t* pA) - { - ssasn(*this, pA); - return *this; - } - - MYTYPE& operator=(CT t) - { - Q172398(*this); - this->assign(1, t); - return *this; - } - - #ifdef SS_INC_COMDEF - MYTYPE& operator=(const _bstr_t& bstr) - { - if ( bstr.length() > 0 ) - { - this->assign(static_cast(bstr), bstr.length()); - return *this; - } - else - { - this->erase(); - return *this; - } - } - #endif - - - // Overloads also needed to fix the MSVC assignment bug (KB: Q172398) - // *** Thanks to Pete The Plumber for catching this one *** - // They also are compiled if you have explicitly turned off refcounting - #if ( defined(_MSC_VER) && ( _MSC_VER < 1200 ) ) || defined(SS_NO_REFCOUNT) - - MYTYPE& assign(const MYTYPE& str) - { - Q172398(*this); - sscpy(GetBuffer(str.size()+1), SSREF(str)); - this->ReleaseBuffer(str.size()); - return *this; - } - - MYTYPE& assign(const MYTYPE& str, MYSIZE nStart, MYSIZE nChars) - { - // This overload of basic_string::assign is supposed to assign up to - // or the NULL terminator, whichever comes first. Since we - // are about to call a less forgiving overload (in which - // must be a valid length), we must adjust the length here to a safe - // value. Thanks to Ullrich Poll�hne for catching this bug - - nChars = SSMIN(nChars, str.length() - nStart); - MYTYPE strTemp(str.c_str()+nStart, nChars); - Q172398(*this); - this->assign(strTemp); - return *this; - } - - MYTYPE& assign(const MYBASE& str) - { - ssasn(*this, str); - return *this; - } - - MYTYPE& assign(const MYBASE& str, MYSIZE nStart, MYSIZE nChars) - { - // This overload of basic_string::assign is supposed to assign up to - // or the NULL terminator, whichever comes first. Since we - // are about to call a less forgiving overload (in which - // must be a valid length), we must adjust the length here to a safe - // value. Thanks to Ullrich Poll�hne for catching this bug - - nChars = SSMIN(nChars, str.length() - nStart); - - // Watch out for assignment to self - - if ( this == &str ) - { - MYTYPE strTemp(str.c_str() + nStart, nChars); - static_cast(this)->assign(strTemp); - } - else - { - Q172398(*this); - static_cast(this)->assign(str.c_str()+nStart, nChars); - } - return *this; - } - - MYTYPE& assign(const CT* pC, MYSIZE nChars) - { - // Q172398 only fix -- erase before assigning, but not if we're - // assigning from our own buffer - - #if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) - if ( !this->empty() && - ( pC < this->data() || pC > this->data() + this->capacity() ) ) - { - this->erase(); - } - #endif - Q172398(*this); - static_cast(this)->assign(pC, nChars); - return *this; - } - - MYTYPE& assign(MYSIZE nChars, MYVAL val) - { - Q172398(*this); - static_cast(this)->assign(nChars, val); - return *this; - } - - MYTYPE& assign(const CT* pT) - { - return this->assign(pT, MYBASE::traits_type::length(pT)); - } - - MYTYPE& assign(MYCITER iterFirst, MYCITER iterLast) - { - #if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) - // Q172398 fix. don't call erase() if we're assigning from ourself - if ( iterFirst < this->begin() || - iterFirst > this->begin() + this->size() ) - { - this->erase() - } - #endif - this->replace(this->begin(), this->end(), iterFirst, iterLast); - return *this; - } - #endif - - - // ------------------------------------------------------------------------- - // CStdStr inline concatenation. - // ------------------------------------------------------------------------- - MYTYPE& operator+=(const MYTYPE& str) - { - ssadd(*this, str); - return *this; - } - - MYTYPE& operator+=(const std::string& str) - { - ssadd(*this, str); - return *this; - } - - MYTYPE& operator+=(const std::wstring& str) - { - ssadd(*this, str); - return *this; - } - - MYTYPE& operator+=(PCSTR pA) - { - ssadd(*this, pA); - return *this; - } - - MYTYPE& operator+=(PCWSTR pW) - { - ssadd(*this, pW); - return *this; - } - - MYTYPE& operator+=(uint16_t* pW) - { - ssadd(*this, pW); - return *this; - } - - MYTYPE& operator+=(uint32_t* pW) - { - ssadd(*this, pW); - return *this; - } - - MYTYPE& operator+=(CT t) - { - this->append(1, t); - return *this; - } - #ifdef SS_INC_COMDEF // if we have _bstr_t, define a += for it too. - MYTYPE& operator+=(const _bstr_t& bstr) - { - return this->operator+=(static_cast(bstr)); - } - #endif - - - // ------------------------------------------------------------------------- - // Case changing functions - // ------------------------------------------------------------------------- - - MYTYPE& ToUpper(const std::locale& loc=std::locale()) - { - // Note -- if there are any MBCS character sets in which the lowercase - // form a character takes up a different number of bytes than the - // uppercase form, this would probably not work... - - std::transform(this->begin(), - this->end(), - this->begin(), -#ifdef SS_NO_LOCALE - SSToUpper()); -#else - std::bind2nd(SSToUpper(), loc)); -#endif - - // ...but if it were, this would probably work better. Also, this way - // seems to be a bit faster when anything other then the "C" locale is - // used... - -// if ( !empty() ) -// { -// ssupr(this->GetBuf(), this->size(), loc); -// this->RelBuf(); -// } - - return *this; - } - - MYTYPE& ToLower(const std::locale& loc=std::locale()) - { - // Note -- if there are any MBCS character sets in which the lowercase - // form a character takes up a different number of bytes than the - // uppercase form, this would probably not work... - - std::transform(this->begin(), - this->end(), - this->begin(), -#ifdef SS_NO_LOCALE - SSToLower()); -#else - std::bind2nd(SSToLower(), loc)); -#endif - - // ...but if it were, this would probably work better. Also, this way - // seems to be a bit faster when anything other then the "C" locale is - // used... - -// if ( !empty() ) -// { -// sslwr(this->GetBuf(), this->size(), loc); -// this->RelBuf(); -// } - return *this; - } - - - MYTYPE& Normalize() - { - return Trim().ToLower(); - } - - - // ------------------------------------------------------------------------- - // CStdStr -- Direct access to character buffer. In the MS' implementation, - // the at() function that we use here also calls _Freeze() providing us some - // protection from multithreading problems associated with ref-counting. - // In VC 7 and later, of course, the ref-counting stuff is gone. - // ------------------------------------------------------------------------- - - CT* GetBuf(int nMinLen=-1) - { - if ( static_cast(this->size()) < nMinLen ) - this->resize(static_cast(nMinLen)); - - return this->empty() ? const_cast(this->data()) : &(this->at(0)); - } - - CT* SetBuf(int nLen) - { - nLen = ( nLen > 0 ? nLen : 0 ); - if ( this->capacity() < 1 && nLen == 0 ) - this->resize(1); - - this->resize(static_cast(nLen)); - return const_cast(this->data()); - } - void RelBuf(int nNewLen=-1) - { - this->resize(static_cast(nNewLen > -1 ? nNewLen : - sslen(this->c_str()))); - } - - void BufferRel() { RelBuf(); } // backwards compatability - CT* Buffer() { return GetBuf(); } // backwards compatability - CT* BufferSet(int nLen) { return SetBuf(nLen);}// backwards compatability - - bool Equals(const CT* pT, bool bUseCase=false) const - { - return 0 == (bUseCase ? this->compare(pT) : ssicmp(this->c_str(), pT)); - } - - // ------------------------------------------------------------------------- - // FUNCTION: CStdStr::Load - // REMARKS: - // Loads string from resource specified by nID - // - // PARAMETERS: - // nID - resource Identifier. Purely a Win32 thing in this case - // - // RETURN VALUE: - // true if successful, false otherwise - // ------------------------------------------------------------------------- - -#ifndef SS_ANSI - - bool Load(UINT nId, HMODULE hModule=NULL) - { - bool bLoaded = false; // set to true of we succeed. - - #ifdef _MFC_VER // When in Rome (or MFC land)... - - // If they gave a resource handle, use it. Note - this is archaic - // and not really what I would recommend. But then again, in MFC - // land, you ought to be using CString for resources anyway since - // it walks the resource chain for you. - - HMODULE hModuleOld = NULL; - - if ( NULL != hModule ) - { - hModuleOld = AfxGetResourceHandle(); - AfxSetResourceHandle(hModule); - } - - // ...load the string - - CString strRes; - bLoaded = FALSE != strRes.LoadString(nId); - - // ...and if we set the resource handle, restore it. - - if ( NULL != hModuleOld ) - AfxSetResourceHandle(hModule); - - if ( bLoaded ) - *this = strRes; - - #else // otherwise make our own hackneyed version of CString's Load - - // Get the resource name and module handle - - if ( NULL == hModule ) - hModule = GetResourceHandle(); - - PCTSTR szName = MAKEINTRESOURCE((nId>>4)+1); // lifted - DWORD dwSize = 0; - - // No sense continuing if we can't find the resource - - HRSRC hrsrc = ::FindResource(hModule, szName, RT_STRING); - - if ( NULL == hrsrc ) - { - TRACE(_T("Cannot find resource %d: 0x%X"), nId, ::GetLastError()); - } - else if ( 0 == (dwSize = ::SizeofResource(hModule, hrsrc) / sizeof(CT))) - { - TRACE(_T("Cant get size of resource %d 0x%X\n"),nId,GetLastError()); - } - else - { - bLoaded = 0 != ssload(hModule, nId, GetBuf(dwSize), dwSize); - ReleaseBuffer(); - } - - #endif // #ifdef _MFC_VER - - if ( !bLoaded ) - TRACE(_T("String not loaded 0x%X\n"), ::GetLastError()); - - return bLoaded; - } - -#endif // #ifdef SS_ANSI - - // ------------------------------------------------------------------------- - // FUNCTION: CStdStr::Format - // void _cdecl Formst(CStdStringA& PCSTR szFormat, ...) - // void _cdecl Format(PCSTR szFormat); - // - // DESCRIPTION: - // This function does sprintf/wsprintf style formatting on CStdStringA - // objects. It looks a lot like MFC's CString::Format. Some people - // might even call this identical. Fortunately, these people are now - // dead... heh heh. - // - // PARAMETERS: - // nId - ID of string resource holding the format string - // szFormat - a PCSTR holding the format specifiers - // argList - a va_list holding the arguments for the format specifiers. - // - // RETURN VALUE: None. - // ------------------------------------------------------------------------- - // formatting (using wsprintf style formatting) - - // If they want a Format() function that safely handles string objects - // without casting - -#ifdef SS_SAFE_FORMAT - - // Question: Joe, you wacky coder you, why do you have so many overloads - // of the Format() function - // Answer: One reason only - CString compatability. In short, by making - // the Format() function a template this way, I can do strong typing - // and allow people to pass CStdString arguments as fillers for - // "%s" format specifiers without crashing their program! The downside - // is that I need to overload on the number of arguments. If you are - // passing more arguments than I have listed below in any of my - // overloads, just add another one. - // - // Yes, yes, this is really ugly. In essence what I am doing here is - // protecting people from a bad (and incorrect) programming practice - // that they should not be doing anyway. I am protecting them from - // themselves. Why am I doing this? Well, if you had any idea the - // number of times I've been emailed by people about this - // "incompatability" in my code, you wouldn't ask. - - void Fmt(const CT* szFmt, ...) - { - va_list argList; - va_start(argList, szFmt); - FormatV(szFmt, argList); - va_end(argList); - } - -#ifndef SS_ANSI - - void Format(UINT nId) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - this->swap(strFmt); - } - template - void Format(UINT nId, const A1& v) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - Fmt(strFmt, FmtArg(v)()); - } - template - void Format(UINT nId, const A1& v1, const A2& v2) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)()); - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(),FmtArg(v5)(), - FmtArg(v6)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(),FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(),FmtArg(v10)(),FmtArg(v11)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(), FmtArg(v13)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(), FmtArg(v13)(),FmtArg(v14)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14, const A15& v15) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(),FmtArg(v13)(),FmtArg(v14)(), - FmtArg(v15)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14, const A15& v15, - const A16& v16) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(),FmtArg(v13)(),FmtArg(v14)(), - FmtArg(v15)(), FmtArg(v16)()); - } - } - template - void Format(UINT nId, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14, const A15& v15, - const A16& v16, const A17& v17) - { - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - { - Fmt(strFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(),FmtArg(v13)(),FmtArg(v14)(), - FmtArg(v15)(),FmtArg(v16)(),FmtArg(v17)()); - } - } - -#endif // #ifndef SS_ANSI - - // ...now the other overload of Format: the one that takes a string literal - - void Format(const CT* szFmt) - { - *this = szFmt; - } - template - void Format(const CT* szFmt, const A1& v) - { - Fmt(szFmt, FmtArg(v)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(),FmtArg(v10)(),FmtArg(v11)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(), FmtArg(v13)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(), FmtArg(v13)(),FmtArg(v14)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14, const A15& v15) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(),FmtArg(v13)(),FmtArg(v14)(), - FmtArg(v15)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14, const A15& v15, - const A16& v16) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(),FmtArg(v13)(),FmtArg(v14)(), - FmtArg(v15)(), FmtArg(v16)()); - } - template - void Format(const CT* szFmt, const A1& v1, const A2& v2, const A3& v3, - const A4& v4, const A5& v5, const A6& v6, const A7& v7, - const A8& v8, const A9& v9, const A10& v10, const A11& v11, - const A12& v12, const A13& v13, const A14& v14, const A15& v15, - const A16& v16, const A17& v17) - { - Fmt(szFmt, FmtArg(v1)(), FmtArg(v2)(), - FmtArg(v3)(), FmtArg(v4)(), FmtArg(v5)(), - FmtArg(v6)(), FmtArg(v7)(), FmtArg(v8)(), - FmtArg(v9)(), FmtArg(v10)(),FmtArg(v11)(), - FmtArg(v12)(),FmtArg(v13)(),FmtArg(v14)(), - FmtArg(v15)(),FmtArg(v16)(),FmtArg(v17)()); - } - -#else // #ifdef SS_SAFE_FORMAT - - -#ifndef SS_ANSI - - void Format(UINT nId, ...) - { - va_list argList; - va_start(argList, nId); - - MYTYPE strFmt; - if ( strFmt.Load(nId) ) - FormatV(strFmt, argList); - - va_end(argList); - } - -#endif // #ifdef SS_ANSI - - void Format(const CT* szFmt, ...) - { - va_list argList; - va_start(argList, szFmt); - FormatV(szFmt, argList); - va_end(argList); - } - -#endif // #ifdef SS_SAFE_FORMAT - - void AppendFormat(const CT* szFmt, ...) - { - va_list argList; - va_start(argList, szFmt); - AppendFormatV(szFmt, argList); - va_end(argList); - } - - #define MAX_FMT_TRIES 5 // #of times we try - #define FMT_BLOCK_SIZE 2048 // # of bytes to increment per try - #define BUFSIZE_1ST 256 - #define BUFSIZE_2ND 512 - #define STD_BUF_SIZE 1024 - - // an efficient way to add formatted characters to the string. You may only - // add up to STD_BUF_SIZE characters at a time, though - void AppendFormatV(const CT* szFmt, va_list argList) - { - CT szBuf[STD_BUF_SIZE]; - int nLen = ssnprintf(szBuf, STD_BUF_SIZE-1, szFmt, argList); - - if ( 0 < nLen ) - this->append(szBuf, nLen); - } - - // ------------------------------------------------------------------------- - // FUNCTION: FormatV - // void FormatV(PCSTR szFormat, va_list, argList); - // - // DESCRIPTION: - // This function formats the string with sprintf style format-specs. - // It makes a general guess at required buffer size and then tries - // successively larger buffers until it finds one big enough or a - // threshold (MAX_FMT_TRIES) is exceeded. - // - // PARAMETERS: - // szFormat - a PCSTR holding the format of the output - // argList - a Microsoft specific va_list for variable argument lists - // - // RETURN VALUE: - // ------------------------------------------------------------------------- - - // NOTE: Changed by JM to actually function under non-win32, - // and to remove the upper limit on size. - void FormatV(const CT* szFormat, va_list argList) - { - // try and grab a sufficient buffersize - int nChars = FMT_BLOCK_SIZE; - va_list argCopy; - - CT *p = reinterpret_cast(malloc(sizeof(CT)*nChars)); - if (!p) return; - - while (1) - { - va_copy(argCopy, argList); - - int nActual = ssvsprintf(p, nChars, szFormat, argCopy); - /* If that worked, return the string. */ - if (nActual > -1 && nActual < nChars) - { /* make sure it's NULL terminated */ - p[nActual] = '\0'; - this->assign(p, nActual); - free(p); - va_end(argCopy); - return; - } - /* Else try again with more space. */ - if (nActual > -1) /* glibc 2.1 */ - nChars = nActual + 1; /* precisely what is needed */ - else /* glibc 2.0 */ - nChars *= 2; /* twice the old size */ - - CT *np = reinterpret_cast(realloc(p, sizeof(CT)*nChars)); - if (np == NULL) - { - free(p); - va_end(argCopy); - return; // failed :( - } - p = np; - va_end(argCopy); - } - } - - // ------------------------------------------------------------------------- - // CString Facade Functions: - // - // The following methods are intended to allow you to use this class as a - // near drop-in replacement for CString. - // ------------------------------------------------------------------------- - #ifdef SS_WIN32 - BSTR AllocSysString() const - { - ostring os; - ssasn(os, *this); - return ::SysAllocString(os.c_str()); - } - #endif - -#ifndef SS_NO_LOCALE - int Collate(PCMYSTR szThat) const - { - return sscoll(this->c_str(), this->length(), szThat, sslen(szThat)); - } - - int CollateNoCase(PCMYSTR szThat) const - { - return ssicoll(this->c_str(), this->length(), szThat, sslen(szThat)); - } -#endif - int Compare(PCMYSTR szThat) const - { - return this->compare(szThat); - } - - int CompareNoCase(PCMYSTR szThat) const - { - return ssicmp(this->c_str(), szThat); - } - - int Delete(int nIdx, int nCount=1) - { - if ( nIdx < 0 ) - nIdx = 0; - - if ( nIdx < this->GetLength() ) - this->erase(static_cast(nIdx), static_cast(nCount)); - - return GetLength(); - } - - void Empty() - { - this->erase(); - } - - int Find(CT ch) const - { - MYSIZE nIdx = this->find_first_of(ch); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int Find(PCMYSTR szSub) const - { - MYSIZE nIdx = this->find(szSub); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int Find(CT ch, int nStart) const - { - // CString::Find docs say add 1 to nStart when it's not zero - // CString::Find code doesn't do that however. We'll stick - // with what the code does - - MYSIZE nIdx = this->find_first_of(ch, static_cast(nStart)); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int Find(PCMYSTR szSub, int nStart) const - { - // CString::Find docs say add 1 to nStart when it's not zero - // CString::Find code doesn't do that however. We'll stick - // with what the code does - - MYSIZE nIdx = this->find(szSub, static_cast(nStart)); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - int FindOneOf(PCMYSTR szCharSet) const - { - MYSIZE nIdx = this->find_first_of(szCharSet); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - -#ifndef SS_ANSI - void FormatMessage(PCMYSTR szFormat, ...) throw(std::exception) - { - va_list argList; - va_start(argList, szFormat); - PMYSTR szTemp; - if ( ssfmtmsg(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, - szFormat, 0, 0, - reinterpret_cast(&szTemp), 0, &argList) == 0 || - szTemp == 0 ) - { - throw std::runtime_error("out of memory"); - } - *this = szTemp; - LocalFree(szTemp); - va_end(argList); - } - - void FormatMessage(UINT nFormatId, ...) throw(std::exception) - { - MYTYPE sFormat; - VERIFY(sFormat.LoadString(nFormatId)); - va_list argList; - va_start(argList, nFormatId); - PMYSTR szTemp; - if ( ssfmtmsg(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, - sFormat, 0, 0, - reinterpret_cast(&szTemp), 0, &argList) == 0 || - szTemp == 0) - { - throw std::runtime_error("out of memory"); - } - *this = szTemp; - LocalFree(szTemp); - va_end(argList); - } -#endif - - // GetAllocLength -- an MSVC7 function but it costs us nothing to add it. - - int GetAllocLength() - { - return static_cast(this->capacity()); - } - - // ------------------------------------------------------------------------- - // GetXXXX -- Direct access to character buffer - // ------------------------------------------------------------------------- - CT GetAt(int nIdx) const - { - return this->at(static_cast(nIdx)); - } - - CT* GetBuffer(int nMinLen=-1) - { - return GetBuf(nMinLen); - } - - CT* GetBufferSetLength(int nLen) - { - return BufferSet(nLen); - } - - // GetLength() -- MFC docs say this is the # of BYTES but - // in truth it is the number of CHARACTERs (chars or wchar_ts) - int GetLength() const - { - return static_cast(this->length()); - } - - int Insert(int nIdx, CT ch) - { - if ( static_cast(nIdx) > this->size()-1 ) - this->append(1, ch); - else - this->insert(static_cast(nIdx), 1, ch); - - return GetLength(); - } - int Insert(int nIdx, PCMYSTR sz) - { - if ( static_cast(nIdx) >= this->size() ) - this->append(sz, static_cast(sslen(sz))); - else - this->insert(static_cast(nIdx), sz); - - return GetLength(); - } - - bool IsEmpty() const - { - return this->empty(); - } - - MYTYPE Left(int nCount) const - { - // Range check the count. - - nCount = SSMAX(0, SSMIN(nCount, static_cast(this->size()))); - return this->substr(0, static_cast(nCount)); - } - -#ifndef SS_ANSI - bool LoadString(UINT nId) - { - return this->Load(nId); - } -#endif - - void MakeLower() - { - ToLower(); - } - - void MakeReverse() - { - std::reverse(this->begin(), this->end()); - } - - void MakeUpper() - { - ToUpper(); - } - - MYTYPE Mid(int nFirst) const - { - return Mid(nFirst, this->GetLength()-nFirst); - } - - MYTYPE Mid(int nFirst, int nCount) const - { - // CString does range checking here. Since we're trying to emulate it, - // we must check too. - - if ( nFirst < 0 ) - nFirst = 0; - if ( nCount < 0 ) - nCount = 0; - - int nSize = static_cast(this->size()); - - if ( nFirst + nCount > nSize ) - nCount = nSize - nFirst; - - if ( nFirst > nSize ) - return MYTYPE(); - - ASSERT(nFirst >= 0); - ASSERT(nFirst + nCount <= nSize); - - return this->substr(static_cast(nFirst), - static_cast(nCount)); - } - - void ReleaseBuffer(int nNewLen=-1) - { - RelBuf(nNewLen); - } - - int Remove(CT ch) - { - MYSIZE nIdx = 0; - int nRemoved = 0; - while ( (nIdx=this->find_first_of(ch)) != MYBASE::npos ) - { - this->erase(nIdx, 1); - nRemoved++; - } - return nRemoved; - } - - int Replace(CT chOld, CT chNew) - { - int nReplaced = 0; - - for ( MYITER iter=this->begin(); iter != this->end(); iter++ ) - { - if ( *iter == chOld ) - { - *iter = chNew; - nReplaced++; - } - } - - return nReplaced; - } - - int Replace(PCMYSTR szOld, PCMYSTR szNew) - { - int nReplaced = 0; - MYSIZE nIdx = 0; - MYSIZE nOldLen = sslen(szOld); - - if ( 0 != nOldLen ) - { - // If the replacement string is longer than the one it replaces, this - // string is going to have to grow in size, Figure out how much - // and grow it all the way now, rather than incrementally - - MYSIZE nNewLen = sslen(szNew); - if ( nNewLen > nOldLen ) - { - int nFound = 0; - while ( nIdx < this->length() && - (nIdx=this->find(szOld, nIdx)) != MYBASE::npos ) - { - nFound++; - nIdx += nOldLen; - } - this->reserve(this->size() + nFound * (nNewLen - nOldLen)); - } - - - static const CT ch = CT(0); - PCMYSTR szRealNew = szNew == 0 ? &ch : szNew; - nIdx = 0; - - while ( nIdx < this->length() && - (nIdx=this->find(szOld, nIdx)) != MYBASE::npos ) - { - this->replace(this->begin()+nIdx, this->begin()+nIdx+nOldLen, - szRealNew); - - nReplaced++; - nIdx += nNewLen; - } - } - - return nReplaced; - } - - int ReverseFind(CT ch) const - { - MYSIZE nIdx = this->find_last_of(ch); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - // ReverseFind overload that's not in CString but might be useful - int ReverseFind(PCMYSTR szFind, MYSIZE pos=MYBASE::npos) const - { - //yuvalt - this does not compile with g++ since MYTTYPE() is different type - //MYSIZE nIdx = this->rfind(0 == szFind ? MYTYPE() : szFind, pos); - MYSIZE nIdx = this->rfind(0 == szFind ? "" : szFind, pos); - return static_cast(MYBASE::npos == nIdx ? -1 : nIdx); - } - - MYTYPE Right(int nCount) const - { - // Range check the count. - - nCount = SSMAX(0, SSMIN(nCount, static_cast(this->size()))); - return this->substr(this->size()-static_cast(nCount)); - } - - void SetAt(int nIndex, CT ch) - { - ASSERT(this->size() > static_cast(nIndex)); - this->at(static_cast(nIndex)) = ch; - } - -#ifndef SS_ANSI - BSTR SetSysString(BSTR* pbstr) const - { - ostring os; - ssasn(os, *this); - if ( !::SysReAllocStringLen(pbstr, os.c_str(), os.length()) ) - throw std::runtime_error("out of memory"); - - ASSERT(*pbstr != 0); - return *pbstr; - } -#endif - - MYTYPE SpanExcluding(PCMYSTR szCharSet) const - { - MYSIZE pos = this->find_first_of(szCharSet); - return pos == MYBASE::npos ? *this : Left(pos); - } - - MYTYPE SpanIncluding(PCMYSTR szCharSet) const - { - MYSIZE pos = this->find_first_not_of(szCharSet); - return pos == MYBASE::npos ? *this : Left(pos); - } - -#if defined SS_WIN32 && !defined(UNICODE) && !defined(SS_ANSI) - - // CString's OemToAnsi and AnsiToOem functions are available only in - // Unicode builds. However since we're a template we also need a - // runtime check of CT and a reinterpret_cast to account for the fact - // that CStdStringW gets instantiated even in non-Unicode builds. - - void AnsiToOem() - { - if ( sizeof(CT) == sizeof(char) && !empty() ) - { - ::CharToOem(reinterpret_cast(this->c_str()), - reinterpret_cast(GetBuf())); - } - else - { - ASSERT(false); - } - } - - void OemToAnsi() - { - if ( sizeof(CT) == sizeof(char) && !empty() ) - { - ::OemToChar(reinterpret_cast(this->c_str()), - reinterpret_cast(GetBuf())); - } - else - { - ASSERT(false); - } - } - -#endif - - - // ------------------------------------------------------------------------- - // Trim and its variants - // ------------------------------------------------------------------------- - MYTYPE& Trim() - { - return TrimLeft().TrimRight(); - } - - MYTYPE& TrimLeft() - { - this->erase(this->begin(), - std::find_if(this->begin(), this->end(), NotSpace())); - - return *this; - } - - MYTYPE& TrimLeft(CT tTrim) - { - this->erase(0, this->find_first_not_of(tTrim)); - return *this; - } - - MYTYPE& TrimLeft(PCMYSTR szTrimChars) - { - this->erase(0, this->find_first_not_of(szTrimChars)); - return *this; - } - - MYTYPE& TrimRight() - { - // NOTE: When comparing reverse_iterators here (MYRITER), I avoid using - // operator!=. This is because namespace rel_ops also has a template - // operator!= which conflicts with the global operator!= already defined - // for reverse_iterator in the header . - // Thanks to John James for alerting me to this. - - MYRITER it = std::find_if(this->rbegin(), this->rend(), NotSpace()); - if ( !(this->rend() == it) ) - this->erase(this->rend() - it); - - this->erase(!(it == this->rend()) ? this->find_last_of(*it) + 1 : 0); - return *this; - } - - MYTYPE& TrimRight(CT tTrim) - { - MYSIZE nIdx = this->find_last_not_of(tTrim); - this->erase(MYBASE::npos == nIdx ? 0 : ++nIdx); - return *this; - } - - MYTYPE& TrimRight(PCMYSTR szTrimChars) - { - MYSIZE nIdx = this->find_last_not_of(szTrimChars); - this->erase(MYBASE::npos == nIdx ? 0 : ++nIdx); - return *this; - } - - void FreeExtra() - { - MYTYPE mt; - this->swap(mt); - if ( !mt.empty() ) - this->assign(mt.c_str(), mt.size()); - } - - // I have intentionally not implemented the following CString - // functions. You cannot make them work without taking advantage - // of implementation specific behavior. However if you absolutely - // MUST have them, uncomment out these lines for "sort-of-like" - // their behavior. You're on your own. - -// CT* LockBuffer() { return GetBuf(); }// won't really lock -// void UnlockBuffer(); { } // why have UnlockBuffer w/o LockBuffer? - - // Array-indexing operators. Required because we defined an implicit cast - // to operator const CT* (Thanks to Julian Selman for pointing this out) - - CT& operator[](int nIdx) - { - return static_cast(this)->operator[](static_cast(nIdx)); - } - - const CT& operator[](int nIdx) const - { - return static_cast(this)->operator[](static_cast(nIdx)); - } - - CT& operator[](unsigned int nIdx) - { - return static_cast(this)->operator[](static_cast(nIdx)); - } - - const CT& operator[](unsigned int nIdx) const - { - return static_cast(this)->operator[](static_cast(nIdx)); - } - - CT& operator[](unsigned long nIdx) - { - return static_cast(this)->operator[](static_cast(nIdx)); - } - - const CT& operator[](unsigned long nIdx) const - { - return static_cast(this)->operator[](static_cast(nIdx)); - } - -#ifndef SS_NO_IMPLICIT_CAST - operator const CT*() const - { - return this->c_str(); - } -#endif - - // IStream related functions. Useful in IPersistStream implementations - -#ifdef SS_INC_COMDEF - - // struct SSSHDR - useful for non Std C++ persistence schemes. - typedef struct SSSHDR - { - BYTE byCtrl; - ULONG nChars; - } SSSHDR; // as in "Standard String Stream Header" - - #define SSSO_UNICODE 0x01 // the string is a wide string - #define SSSO_COMPRESS 0x02 // the string is compressed - - // ------------------------------------------------------------------------- - // FUNCTION: StreamSize - // REMARKS: - // Returns how many bytes it will take to StreamSave() this CStdString - // object to an IStream. - // ------------------------------------------------------------------------- - ULONG StreamSize() const - { - // Control header plus string - ASSERT(this->size()*sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); - return (this->size() * sizeof(CT)) + sizeof(SSSHDR); - } - - // ------------------------------------------------------------------------- - // FUNCTION: StreamSave - // REMARKS: - // Saves this CStdString object to a COM IStream. - // ------------------------------------------------------------------------- - HRESULT StreamSave(IStream* pStream) const - { - ASSERT(this->size()*sizeof(CT) < 0xffffffffUL - sizeof(SSSHDR)); - HRESULT hr = E_FAIL; - ASSERT(pStream != 0); - SSSHDR hdr; - hdr.byCtrl = sizeof(CT) == 2 ? SSSO_UNICODE : 0; - hdr.nChars = this->size(); - - - if ( FAILED(hr=pStream->Write(&hdr, sizeof(SSSHDR), 0)) ) - { - TRACE(_T("StreamSave: Cannot write control header, ERR=0x%X\n"),hr); - } - else if ( empty() ) - { - ; // nothing to write - } - else if ( FAILED(hr=pStream->Write(this->c_str(), - this->size()*sizeof(CT), 0)) ) - { - TRACE(_T("StreamSave: Cannot write string to stream 0x%X\n"), hr); - } - - return hr; - } - - - // ------------------------------------------------------------------------- - // FUNCTION: StreamLoad - // REMARKS: - // This method loads the object from an IStream. - // ------------------------------------------------------------------------- - HRESULT StreamLoad(IStream* pStream) - { - ASSERT(pStream != 0); - SSSHDR hdr; - HRESULT hr = E_FAIL; - - if ( FAILED(hr=pStream->Read(&hdr, sizeof(SSSHDR), 0)) ) - { - TRACE(_T("StreamLoad: Cant read control header, ERR=0x%X\n"), hr); - } - else if ( hdr.nChars > 0 ) - { - ULONG nRead = 0; - PMYSTR pMyBuf = BufferSet(hdr.nChars); - - // If our character size matches the character size of the string - // we're trying to read, then we can read it directly into our - // buffer. Otherwise, we have to read into an intermediate buffer - // and convert. - - if ( (hdr.byCtrl & SSSO_UNICODE) != 0 ) - { - ULONG nBytes = hdr.nChars * sizeof(wchar_t); - if ( sizeof(CT) == sizeof(wchar_t) ) - { - if ( FAILED(hr=pStream->Read(pMyBuf, nBytes, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - } - else - { - PWSTR pBufW = reinterpret_cast(_alloca((nBytes)+1)); - if ( FAILED(hr=pStream->Read(pBufW, nBytes, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - else - sscpy(pMyBuf, pBufW, hdr.nChars); - } - } - else - { - ULONG nBytes = hdr.nChars * sizeof(char); - if ( sizeof(CT) == sizeof(char) ) - { - if ( FAILED(hr=pStream->Read(pMyBuf, nBytes, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - } - else - { - PSTR pBufA = reinterpret_cast(_alloca(nBytes)); - if ( FAILED(hr=pStream->Read(pBufA, hdr.nChars, &nRead)) ) - TRACE(_T("StreamLoad: Cannot read string: 0x%X\n"), hr); - else - sscpy(pMyBuf, pBufA, hdr.nChars); - } - } - } - else - { - this->erase(); - } - return hr; - } -#endif // #ifdef SS_INC_COMDEF - -#ifndef SS_ANSI - - // SetResourceHandle/GetResourceHandle. In MFC builds, these map directly - // to AfxSetResourceHandle and AfxGetResourceHandle. In non-MFC builds they - // point to a single static HINST so that those who call the member - // functions that take resource IDs can provide an alternate HINST of a DLL - // to search. This is not exactly the list of HMODULES that MFC provides - // but it's better than nothing. - - #ifdef _MFC_VER - static void SetResourceHandle(HMODULE hNew) - { - AfxSetResourceHandle(hNew); - } - static HMODULE GetResourceHandle() - { - return AfxGetResourceHandle(); - } - #else - static void SetResourceHandle(HMODULE hNew) - { - SSResourceHandle() = hNew; - } - static HMODULE GetResourceHandle() - { - return SSResourceHandle(); - } - #endif - -#endif -}; - -// ----------------------------------------------------------------------------- -// MSVC USERS: HOW TO EXPORT CSTDSTRING FROM A DLL -// -// If you are using MS Visual C++ and you want to export CStdStringA and -// CStdStringW from a DLL, then all you need to -// -// 1. make sure that all components link to the same DLL version -// of the CRT (not the static one). -// 2. Uncomment the 3 lines of code below -// 3. #define 2 macros per the instructions in MS KnowledgeBase -// article Q168958. The macros are: -// -// MACRO DEFINTION WHEN EXPORTING DEFINITION WHEN IMPORTING -// ----- ------------------------ ------------------------- -// SSDLLEXP (nothing, just #define it) extern -// SSDLLSPEC __declspec(dllexport) __declspec(dllimport) -// -// Note that these macros must be available to ALL clients who want to -// link to the DLL and use the class. If they -// -// A word of advice: Don't bother. -// -// Really, it is not necessary to export CStdString functions from a DLL. I -// never do. In my projects, I do generally link to the DLL version of the -// Standard C++ Library, but I do NOT attempt to export CStdString functions. -// I simply include the header where it is needed and allow for the code -// redundancy. -// -// That redundancy is a lot less than you think. This class does most of its -// work via the Standard C++ Library, particularly the base_class basic_string<> -// member functions. Most of the functions here are small enough to be inlined -// anyway. Besides, you'll find that in actual practice you use less than 1/2 -// of the code here, even in big projects and different modules will use as -// little as 10% of it. That means a lot less functions actually get linked -// your binaries. If you export this code from a DLL, it ALL gets linked in. -// -// I've compared the size of the binaries from exporting vs NOT exporting. Take -// my word for it -- exporting this code is not worth the hassle. -// -// ----------------------------------------------------------------------------- -//#pragma warning(disable:4231) // non-standard extension ("extern template") -// SSDLLEXP template class SSDLLSPEC CStdStr; -// SSDLLEXP template class SSDLLSPEC CStdStr; - - -// ============================================================================= -// END OF CStdStr INLINE FUNCTION DEFINITIONS -// ============================================================================= - -// Now typedef our class names based upon this humongous template - -typedef CStdStr CStdStringA; // a better std::string -typedef CStdStr CStdStringW; // a better std::wstring -typedef CStdStr CStdString16; // a 16bit char string -typedef CStdStr CStdString32; // a 32bit char string -typedef CStdStr CStdStringO; // almost always CStdStringW - -// ----------------------------------------------------------------------------- -// CStdStr addition functions defined as inline -// ----------------------------------------------------------------------------- - - -inline CStdStringA operator+(const CStdStringA& s1, const CStdStringA& s2) -{ - CStdStringA sRet(SSREF(s1)); - sRet.append(s2); - return sRet; -} -inline CStdStringA operator+(const CStdStringA& s1, CStdStringA::value_type t) -{ - CStdStringA sRet(SSREF(s1)); - sRet.append(1, t); - return sRet; -} -inline CStdStringA operator+(const CStdStringA& s1, PCSTR pA) -{ - CStdStringA sRet(SSREF(s1)); - sRet.append(pA); - return sRet; -} -inline CStdStringA operator+(PCSTR pA, const CStdStringA& sA) -{ - CStdStringA sRet; - CStdStringA::size_type nObjSize = sA.size(); - CStdStringA::size_type nLitSize = - static_cast(sslen(pA)); - - sRet.reserve(nLitSize + nObjSize); - sRet.assign(pA); - sRet.append(sA); - return sRet; -} - - -inline CStdStringA operator+(const CStdStringA& s1, const CStdStringW& s2) -{ - return s1 + CStdStringA(s2); -} -inline CStdStringW operator+(const CStdStringW& s1, const CStdStringW& s2) -{ - CStdStringW sRet(SSREF(s1)); - sRet.append(s2); - return sRet; -} -inline CStdStringA operator+(const CStdStringA& s1, PCWSTR pW) -{ - return s1 + CStdStringA(pW); -} - -#ifdef UNICODE - inline CStdStringW operator+(PCWSTR pW, const CStdStringA& sA) - { - return CStdStringW(pW) + CStdStringW(SSREF(sA)); - } - inline CStdStringW operator+(PCSTR pA, const CStdStringW& sW) - { - return CStdStringW(pA) + sW; - } -#else - inline CStdStringA operator+(PCWSTR pW, const CStdStringA& sA) - { - return CStdStringA(pW) + sA; - } - inline CStdStringA operator+(PCSTR pA, const CStdStringW& sW) - { - return pA + CStdStringA(sW); - } -#endif - -// ...Now the wide string versions. -inline CStdStringW operator+(const CStdStringW& s1, CStdStringW::value_type t) -{ - CStdStringW sRet(SSREF(s1)); - sRet.append(1, t); - return sRet; -} -inline CStdStringW operator+(const CStdStringW& s1, PCWSTR pW) -{ - CStdStringW sRet(SSREF(s1)); - sRet.append(pW); - return sRet; -} -inline CStdStringW operator+(PCWSTR pW, const CStdStringW& sW) -{ - CStdStringW sRet; - CStdStringW::size_type nObjSize = sW.size(); - CStdStringA::size_type nLitSize = - static_cast(sslen(pW)); - - sRet.reserve(nLitSize + nObjSize); - sRet.assign(pW); - sRet.append(sW); - return sRet; -} - -inline CStdStringW operator+(const CStdStringW& s1, const CStdStringA& s2) -{ - return s1 + CStdStringW(s2); -} -inline CStdStringW operator+(const CStdStringW& s1, PCSTR pA) -{ - return s1 + CStdStringW(pA); -} - - -// New-style format function is a template - -#ifdef SS_SAFE_FORMAT - -template<> -struct FmtArg -{ - explicit FmtArg(const CStdStringA& arg) : a_(arg) {} - PCSTR operator()() const { return a_.c_str(); } - const CStdStringA& a_; -private: - FmtArg& operator=(const FmtArg&) { return *this; } -}; -template<> -struct FmtArg -{ - explicit FmtArg(const CStdStringW& arg) : a_(arg) {} - PCWSTR operator()() const { return a_.c_str(); } - const CStdStringW& a_; -private: - FmtArg& operator=(const FmtArg&) { return *this; } -}; - -template<> -struct FmtArg -{ - explicit FmtArg(const std::string& arg) : a_(arg) {} - PCSTR operator()() const { return a_.c_str(); } - const std::string& a_; -private: - FmtArg& operator=(const FmtArg&) { return *this; } -}; -template<> -struct FmtArg -{ - explicit FmtArg(const std::wstring& arg) : a_(arg) {} - PCWSTR operator()() const { return a_.c_str(); } - const std::wstring& a_; -private: - FmtArg& operator=(const FmtArg&) {return *this;} -}; -#endif // #ifdef SS_SAFEFORMAT - -#ifndef SS_ANSI - // SSResourceHandle: our MFC-like resource handle - inline HMODULE& SSResourceHandle() - { - static HMODULE hModuleSS = GetModuleHandle(0); - return hModuleSS; - } -#endif - - -// In MFC builds, define some global serialization operators -// Special operators that allow us to serialize CStdStrings to CArchives. -// Note that we use an intermediate CString object in order to ensure that -// we use the exact same format. - -#ifdef _MFC_VER - inline CArchive& AFXAPI operator<<(CArchive& ar, const CStdStringA& strA) - { - CString strTemp = strA; - return ar << strTemp; - } - inline CArchive& AFXAPI operator<<(CArchive& ar, const CStdStringW& strW) - { - CString strTemp = strW; - return ar << strTemp; - } - - inline CArchive& AFXAPI operator>>(CArchive& ar, CStdStringA& strA) - { - CString strTemp; - ar >> strTemp; - strA = strTemp; - return ar; - } - inline CArchive& AFXAPI operator>>(CArchive& ar, CStdStringW& strW) - { - CString strTemp; - ar >> strTemp; - strW = strTemp; - return ar; - } -#endif // #ifdef _MFC_VER -- (i.e. is this MFC?) - - - -// ----------------------------------------------------------------------------- -// GLOBAL FUNCTION: WUFormat -// CStdStringA WUFormat(UINT nId, ...); -// CStdStringA WUFormat(PCSTR szFormat, ...); -// -// REMARKS: -// This function allows the caller for format and return a CStdStringA -// object with a single line of code. -// ----------------------------------------------------------------------------- -#ifdef SS_ANSI -#else - inline CStdStringA WUFormatA(UINT nId, ...) - { - va_list argList; - va_start(argList, nId); - - CStdStringA strFmt; - CStdStringA strOut; - if ( strFmt.Load(nId) ) - strOut.FormatV(strFmt, argList); - - va_end(argList); - return strOut; - } - inline CStdStringA WUFormatA(PCSTR szFormat, ...) - { - va_list argList; - va_start(argList, szFormat); - CStdStringA strOut; - strOut.FormatV(szFormat, argList); - va_end(argList); - return strOut; - } - inline CStdStringW WUFormatW(UINT nId, ...) - { - va_list argList; - va_start(argList, nId); - - CStdStringW strFmt; - CStdStringW strOut; - if ( strFmt.Load(nId) ) - strOut.FormatV(strFmt, argList); - - va_end(argList); - return strOut; - } - inline CStdStringW WUFormatW(PCWSTR szwFormat, ...) - { - va_list argList; - va_start(argList, szwFormat); - CStdStringW strOut; - strOut.FormatV(szwFormat, argList); - va_end(argList); - return strOut; - } -#endif // #ifdef SS_ANSI - - - -#if defined(SS_WIN32) && !defined (SS_ANSI) - // ------------------------------------------------------------------------- - // FUNCTION: WUSysMessage - // CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); - // CStdStringW WUSysMessageW(DWORD dwError, DWORD dwLangId=SS_DEFLANGID); - // - // DESCRIPTION: - // This function simplifies the process of obtaining a string equivalent - // of a system error code returned from GetLastError(). You simply - // supply the value returned by GetLastError() to this function and the - // corresponding system string is returned in the form of a CStdStringA. - // - // PARAMETERS: - // dwError - a DWORD value representing the error code to be translated - // dwLangId - the language id to use. defaults to english. - // - // RETURN VALUE: - // a CStdStringA equivalent of the error code. Currently, this function - // only returns either English of the system default language strings. - // ------------------------------------------------------------------------- - #define SS_DEFLANGID MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT) - inline CStdStringA WUSysMessageA(DWORD dwError, DWORD dwLangId=SS_DEFLANGID) - { - CHAR szBuf[512]; - - if ( 0 != ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, - dwLangId, szBuf, 511, NULL) ) - return WUFormatA("%s (0x%X)", szBuf, dwError); - else - return WUFormatA("Unknown error (0x%X)", dwError); - } - inline CStdStringW WUSysMessageW(DWORD dwError, DWORD dwLangId=SS_DEFLANGID) - { - WCHAR szBuf[512]; - - if ( 0 != ::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, - dwLangId, szBuf, 511, NULL) ) - return WUFormatW(L"%s (0x%X)", szBuf, dwError); - else - return WUFormatW(L"Unknown error (0x%X)", dwError); - } -#endif - -// Define TCHAR based friendly names for some of these functions - -#ifdef UNICODE - //#define CStdString CStdStringW - typedef CStdStringW CStdString; - #define WUSysMessage WUSysMessageW - #define WUFormat WUFormatW -#else - //#define CStdString CStdStringA - typedef CStdStringA CStdString; - #define WUSysMessage WUSysMessageA - #define WUFormat WUFormatA -#endif - -// ...and some shorter names for the space-efficient - -#define WUSysMsg WUSysMessage -#define WUSysMsgA WUSysMessageA -#define WUSysMsgW WUSysMessageW -#define WUFmtA WUFormatA -#define WUFmtW WUFormatW -#define WUFmt WUFormat -#define WULastErrMsg() WUSysMessage(::GetLastError()) -#define WULastErrMsgA() WUSysMessageA(::GetLastError()) -#define WULastErrMsgW() WUSysMessageW(::GetLastError()) - - -// ----------------------------------------------------------------------------- -// FUNCTIONAL COMPARATORS: -// REMARKS: -// These structs are derived from the std::binary_function template. They -// give us functional classes (which may be used in Standard C++ Library -// collections and algorithms) that perform case-insensitive comparisons of -// CStdString objects. This is useful for maps in which the key may be the -// proper string but in the wrong case. -// ----------------------------------------------------------------------------- -#define StdStringLessNoCaseW SSLNCW // avoid VC compiler warning 4786 -#define StdStringEqualsNoCaseW SSENCW -#define StdStringLessNoCaseA SSLNCA -#define StdStringEqualsNoCaseA SSENCA - -#ifdef UNICODE - #define StdStringLessNoCase SSLNCW - #define StdStringEqualsNoCase SSENCW -#else - #define StdStringLessNoCase SSLNCA - #define StdStringEqualsNoCase SSENCA -#endif - -struct StdStringLessNoCaseW - : std::binary_function -{ - inline - bool operator()(const CStdStringW& sLeft, const CStdStringW& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; } -}; -struct StdStringEqualsNoCaseW - : std::binary_function -{ - inline - bool operator()(const CStdStringW& sLeft, const CStdStringW& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; } -}; -struct StdStringLessNoCaseA - : std::binary_function -{ - inline - bool operator()(const CStdStringA& sLeft, const CStdStringA& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) < 0; } -}; -struct StdStringEqualsNoCaseA - : std::binary_function -{ - inline - bool operator()(const CStdStringA& sLeft, const CStdStringA& sRight) const - { return ssicmp(sLeft.c_str(), sRight.c_str()) == 0; } -}; - -// If we had to define our own version of TRACE above, get rid of it now - -#ifdef TRACE_DEFINED_HERE - #undef TRACE - #undef TRACE_DEFINED_HERE -#endif - - -// These std::swap specializations come courtesy of Mike Crusader. - -//namespace std -//{ -// inline void swap(CStdStringA& s1, CStdStringA& s2) throw() -// { -// s1.swap(s2); -// } -// template<> -// inline void swap(CStdStringW& s1, CStdStringW& s2) throw() -// { -// s1.swap(s2); -// } -//} - -// Turn back on any Borland warnings we turned off. - -#ifdef __BORLANDC__ - #pragma option pop // Turn back on inline function warnings -// #pragma warn +inl // Turn back on inline function warnings -#endif - -typedef std::vector CStdStringArray; - -#endif // #ifndef STDSTRING_H diff -Nru kodiplatform-15.0.0/src/util/StringUtils.cpp kodiplatform-16.0.0/src/util/StringUtils.cpp --- kodiplatform-15.0.0/src/util/StringUtils.cpp 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/StringUtils.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1174 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ -//----------------------------------------------------------------------- -// -// File: StringUtils.cpp -// -// Purpose: ATL split string utility -// Author: Paul J. Weiss -// -// Modified to use J O'Leary's std::string class by kraqh3d -// -//------------------------------------------------------------------------ - - -#include "StringUtils.h" -#include "fstrcmp.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define FORMAT_BLOCK_SIZE 2048 // # of bytes to increment per try - -using namespace std; - -/* empty string for use in returns by ref */ -const std::string StringUtils::Empty = ""; -std::string StringUtils::m_lastUUID = ""; - -// Copyright (c) Leigh Brasington 2012. All rights reserved. -// This code may be used and reproduced without written permission. -// http://www.leighb.com/tounicupper.htm -// -// The tables were constructed from -// http://publib.boulder.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Fnls%2Frbagslowtoupmaptable.htm - -static wchar_t unicode_lowers[] = { - (wchar_t)0x0061, (wchar_t)0x0062, (wchar_t)0x0063, (wchar_t)0x0064, (wchar_t)0x0065, (wchar_t)0x0066, (wchar_t)0x0067, (wchar_t)0x0068, (wchar_t)0x0069, - (wchar_t)0x006A, (wchar_t)0x006B, (wchar_t)0x006C, (wchar_t)0x006D, (wchar_t)0x006E, (wchar_t)0x006F, (wchar_t)0x0070, (wchar_t)0x0071, (wchar_t)0x0072, - (wchar_t)0x0073, (wchar_t)0x0074, (wchar_t)0x0075, (wchar_t)0x0076, (wchar_t)0x0077, (wchar_t)0x0078, (wchar_t)0x0079, (wchar_t)0x007A, (wchar_t)0x00E0, - (wchar_t)0x00E1, (wchar_t)0x00E2, (wchar_t)0x00E3, (wchar_t)0x00E4, (wchar_t)0x00E5, (wchar_t)0x00E6, (wchar_t)0x00E7, (wchar_t)0x00E8, (wchar_t)0x00E9, - (wchar_t)0x00EA, (wchar_t)0x00EB, (wchar_t)0x00EC, (wchar_t)0x00ED, (wchar_t)0x00EE, (wchar_t)0x00EF, (wchar_t)0x00F0, (wchar_t)0x00F1, (wchar_t)0x00F2, - (wchar_t)0x00F3, (wchar_t)0x00F4, (wchar_t)0x00F5, (wchar_t)0x00F6, (wchar_t)0x00F8, (wchar_t)0x00F9, (wchar_t)0x00FA, (wchar_t)0x00FB, (wchar_t)0x00FC, - (wchar_t)0x00FD, (wchar_t)0x00FE, (wchar_t)0x00FF, (wchar_t)0x0101, (wchar_t)0x0103, (wchar_t)0x0105, (wchar_t)0x0107, (wchar_t)0x0109, (wchar_t)0x010B, - (wchar_t)0x010D, (wchar_t)0x010F, (wchar_t)0x0111, (wchar_t)0x0113, (wchar_t)0x0115, (wchar_t)0x0117, (wchar_t)0x0119, (wchar_t)0x011B, (wchar_t)0x011D, - (wchar_t)0x011F, (wchar_t)0x0121, (wchar_t)0x0123, (wchar_t)0x0125, (wchar_t)0x0127, (wchar_t)0x0129, (wchar_t)0x012B, (wchar_t)0x012D, (wchar_t)0x012F, - (wchar_t)0x0131, (wchar_t)0x0133, (wchar_t)0x0135, (wchar_t)0x0137, (wchar_t)0x013A, (wchar_t)0x013C, (wchar_t)0x013E, (wchar_t)0x0140, (wchar_t)0x0142, - (wchar_t)0x0144, (wchar_t)0x0146, (wchar_t)0x0148, (wchar_t)0x014B, (wchar_t)0x014D, (wchar_t)0x014F, (wchar_t)0x0151, (wchar_t)0x0153, (wchar_t)0x0155, - (wchar_t)0x0157, (wchar_t)0x0159, (wchar_t)0x015B, (wchar_t)0x015D, (wchar_t)0x015F, (wchar_t)0x0161, (wchar_t)0x0163, (wchar_t)0x0165, (wchar_t)0x0167, - (wchar_t)0x0169, (wchar_t)0x016B, (wchar_t)0x016D, (wchar_t)0x016F, (wchar_t)0x0171, (wchar_t)0x0173, (wchar_t)0x0175, (wchar_t)0x0177, (wchar_t)0x017A, - (wchar_t)0x017C, (wchar_t)0x017E, (wchar_t)0x0183, (wchar_t)0x0185, (wchar_t)0x0188, (wchar_t)0x018C, (wchar_t)0x0192, (wchar_t)0x0199, (wchar_t)0x01A1, - (wchar_t)0x01A3, (wchar_t)0x01A5, (wchar_t)0x01A8, (wchar_t)0x01AD, (wchar_t)0x01B0, (wchar_t)0x01B4, (wchar_t)0x01B6, (wchar_t)0x01B9, (wchar_t)0x01BD, - (wchar_t)0x01C6, (wchar_t)0x01C9, (wchar_t)0x01CC, (wchar_t)0x01CE, (wchar_t)0x01D0, (wchar_t)0x01D2, (wchar_t)0x01D4, (wchar_t)0x01D6, (wchar_t)0x01D8, - (wchar_t)0x01DA, (wchar_t)0x01DC, (wchar_t)0x01DF, (wchar_t)0x01E1, (wchar_t)0x01E3, (wchar_t)0x01E5, (wchar_t)0x01E7, (wchar_t)0x01E9, (wchar_t)0x01EB, - (wchar_t)0x01ED, (wchar_t)0x01EF, (wchar_t)0x01F3, (wchar_t)0x01F5, (wchar_t)0x01FB, (wchar_t)0x01FD, (wchar_t)0x01FF, (wchar_t)0x0201, (wchar_t)0x0203, - (wchar_t)0x0205, (wchar_t)0x0207, (wchar_t)0x0209, (wchar_t)0x020B, (wchar_t)0x020D, (wchar_t)0x020F, (wchar_t)0x0211, (wchar_t)0x0213, (wchar_t)0x0215, - (wchar_t)0x0217, (wchar_t)0x0253, (wchar_t)0x0254, (wchar_t)0x0257, (wchar_t)0x0258, (wchar_t)0x0259, (wchar_t)0x025B, (wchar_t)0x0260, (wchar_t)0x0263, - (wchar_t)0x0268, (wchar_t)0x0269, (wchar_t)0x026F, (wchar_t)0x0272, (wchar_t)0x0275, (wchar_t)0x0283, (wchar_t)0x0288, (wchar_t)0x028A, (wchar_t)0x028B, - (wchar_t)0x0292, (wchar_t)0x03AC, (wchar_t)0x03AD, (wchar_t)0x03AE, (wchar_t)0x03AF, (wchar_t)0x03B1, (wchar_t)0x03B2, (wchar_t)0x03B3, (wchar_t)0x03B4, - (wchar_t)0x03B5, (wchar_t)0x03B6, (wchar_t)0x03B7, (wchar_t)0x03B8, (wchar_t)0x03B9, (wchar_t)0x03BA, (wchar_t)0x03BB, (wchar_t)0x03BC, (wchar_t)0x03BD, - (wchar_t)0x03BE, (wchar_t)0x03BF, (wchar_t)0x03C0, (wchar_t)0x03C1, (wchar_t)0x03C3, (wchar_t)0x03C4, (wchar_t)0x03C5, (wchar_t)0x03C6, (wchar_t)0x03C7, - (wchar_t)0x03C8, (wchar_t)0x03C9, (wchar_t)0x03CA, (wchar_t)0x03CB, (wchar_t)0x03CC, (wchar_t)0x03CD, (wchar_t)0x03CE, (wchar_t)0x03E3, (wchar_t)0x03E5, - (wchar_t)0x03E7, (wchar_t)0x03E9, (wchar_t)0x03EB, (wchar_t)0x03ED, (wchar_t)0x03EF, (wchar_t)0x0430, (wchar_t)0x0431, (wchar_t)0x0432, (wchar_t)0x0433, - (wchar_t)0x0434, (wchar_t)0x0435, (wchar_t)0x0436, (wchar_t)0x0437, (wchar_t)0x0438, (wchar_t)0x0439, (wchar_t)0x043A, (wchar_t)0x043B, (wchar_t)0x043C, - (wchar_t)0x043D, (wchar_t)0x043E, (wchar_t)0x043F, (wchar_t)0x0440, (wchar_t)0x0441, (wchar_t)0x0442, (wchar_t)0x0443, (wchar_t)0x0444, (wchar_t)0x0445, - (wchar_t)0x0446, (wchar_t)0x0447, (wchar_t)0x0448, (wchar_t)0x0449, (wchar_t)0x044A, (wchar_t)0x044B, (wchar_t)0x044C, (wchar_t)0x044D, (wchar_t)0x044E, - (wchar_t)0x044F, (wchar_t)0x0451, (wchar_t)0x0452, (wchar_t)0x0453, (wchar_t)0x0454, (wchar_t)0x0455, (wchar_t)0x0456, (wchar_t)0x0457, (wchar_t)0x0458, - (wchar_t)0x0459, (wchar_t)0x045A, (wchar_t)0x045B, (wchar_t)0x045C, (wchar_t)0x045E, (wchar_t)0x045F, (wchar_t)0x0461, (wchar_t)0x0463, (wchar_t)0x0465, - (wchar_t)0x0467, (wchar_t)0x0469, (wchar_t)0x046B, (wchar_t)0x046D, (wchar_t)0x046F, (wchar_t)0x0471, (wchar_t)0x0473, (wchar_t)0x0475, (wchar_t)0x0477, - (wchar_t)0x0479, (wchar_t)0x047B, (wchar_t)0x047D, (wchar_t)0x047F, (wchar_t)0x0481, (wchar_t)0x0491, (wchar_t)0x0493, (wchar_t)0x0495, (wchar_t)0x0497, - (wchar_t)0x0499, (wchar_t)0x049B, (wchar_t)0x049D, (wchar_t)0x049F, (wchar_t)0x04A1, (wchar_t)0x04A3, (wchar_t)0x04A5, (wchar_t)0x04A7, (wchar_t)0x04A9, - (wchar_t)0x04AB, (wchar_t)0x04AD, (wchar_t)0x04AF, (wchar_t)0x04B1, (wchar_t)0x04B3, (wchar_t)0x04B5, (wchar_t)0x04B7, (wchar_t)0x04B9, (wchar_t)0x04BB, - (wchar_t)0x04BD, (wchar_t)0x04BF, (wchar_t)0x04C2, (wchar_t)0x04C4, (wchar_t)0x04C8, (wchar_t)0x04CC, (wchar_t)0x04D1, (wchar_t)0x04D3, (wchar_t)0x04D5, - (wchar_t)0x04D7, (wchar_t)0x04D9, (wchar_t)0x04DB, (wchar_t)0x04DD, (wchar_t)0x04DF, (wchar_t)0x04E1, (wchar_t)0x04E3, (wchar_t)0x04E5, (wchar_t)0x04E7, - (wchar_t)0x04E9, (wchar_t)0x04EB, (wchar_t)0x04EF, (wchar_t)0x04F1, (wchar_t)0x04F3, (wchar_t)0x04F5, (wchar_t)0x04F9, (wchar_t)0x0561, (wchar_t)0x0562, - (wchar_t)0x0563, (wchar_t)0x0564, (wchar_t)0x0565, (wchar_t)0x0566, (wchar_t)0x0567, (wchar_t)0x0568, (wchar_t)0x0569, (wchar_t)0x056A, (wchar_t)0x056B, - (wchar_t)0x056C, (wchar_t)0x056D, (wchar_t)0x056E, (wchar_t)0x056F, (wchar_t)0x0570, (wchar_t)0x0571, (wchar_t)0x0572, (wchar_t)0x0573, (wchar_t)0x0574, - (wchar_t)0x0575, (wchar_t)0x0576, (wchar_t)0x0577, (wchar_t)0x0578, (wchar_t)0x0579, (wchar_t)0x057A, (wchar_t)0x057B, (wchar_t)0x057C, (wchar_t)0x057D, - (wchar_t)0x057E, (wchar_t)0x057F, (wchar_t)0x0580, (wchar_t)0x0581, (wchar_t)0x0582, (wchar_t)0x0583, (wchar_t)0x0584, (wchar_t)0x0585, (wchar_t)0x0586, - (wchar_t)0x10D0, (wchar_t)0x10D1, (wchar_t)0x10D2, (wchar_t)0x10D3, (wchar_t)0x10D4, (wchar_t)0x10D5, (wchar_t)0x10D6, (wchar_t)0x10D7, (wchar_t)0x10D8, - (wchar_t)0x10D9, (wchar_t)0x10DA, (wchar_t)0x10DB, (wchar_t)0x10DC, (wchar_t)0x10DD, (wchar_t)0x10DE, (wchar_t)0x10DF, (wchar_t)0x10E0, (wchar_t)0x10E1, - (wchar_t)0x10E2, (wchar_t)0x10E3, (wchar_t)0x10E4, (wchar_t)0x10E5, (wchar_t)0x10E6, (wchar_t)0x10E7, (wchar_t)0x10E8, (wchar_t)0x10E9, (wchar_t)0x10EA, - (wchar_t)0x10EB, (wchar_t)0x10EC, (wchar_t)0x10ED, (wchar_t)0x10EE, (wchar_t)0x10EF, (wchar_t)0x10F0, (wchar_t)0x10F1, (wchar_t)0x10F2, (wchar_t)0x10F3, - (wchar_t)0x10F4, (wchar_t)0x10F5, (wchar_t)0x1E01, (wchar_t)0x1E03, (wchar_t)0x1E05, (wchar_t)0x1E07, (wchar_t)0x1E09, (wchar_t)0x1E0B, (wchar_t)0x1E0D, - (wchar_t)0x1E0F, (wchar_t)0x1E11, (wchar_t)0x1E13, (wchar_t)0x1E15, (wchar_t)0x1E17, (wchar_t)0x1E19, (wchar_t)0x1E1B, (wchar_t)0x1E1D, (wchar_t)0x1E1F, - (wchar_t)0x1E21, (wchar_t)0x1E23, (wchar_t)0x1E25, (wchar_t)0x1E27, (wchar_t)0x1E29, (wchar_t)0x1E2B, (wchar_t)0x1E2D, (wchar_t)0x1E2F, (wchar_t)0x1E31, - (wchar_t)0x1E33, (wchar_t)0x1E35, (wchar_t)0x1E37, (wchar_t)0x1E39, (wchar_t)0x1E3B, (wchar_t)0x1E3D, (wchar_t)0x1E3F, (wchar_t)0x1E41, (wchar_t)0x1E43, - (wchar_t)0x1E45, (wchar_t)0x1E47, (wchar_t)0x1E49, (wchar_t)0x1E4B, (wchar_t)0x1E4D, (wchar_t)0x1E4F, (wchar_t)0x1E51, (wchar_t)0x1E53, (wchar_t)0x1E55, - (wchar_t)0x1E57, (wchar_t)0x1E59, (wchar_t)0x1E5B, (wchar_t)0x1E5D, (wchar_t)0x1E5F, (wchar_t)0x1E61, (wchar_t)0x1E63, (wchar_t)0x1E65, (wchar_t)0x1E67, - (wchar_t)0x1E69, (wchar_t)0x1E6B, (wchar_t)0x1E6D, (wchar_t)0x1E6F, (wchar_t)0x1E71, (wchar_t)0x1E73, (wchar_t)0x1E75, (wchar_t)0x1E77, (wchar_t)0x1E79, - (wchar_t)0x1E7B, (wchar_t)0x1E7D, (wchar_t)0x1E7F, (wchar_t)0x1E81, (wchar_t)0x1E83, (wchar_t)0x1E85, (wchar_t)0x1E87, (wchar_t)0x1E89, (wchar_t)0x1E8B, - (wchar_t)0x1E8D, (wchar_t)0x1E8F, (wchar_t)0x1E91, (wchar_t)0x1E93, (wchar_t)0x1E95, (wchar_t)0x1EA1, (wchar_t)0x1EA3, (wchar_t)0x1EA5, (wchar_t)0x1EA7, - (wchar_t)0x1EA9, (wchar_t)0x1EAB, (wchar_t)0x1EAD, (wchar_t)0x1EAF, (wchar_t)0x1EB1, (wchar_t)0x1EB3, (wchar_t)0x1EB5, (wchar_t)0x1EB7, (wchar_t)0x1EB9, - (wchar_t)0x1EBB, (wchar_t)0x1EBD, (wchar_t)0x1EBF, (wchar_t)0x1EC1, (wchar_t)0x1EC3, (wchar_t)0x1EC5, (wchar_t)0x1EC7, (wchar_t)0x1EC9, (wchar_t)0x1ECB, - (wchar_t)0x1ECD, (wchar_t)0x1ECF, (wchar_t)0x1ED1, (wchar_t)0x1ED3, (wchar_t)0x1ED5, (wchar_t)0x1ED7, (wchar_t)0x1ED9, (wchar_t)0x1EDB, (wchar_t)0x1EDD, - (wchar_t)0x1EDF, (wchar_t)0x1EE1, (wchar_t)0x1EE3, (wchar_t)0x1EE5, (wchar_t)0x1EE7, (wchar_t)0x1EE9, (wchar_t)0x1EEB, (wchar_t)0x1EED, (wchar_t)0x1EEF, - (wchar_t)0x1EF1, (wchar_t)0x1EF3, (wchar_t)0x1EF5, (wchar_t)0x1EF7, (wchar_t)0x1EF9, (wchar_t)0x1F00, (wchar_t)0x1F01, (wchar_t)0x1F02, (wchar_t)0x1F03, - (wchar_t)0x1F04, (wchar_t)0x1F05, (wchar_t)0x1F06, (wchar_t)0x1F07, (wchar_t)0x1F10, (wchar_t)0x1F11, (wchar_t)0x1F12, (wchar_t)0x1F13, (wchar_t)0x1F14, - (wchar_t)0x1F15, (wchar_t)0x1F20, (wchar_t)0x1F21, (wchar_t)0x1F22, (wchar_t)0x1F23, (wchar_t)0x1F24, (wchar_t)0x1F25, (wchar_t)0x1F26, (wchar_t)0x1F27, - (wchar_t)0x1F30, (wchar_t)0x1F31, (wchar_t)0x1F32, (wchar_t)0x1F33, (wchar_t)0x1F34, (wchar_t)0x1F35, (wchar_t)0x1F36, (wchar_t)0x1F37, (wchar_t)0x1F40, - (wchar_t)0x1F41, (wchar_t)0x1F42, (wchar_t)0x1F43, (wchar_t)0x1F44, (wchar_t)0x1F45, (wchar_t)0x1F51, (wchar_t)0x1F53, (wchar_t)0x1F55, (wchar_t)0x1F57, - (wchar_t)0x1F60, (wchar_t)0x1F61, (wchar_t)0x1F62, (wchar_t)0x1F63, (wchar_t)0x1F64, (wchar_t)0x1F65, (wchar_t)0x1F66, (wchar_t)0x1F67, (wchar_t)0x1F80, - (wchar_t)0x1F81, (wchar_t)0x1F82, (wchar_t)0x1F83, (wchar_t)0x1F84, (wchar_t)0x1F85, (wchar_t)0x1F86, (wchar_t)0x1F87, (wchar_t)0x1F90, (wchar_t)0x1F91, - (wchar_t)0x1F92, (wchar_t)0x1F93, (wchar_t)0x1F94, (wchar_t)0x1F95, (wchar_t)0x1F96, (wchar_t)0x1F97, (wchar_t)0x1FA0, (wchar_t)0x1FA1, (wchar_t)0x1FA2, - (wchar_t)0x1FA3, (wchar_t)0x1FA4, (wchar_t)0x1FA5, (wchar_t)0x1FA6, (wchar_t)0x1FA7, (wchar_t)0x1FB0, (wchar_t)0x1FB1, (wchar_t)0x1FD0, (wchar_t)0x1FD1, - (wchar_t)0x1FE0, (wchar_t)0x1FE1, (wchar_t)0x24D0, (wchar_t)0x24D1, (wchar_t)0x24D2, (wchar_t)0x24D3, (wchar_t)0x24D4, (wchar_t)0x24D5, (wchar_t)0x24D6, - (wchar_t)0x24D7, (wchar_t)0x24D8, (wchar_t)0x24D9, (wchar_t)0x24DA, (wchar_t)0x24DB, (wchar_t)0x24DC, (wchar_t)0x24DD, (wchar_t)0x24DE, (wchar_t)0x24DF, - (wchar_t)0x24E0, (wchar_t)0x24E1, (wchar_t)0x24E2, (wchar_t)0x24E3, (wchar_t)0x24E4, (wchar_t)0x24E5, (wchar_t)0x24E6, (wchar_t)0x24E7, (wchar_t)0x24E8, - (wchar_t)0x24E9, (wchar_t)0xFF41, (wchar_t)0xFF42, (wchar_t)0xFF43, (wchar_t)0xFF44, (wchar_t)0xFF45, (wchar_t)0xFF46, (wchar_t)0xFF47, (wchar_t)0xFF48, - (wchar_t)0xFF49, (wchar_t)0xFF4A, (wchar_t)0xFF4B, (wchar_t)0xFF4C, (wchar_t)0xFF4D, (wchar_t)0xFF4E, (wchar_t)0xFF4F, (wchar_t)0xFF50, (wchar_t)0xFF51, - (wchar_t)0xFF52, (wchar_t)0xFF53, (wchar_t)0xFF54, (wchar_t)0xFF55, (wchar_t)0xFF56, (wchar_t)0xFF57, (wchar_t)0xFF58, (wchar_t)0xFF59, (wchar_t)0xFF5A -}; - -static const wchar_t unicode_uppers[] = { - (wchar_t)0x0041, (wchar_t)0x0042, (wchar_t)0x0043, (wchar_t)0x0044, (wchar_t)0x0045, (wchar_t)0x0046, (wchar_t)0x0047, (wchar_t)0x0048, (wchar_t)0x0049, - (wchar_t)0x004A, (wchar_t)0x004B, (wchar_t)0x004C, (wchar_t)0x004D, (wchar_t)0x004E, (wchar_t)0x004F, (wchar_t)0x0050, (wchar_t)0x0051, (wchar_t)0x0052, - (wchar_t)0x0053, (wchar_t)0x0054, (wchar_t)0x0055, (wchar_t)0x0056, (wchar_t)0x0057, (wchar_t)0x0058, (wchar_t)0x0059, (wchar_t)0x005A, (wchar_t)0x00C0, - (wchar_t)0x00C1, (wchar_t)0x00C2, (wchar_t)0x00C3, (wchar_t)0x00C4, (wchar_t)0x00C5, (wchar_t)0x00C6, (wchar_t)0x00C7, (wchar_t)0x00C8, (wchar_t)0x00C9, - (wchar_t)0x00CA, (wchar_t)0x00CB, (wchar_t)0x00CC, (wchar_t)0x00CD, (wchar_t)0x00CE, (wchar_t)0x00CF, (wchar_t)0x00D0, (wchar_t)0x00D1, (wchar_t)0x00D2, - (wchar_t)0x00D3, (wchar_t)0x00D4, (wchar_t)0x00D5, (wchar_t)0x00D6, (wchar_t)0x00D8, (wchar_t)0x00D9, (wchar_t)0x00DA, (wchar_t)0x00DB, (wchar_t)0x00DC, - (wchar_t)0x00DD, (wchar_t)0x00DE, (wchar_t)0x0178, (wchar_t)0x0100, (wchar_t)0x0102, (wchar_t)0x0104, (wchar_t)0x0106, (wchar_t)0x0108, (wchar_t)0x010A, - (wchar_t)0x010C, (wchar_t)0x010E, (wchar_t)0x0110, (wchar_t)0x0112, (wchar_t)0x0114, (wchar_t)0x0116, (wchar_t)0x0118, (wchar_t)0x011A, (wchar_t)0x011C, - (wchar_t)0x011E, (wchar_t)0x0120, (wchar_t)0x0122, (wchar_t)0x0124, (wchar_t)0x0126, (wchar_t)0x0128, (wchar_t)0x012A, (wchar_t)0x012C, (wchar_t)0x012E, - (wchar_t)0x0049, (wchar_t)0x0132, (wchar_t)0x0134, (wchar_t)0x0136, (wchar_t)0x0139, (wchar_t)0x013B, (wchar_t)0x013D, (wchar_t)0x013F, (wchar_t)0x0141, - (wchar_t)0x0143, (wchar_t)0x0145, (wchar_t)0x0147, (wchar_t)0x014A, (wchar_t)0x014C, (wchar_t)0x014E, (wchar_t)0x0150, (wchar_t)0x0152, (wchar_t)0x0154, - (wchar_t)0x0156, (wchar_t)0x0158, (wchar_t)0x015A, (wchar_t)0x015C, (wchar_t)0x015E, (wchar_t)0x0160, (wchar_t)0x0162, (wchar_t)0x0164, (wchar_t)0x0166, - (wchar_t)0x0168, (wchar_t)0x016A, (wchar_t)0x016C, (wchar_t)0x016E, (wchar_t)0x0170, (wchar_t)0x0172, (wchar_t)0x0174, (wchar_t)0x0176, (wchar_t)0x0179, - (wchar_t)0x017B, (wchar_t)0x017D, (wchar_t)0x0182, (wchar_t)0x0184, (wchar_t)0x0187, (wchar_t)0x018B, (wchar_t)0x0191, (wchar_t)0x0198, (wchar_t)0x01A0, - (wchar_t)0x01A2, (wchar_t)0x01A4, (wchar_t)0x01A7, (wchar_t)0x01AC, (wchar_t)0x01AF, (wchar_t)0x01B3, (wchar_t)0x01B5, (wchar_t)0x01B8, (wchar_t)0x01BC, - (wchar_t)0x01C4, (wchar_t)0x01C7, (wchar_t)0x01CA, (wchar_t)0x01CD, (wchar_t)0x01CF, (wchar_t)0x01D1, (wchar_t)0x01D3, (wchar_t)0x01D5, (wchar_t)0x01D7, - (wchar_t)0x01D9, (wchar_t)0x01DB, (wchar_t)0x01DE, (wchar_t)0x01E0, (wchar_t)0x01E2, (wchar_t)0x01E4, (wchar_t)0x01E6, (wchar_t)0x01E8, (wchar_t)0x01EA, - (wchar_t)0x01EC, (wchar_t)0x01EE, (wchar_t)0x01F1, (wchar_t)0x01F4, (wchar_t)0x01FA, (wchar_t)0x01FC, (wchar_t)0x01FE, (wchar_t)0x0200, (wchar_t)0x0202, - (wchar_t)0x0204, (wchar_t)0x0206, (wchar_t)0x0208, (wchar_t)0x020A, (wchar_t)0x020C, (wchar_t)0x020E, (wchar_t)0x0210, (wchar_t)0x0212, (wchar_t)0x0214, - (wchar_t)0x0216, (wchar_t)0x0181, (wchar_t)0x0186, (wchar_t)0x018A, (wchar_t)0x018E, (wchar_t)0x018F, (wchar_t)0x0190, (wchar_t)0x0193, (wchar_t)0x0194, - (wchar_t)0x0197, (wchar_t)0x0196, (wchar_t)0x019C, (wchar_t)0x019D, (wchar_t)0x019F, (wchar_t)0x01A9, (wchar_t)0x01AE, (wchar_t)0x01B1, (wchar_t)0x01B2, - (wchar_t)0x01B7, (wchar_t)0x0386, (wchar_t)0x0388, (wchar_t)0x0389, (wchar_t)0x038A, (wchar_t)0x0391, (wchar_t)0x0392, (wchar_t)0x0393, (wchar_t)0x0394, - (wchar_t)0x0395, (wchar_t)0x0396, (wchar_t)0x0397, (wchar_t)0x0398, (wchar_t)0x0399, (wchar_t)0x039A, (wchar_t)0x039B, (wchar_t)0x039C, (wchar_t)0x039D, - (wchar_t)0x039E, (wchar_t)0x039F, (wchar_t)0x03A0, (wchar_t)0x03A1, (wchar_t)0x03A3, (wchar_t)0x03A4, (wchar_t)0x03A5, (wchar_t)0x03A6, (wchar_t)0x03A7, - (wchar_t)0x03A8, (wchar_t)0x03A9, (wchar_t)0x03AA, (wchar_t)0x03AB, (wchar_t)0x038C, (wchar_t)0x038E, (wchar_t)0x038F, (wchar_t)0x03E2, (wchar_t)0x03E4, - (wchar_t)0x03E6, (wchar_t)0x03E8, (wchar_t)0x03EA, (wchar_t)0x03EC, (wchar_t)0x03EE, (wchar_t)0x0410, (wchar_t)0x0411, (wchar_t)0x0412, (wchar_t)0x0413, - (wchar_t)0x0414, (wchar_t)0x0415, (wchar_t)0x0416, (wchar_t)0x0417, (wchar_t)0x0418, (wchar_t)0x0419, (wchar_t)0x041A, (wchar_t)0x041B, (wchar_t)0x041C, - (wchar_t)0x041D, (wchar_t)0x041E, (wchar_t)0x041F, (wchar_t)0x0420, (wchar_t)0x0421, (wchar_t)0x0422, (wchar_t)0x0423, (wchar_t)0x0424, (wchar_t)0x0425, - (wchar_t)0x0426, (wchar_t)0x0427, (wchar_t)0x0428, (wchar_t)0x0429, (wchar_t)0x042A, (wchar_t)0x042B, (wchar_t)0x042C, (wchar_t)0x042D, (wchar_t)0x042E, - (wchar_t)0x042F, (wchar_t)0x0401, (wchar_t)0x0402, (wchar_t)0x0403, (wchar_t)0x0404, (wchar_t)0x0405, (wchar_t)0x0406, (wchar_t)0x0407, (wchar_t)0x0408, - (wchar_t)0x0409, (wchar_t)0x040A, (wchar_t)0x040B, (wchar_t)0x040C, (wchar_t)0x040E, (wchar_t)0x040F, (wchar_t)0x0460, (wchar_t)0x0462, (wchar_t)0x0464, - (wchar_t)0x0466, (wchar_t)0x0468, (wchar_t)0x046A, (wchar_t)0x046C, (wchar_t)0x046E, (wchar_t)0x0470, (wchar_t)0x0472, (wchar_t)0x0474, (wchar_t)0x0476, - (wchar_t)0x0478, (wchar_t)0x047A, (wchar_t)0x047C, (wchar_t)0x047E, (wchar_t)0x0480, (wchar_t)0x0490, (wchar_t)0x0492, (wchar_t)0x0494, (wchar_t)0x0496, - (wchar_t)0x0498, (wchar_t)0x049A, (wchar_t)0x049C, (wchar_t)0x049E, (wchar_t)0x04A0, (wchar_t)0x04A2, (wchar_t)0x04A4, (wchar_t)0x04A6, (wchar_t)0x04A8, - (wchar_t)0x04AA, (wchar_t)0x04AC, (wchar_t)0x04AE, (wchar_t)0x04B0, (wchar_t)0x04B2, (wchar_t)0x04B4, (wchar_t)0x04B6, (wchar_t)0x04B8, (wchar_t)0x04BA, - (wchar_t)0x04BC, (wchar_t)0x04BE, (wchar_t)0x04C1, (wchar_t)0x04C3, (wchar_t)0x04C7, (wchar_t)0x04CB, (wchar_t)0x04D0, (wchar_t)0x04D2, (wchar_t)0x04D4, - (wchar_t)0x04D6, (wchar_t)0x04D8, (wchar_t)0x04DA, (wchar_t)0x04DC, (wchar_t)0x04DE, (wchar_t)0x04E0, (wchar_t)0x04E2, (wchar_t)0x04E4, (wchar_t)0x04E6, - (wchar_t)0x04E8, (wchar_t)0x04EA, (wchar_t)0x04EE, (wchar_t)0x04F0, (wchar_t)0x04F2, (wchar_t)0x04F4, (wchar_t)0x04F8, (wchar_t)0x0531, (wchar_t)0x0532, - (wchar_t)0x0533, (wchar_t)0x0534, (wchar_t)0x0535, (wchar_t)0x0536, (wchar_t)0x0537, (wchar_t)0x0538, (wchar_t)0x0539, (wchar_t)0x053A, (wchar_t)0x053B, - (wchar_t)0x053C, (wchar_t)0x053D, (wchar_t)0x053E, (wchar_t)0x053F, (wchar_t)0x0540, (wchar_t)0x0541, (wchar_t)0x0542, (wchar_t)0x0543, (wchar_t)0x0544, - (wchar_t)0x0545, (wchar_t)0x0546, (wchar_t)0x0547, (wchar_t)0x0548, (wchar_t)0x0549, (wchar_t)0x054A, (wchar_t)0x054B, (wchar_t)0x054C, (wchar_t)0x054D, - (wchar_t)0x054E, (wchar_t)0x054F, (wchar_t)0x0550, (wchar_t)0x0551, (wchar_t)0x0552, (wchar_t)0x0553, (wchar_t)0x0554, (wchar_t)0x0555, (wchar_t)0x0556, - (wchar_t)0x10A0, (wchar_t)0x10A1, (wchar_t)0x10A2, (wchar_t)0x10A3, (wchar_t)0x10A4, (wchar_t)0x10A5, (wchar_t)0x10A6, (wchar_t)0x10A7, (wchar_t)0x10A8, - (wchar_t)0x10A9, (wchar_t)0x10AA, (wchar_t)0x10AB, (wchar_t)0x10AC, (wchar_t)0x10AD, (wchar_t)0x10AE, (wchar_t)0x10AF, (wchar_t)0x10B0, (wchar_t)0x10B1, - (wchar_t)0x10B2, (wchar_t)0x10B3, (wchar_t)0x10B4, (wchar_t)0x10B5, (wchar_t)0x10B6, (wchar_t)0x10B7, (wchar_t)0x10B8, (wchar_t)0x10B9, (wchar_t)0x10BA, - (wchar_t)0x10BB, (wchar_t)0x10BC, (wchar_t)0x10BD, (wchar_t)0x10BE, (wchar_t)0x10BF, (wchar_t)0x10C0, (wchar_t)0x10C1, (wchar_t)0x10C2, (wchar_t)0x10C3, - (wchar_t)0x10C4, (wchar_t)0x10C5, (wchar_t)0x1E00, (wchar_t)0x1E02, (wchar_t)0x1E04, (wchar_t)0x1E06, (wchar_t)0x1E08, (wchar_t)0x1E0A, (wchar_t)0x1E0C, - (wchar_t)0x1E0E, (wchar_t)0x1E10, (wchar_t)0x1E12, (wchar_t)0x1E14, (wchar_t)0x1E16, (wchar_t)0x1E18, (wchar_t)0x1E1A, (wchar_t)0x1E1C, (wchar_t)0x1E1E, - (wchar_t)0x1E20, (wchar_t)0x1E22, (wchar_t)0x1E24, (wchar_t)0x1E26, (wchar_t)0x1E28, (wchar_t)0x1E2A, (wchar_t)0x1E2C, (wchar_t)0x1E2E, (wchar_t)0x1E30, - (wchar_t)0x1E32, (wchar_t)0x1E34, (wchar_t)0x1E36, (wchar_t)0x1E38, (wchar_t)0x1E3A, (wchar_t)0x1E3C, (wchar_t)0x1E3E, (wchar_t)0x1E40, (wchar_t)0x1E42, - (wchar_t)0x1E44, (wchar_t)0x1E46, (wchar_t)0x1E48, (wchar_t)0x1E4A, (wchar_t)0x1E4C, (wchar_t)0x1E4E, (wchar_t)0x1E50, (wchar_t)0x1E52, (wchar_t)0x1E54, - (wchar_t)0x1E56, (wchar_t)0x1E58, (wchar_t)0x1E5A, (wchar_t)0x1E5C, (wchar_t)0x1E5E, (wchar_t)0x1E60, (wchar_t)0x1E62, (wchar_t)0x1E64, (wchar_t)0x1E66, - (wchar_t)0x1E68, (wchar_t)0x1E6A, (wchar_t)0x1E6C, (wchar_t)0x1E6E, (wchar_t)0x1E70, (wchar_t)0x1E72, (wchar_t)0x1E74, (wchar_t)0x1E76, (wchar_t)0x1E78, - (wchar_t)0x1E7A, (wchar_t)0x1E7C, (wchar_t)0x1E7E, (wchar_t)0x1E80, (wchar_t)0x1E82, (wchar_t)0x1E84, (wchar_t)0x1E86, (wchar_t)0x1E88, (wchar_t)0x1E8A, - (wchar_t)0x1E8C, (wchar_t)0x1E8E, (wchar_t)0x1E90, (wchar_t)0x1E92, (wchar_t)0x1E94, (wchar_t)0x1EA0, (wchar_t)0x1EA2, (wchar_t)0x1EA4, (wchar_t)0x1EA6, - (wchar_t)0x1EA8, (wchar_t)0x1EAA, (wchar_t)0x1EAC, (wchar_t)0x1EAE, (wchar_t)0x1EB0, (wchar_t)0x1EB2, (wchar_t)0x1EB4, (wchar_t)0x1EB6, (wchar_t)0x1EB8, - (wchar_t)0x1EBA, (wchar_t)0x1EBC, (wchar_t)0x1EBE, (wchar_t)0x1EC0, (wchar_t)0x1EC2, (wchar_t)0x1EC4, (wchar_t)0x1EC6, (wchar_t)0x1EC8, (wchar_t)0x1ECA, - (wchar_t)0x1ECC, (wchar_t)0x1ECE, (wchar_t)0x1ED0, (wchar_t)0x1ED2, (wchar_t)0x1ED4, (wchar_t)0x1ED6, (wchar_t)0x1ED8, (wchar_t)0x1EDA, (wchar_t)0x1EDC, - (wchar_t)0x1EDE, (wchar_t)0x1EE0, (wchar_t)0x1EE2, (wchar_t)0x1EE4, (wchar_t)0x1EE6, (wchar_t)0x1EE8, (wchar_t)0x1EEA, (wchar_t)0x1EEC, (wchar_t)0x1EEE, - (wchar_t)0x1EF0, (wchar_t)0x1EF2, (wchar_t)0x1EF4, (wchar_t)0x1EF6, (wchar_t)0x1EF8, (wchar_t)0x1F08, (wchar_t)0x1F09, (wchar_t)0x1F0A, (wchar_t)0x1F0B, - (wchar_t)0x1F0C, (wchar_t)0x1F0D, (wchar_t)0x1F0E, (wchar_t)0x1F0F, (wchar_t)0x1F18, (wchar_t)0x1F19, (wchar_t)0x1F1A, (wchar_t)0x1F1B, (wchar_t)0x1F1C, - (wchar_t)0x1F1D, (wchar_t)0x1F28, (wchar_t)0x1F29, (wchar_t)0x1F2A, (wchar_t)0x1F2B, (wchar_t)0x1F2C, (wchar_t)0x1F2D, (wchar_t)0x1F2E, (wchar_t)0x1F2F, - (wchar_t)0x1F38, (wchar_t)0x1F39, (wchar_t)0x1F3A, (wchar_t)0x1F3B, (wchar_t)0x1F3C, (wchar_t)0x1F3D, (wchar_t)0x1F3E, (wchar_t)0x1F3F, (wchar_t)0x1F48, - (wchar_t)0x1F49, (wchar_t)0x1F4A, (wchar_t)0x1F4B, (wchar_t)0x1F4C, (wchar_t)0x1F4D, (wchar_t)0x1F59, (wchar_t)0x1F5B, (wchar_t)0x1F5D, (wchar_t)0x1F5F, - (wchar_t)0x1F68, (wchar_t)0x1F69, (wchar_t)0x1F6A, (wchar_t)0x1F6B, (wchar_t)0x1F6C, (wchar_t)0x1F6D, (wchar_t)0x1F6E, (wchar_t)0x1F6F, (wchar_t)0x1F88, - (wchar_t)0x1F89, (wchar_t)0x1F8A, (wchar_t)0x1F8B, (wchar_t)0x1F8C, (wchar_t)0x1F8D, (wchar_t)0x1F8E, (wchar_t)0x1F8F, (wchar_t)0x1F98, (wchar_t)0x1F99, - (wchar_t)0x1F9A, (wchar_t)0x1F9B, (wchar_t)0x1F9C, (wchar_t)0x1F9D, (wchar_t)0x1F9E, (wchar_t)0x1F9F, (wchar_t)0x1FA8, (wchar_t)0x1FA9, (wchar_t)0x1FAA, - (wchar_t)0x1FAB, (wchar_t)0x1FAC, (wchar_t)0x1FAD, (wchar_t)0x1FAE, (wchar_t)0x1FAF, (wchar_t)0x1FB8, (wchar_t)0x1FB9, (wchar_t)0x1FD8, (wchar_t)0x1FD9, - (wchar_t)0x1FE8, (wchar_t)0x1FE9, (wchar_t)0x24B6, (wchar_t)0x24B7, (wchar_t)0x24B8, (wchar_t)0x24B9, (wchar_t)0x24BA, (wchar_t)0x24BB, (wchar_t)0x24BC, - (wchar_t)0x24BD, (wchar_t)0x24BE, (wchar_t)0x24BF, (wchar_t)0x24C0, (wchar_t)0x24C1, (wchar_t)0x24C2, (wchar_t)0x24C3, (wchar_t)0x24C4, (wchar_t)0x24C5, - (wchar_t)0x24C6, (wchar_t)0x24C7, (wchar_t)0x24C8, (wchar_t)0x24C9, (wchar_t)0x24CA, (wchar_t)0x24CB, (wchar_t)0x24CC, (wchar_t)0x24CD, (wchar_t)0x24CE, - (wchar_t)0x24CF, (wchar_t)0xFF21, (wchar_t)0xFF22, (wchar_t)0xFF23, (wchar_t)0xFF24, (wchar_t)0xFF25, (wchar_t)0xFF26, (wchar_t)0xFF27, (wchar_t)0xFF28, - (wchar_t)0xFF29, (wchar_t)0xFF2A, (wchar_t)0xFF2B, (wchar_t)0xFF2C, (wchar_t)0xFF2D, (wchar_t)0xFF2E, (wchar_t)0xFF2F, (wchar_t)0xFF30, (wchar_t)0xFF31, - (wchar_t)0xFF32, (wchar_t)0xFF33, (wchar_t)0xFF34, (wchar_t)0xFF35, (wchar_t)0xFF36, (wchar_t)0xFF37, (wchar_t)0xFF38, (wchar_t)0xFF39, (wchar_t)0xFF3A -}; - -string StringUtils::Format(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - string str = FormatV(fmt, args); - va_end(args); - - return str; -} - -string StringUtils::FormatV(const char *fmt, va_list args) -{ - if (fmt == NULL) - return ""; - - int size = FORMAT_BLOCK_SIZE; - va_list argCopy; - - char *cstr = reinterpret_cast(malloc(sizeof(char) * size)); - if (cstr == NULL) - return ""; - - while (1) - { - va_copy(argCopy, args); - - int nActual = vsnprintf(cstr, size, fmt, argCopy); - va_end(argCopy); - - if (nActual > -1 && nActual < size) // We got a valid result - { - string str(cstr, nActual); - free(cstr); - return str; - } - if (nActual > -1) // Exactly what we will need (glibc 2.1) - size = nActual + 1; - else // Let's try to double the size (glibc 2.0) - size *= 2; - - char *new_cstr = reinterpret_cast(realloc(cstr, sizeof(char) * size)); - if (new_cstr == NULL) - { - free(cstr); - return ""; - } - - cstr = new_cstr; - } - - free(cstr); - return ""; -} - -wstring StringUtils::Format(const wchar_t *fmt, ...) -{ - va_list args; - va_start(args, fmt); - wstring str = FormatV(fmt, args); - va_end(args); - - return str; -} - -wstring StringUtils::FormatV(const wchar_t *fmt, va_list args) -{ - if (fmt == NULL) - return L""; - - int size = FORMAT_BLOCK_SIZE; - va_list argCopy; - - wchar_t *cstr = reinterpret_cast(malloc(sizeof(wchar_t) * size)); - if (cstr == NULL) - return L""; - - while (1) - { - va_copy(argCopy, args); - - int nActual = vswprintf(cstr, size, fmt, argCopy); - va_end(argCopy); - - if (nActual > -1 && nActual < size) // We got a valid result - { - wstring str(cstr, nActual); - free(cstr); - return str; - } - if (nActual > -1) // Exactly what we will need (glibc 2.1) - size = nActual + 1; - else // Let's try to double the size (glibc 2.0) - size *= 2; - - wchar_t *new_cstr = reinterpret_cast(realloc(cstr, sizeof(wchar_t) * size)); - if (new_cstr == NULL) - { - free(cstr); - return L""; - } - - cstr = new_cstr; - } - - return L""; -} - -int compareWchar (const void* a, const void* b) -{ - if (*(wchar_t*)a < *(wchar_t*)b) - return -1; - else if (*(wchar_t*)a > *(wchar_t*)b) - return 1; - return 0; -} - -wchar_t tolowerUnicode(const wchar_t& c) -{ - wchar_t* p = (wchar_t*) bsearch (&c, unicode_uppers, sizeof(unicode_uppers) / sizeof(wchar_t), sizeof(wchar_t), compareWchar); - if (p) - return *(unicode_lowers + (p - unicode_uppers)); - - return c; -} - -wchar_t toupperUnicode(const wchar_t& c) -{ - wchar_t* p = (wchar_t*) bsearch (&c, unicode_lowers, sizeof(unicode_lowers) / sizeof(wchar_t), sizeof(wchar_t), compareWchar); - if (p) - return *(unicode_uppers + (p - unicode_lowers)); - - return c; -} - -void StringUtils::ToUpper(string &str) -{ - std::transform(str.begin(), str.end(), str.begin(), ::toupper); -} - -void StringUtils::ToUpper(wstring &str) -{ - transform(str.begin(), str.end(), str.begin(), toupperUnicode); -} - -void StringUtils::ToLower(string &str) -{ - transform(str.begin(), str.end(), str.begin(), ::tolower); -} - -void StringUtils::ToLower(wstring &str) -{ - transform(str.begin(), str.end(), str.begin(), tolowerUnicode); -} - -bool StringUtils::EqualsNoCase(const std::string &str1, const std::string &str2) -{ - return EqualsNoCase(str1.c_str(), str2.c_str()); -} - -bool StringUtils::EqualsNoCase(const std::string &str1, const char *s2) -{ - return EqualsNoCase(str1.c_str(), s2); -} - -bool StringUtils::EqualsNoCase(const char *s1, const char *s2) -{ - char c2; // we need only one char outside the loop - do - { - const char c1 = *s1++; // const local variable should help compiler to optimize - c2 = *s2++; - if (c1 != c2 && ::tolower(c1) != ::tolower(c2)) // This includes the possibility that one of the characters is the null-terminator, which implies a string mismatch. - return false; - } while (c2 != '\0'); // At this point, we know c1 == c2, so there's no need to test them both. - return true; -} - -int StringUtils::CompareNoCase(const std::string &str1, const std::string &str2) -{ - return CompareNoCase(str1.c_str(), str2.c_str()); -} - -int StringUtils::CompareNoCase(const char *s1, const char *s2) -{ - char c2; // we need only one char outside the loop - do - { - const char c1 = *s1++; // const local variable should help compiler to optimize - c2 = *s2++; - if (c1 != c2 && ::tolower(c1) != ::tolower(c2)) // This includes the possibility that one of the characters is the null-terminator, which implies a string mismatch. - return ::tolower(c1) - ::tolower(c2); - } while (c2 != '\0'); // At this point, we know c1 == c2, so there's no need to test them both. - return 0; -} - -string StringUtils::Left(const string &str, size_t count) -{ - count = max((size_t)0, min(count, str.size())); - return str.substr(0, count); -} - -string StringUtils::Mid(const string &str, size_t first, size_t count /* = string::npos */) -{ - if (first + count > str.size()) - count = str.size() - first; - - if (first > str.size()) - return string(); - - assert(first + count <= str.size()); - - return str.substr(first, count); -} - -string StringUtils::Right(const string &str, size_t count) -{ - count = max((size_t)0, min(count, str.size())); - return str.substr(str.size() - count); -} - -std::string& StringUtils::Trim(std::string &str) -{ - TrimLeft(str); - return TrimRight(str); -} - -std::string& StringUtils::Trim(std::string &str, const char* const chars) -{ - TrimLeft(str, chars); - return TrimRight(str, chars); -} - -// hack to ensure that std::string::iterator will be dereferenced as _unsigned_ char -// without this hack "TrimX" functions failed on Win32 with UTF-8 strings -static int isspace_c(char c) -{ - return ::isspace((unsigned char)c); -} - -std::string& StringUtils::TrimLeft(std::string &str) -{ - str.erase(str.begin(), ::find_if(str.begin(), str.end(), ::not1(::ptr_fun(isspace_c)))); - return str; -} - -std::string& StringUtils::TrimLeft(std::string &str, const char* const chars) -{ - size_t nidx = str.find_first_not_of(chars); - str.erase(0, nidx); - return str; -} - -std::string& StringUtils::TrimRight(std::string &str) -{ - str.erase(::find_if(str.rbegin(), str.rend(), ::not1(::ptr_fun(isspace_c))).base(), str.end()); - return str; -} - -std::string& StringUtils::TrimRight(std::string &str, const char* const chars) -{ - size_t nidx = str.find_last_not_of(chars); - str.erase(str.npos == nidx ? 0 : ++nidx); - return str; -} - -std::string& StringUtils::RemoveDuplicatedSpacesAndTabs(std::string& str) -{ - std::string::iterator it = str.begin(); - bool onSpace = false; - while(it != str.end()) - { - if (*it == '\t') - *it = ' '; - - if (*it == ' ') - { - if (onSpace) - { - it = str.erase(it); - continue; - } - else - onSpace = true; - } - else - onSpace = false; - - ++it; - } - return str; -} - -int StringUtils::Replace(string &str, char oldChar, char newChar) -{ - int replacedChars = 0; - for (string::iterator it = str.begin(); it != str.end(); ++it) - { - if (*it == oldChar) - { - *it = newChar; - replacedChars++; - } - } - - return replacedChars; -} - -int StringUtils::Replace(std::string &str, const std::string &oldStr, const std::string &newStr) -{ - if (oldStr.empty()) - return 0; - - int replacedChars = 0; - size_t index = 0; - - while (index < str.size() && (index = str.find(oldStr, index)) != string::npos) - { - str.replace(index, oldStr.size(), newStr); - index += newStr.size(); - replacedChars++; - } - - return replacedChars; -} - -int StringUtils::Replace(std::wstring &str, const std::wstring &oldStr, const std::wstring &newStr) -{ - if (oldStr.empty()) - return 0; - - int replacedChars = 0; - size_t index = 0; - - while (index < str.size() && (index = str.find(oldStr, index)) != string::npos) - { - str.replace(index, oldStr.size(), newStr); - index += newStr.size(); - replacedChars++; - } - - return replacedChars; -} - -bool StringUtils::StartsWith(const std::string &str1, const std::string &str2) -{ - return str1.compare(0, str2.size(), str2) == 0; -} - -bool StringUtils::StartsWith(const std::string &str1, const char *s2) -{ - return StartsWith(str1.c_str(), s2); -} - -bool StringUtils::StartsWith(const char *s1, const char *s2) -{ - while (*s2 != '\0') - { - if (*s1 != *s2) - return false; - s1++; - s2++; - } - return true; -} - -bool StringUtils::StartsWithNoCase(const std::string &str1, const std::string &str2) -{ - return StartsWithNoCase(str1.c_str(), str2.c_str()); -} - -bool StringUtils::StartsWithNoCase(const std::string &str1, const char *s2) -{ - return StartsWithNoCase(str1.c_str(), s2); -} - -bool StringUtils::StartsWithNoCase(const char *s1, const char *s2) -{ - while (*s2 != '\0') - { - if (::tolower(*s1) != ::tolower(*s2)) - return false; - s1++; - s2++; - } - return true; -} - -bool StringUtils::EndsWith(const std::string &str1, const std::string &str2) -{ - if (str1.size() < str2.size()) - return false; - return str1.compare(str1.size() - str2.size(), str2.size(), str2) == 0; -} - -bool StringUtils::EndsWith(const std::string &str1, const char *s2) -{ - size_t len2 = strlen(s2); - if (str1.size() < len2) - return false; - return str1.compare(str1.size() - len2, len2, s2) == 0; -} - -bool StringUtils::EndsWithNoCase(const std::string &str1, const std::string &str2) -{ - if (str1.size() < str2.size()) - return false; - const char *s1 = str1.c_str() + str1.size() - str2.size(); - const char *s2 = str2.c_str(); - while (*s2 != '\0') - { - if (::tolower(*s1) != ::tolower(*s2)) - return false; - s1++; - s2++; - } - return true; -} - -bool StringUtils::EndsWithNoCase(const std::string &str1, const char *s2) -{ - size_t len2 = strlen(s2); - if (str1.size() < len2) - return false; - const char *s1 = str1.c_str() + str1.size() - len2; - while (*s2 != '\0') - { - if (::tolower(*s1) != ::tolower(*s2)) - return false; - s1++; - s2++; - } - return true; -} - -std::string StringUtils::Join(const vector &strings, const std::string& delimiter) -{ - std::string result; - for(vector::const_iterator it = strings.begin(); it != strings.end(); it++ ) - result += (*it) + delimiter; - - if (!result.empty()) - result.erase(result.size() - delimiter.size()); - return result; -} - -vector StringUtils::Split(const std::string& input, const std::string& delimiter, unsigned int iMaxStrings /* = 0 */) -{ - vector results; - if (input.empty()) - return results; - - size_t iPos = std::string::npos; - size_t newPos = std::string::npos; - size_t sizeS2 = delimiter.size(); - size_t isize = input.size(); - - vector positions; - - newPos = input.find(delimiter, 0); - - if (newPos == std::string::npos) - { - results.push_back(input); - return results; - } - - while (newPos != std::string::npos) - { - positions.push_back(newPos); - iPos = newPos; - newPos = input.find(delimiter, iPos + sizeS2); - } - - // numFound is the number of delimiters which is one less - // than the number of substrings - unsigned int numFound = positions.size(); - if (iMaxStrings > 0 && numFound >= iMaxStrings) - numFound = iMaxStrings - 1; - - for ( unsigned int i = 0; i <= numFound; i++ ) - { - string s; - if ( i == 0 ) - { - if ( i == numFound ) - s = input; - else - s = input.substr(i, positions[i]); - } - else - { - size_t offset = positions[i - 1] + sizeS2; - if ( offset < isize ) - { - if ( i == numFound ) - s = input.substr(offset); - else if ( i > 0 ) - s = input.substr( positions[i - 1] + sizeS2, - positions[i] - positions[i - 1] - sizeS2 ); - } - } - results.push_back(s); - } - return results; -} - -// returns the number of occurrences of strFind in strInput. -int StringUtils::FindNumber(const std::string& strInput, const std::string &strFind) -{ - size_t pos = strInput.find(strFind, 0); - int numfound = 0; - while (pos != std::string::npos) - { - numfound++; - pos = strInput.find(strFind, pos + 1); - } - return numfound; -} - -// Compares separately the numeric and alphabetic parts of a string. -// returns negative if left < right, positive if left > right -// and 0 if they are identical (essentially calculates left - right) -int64_t StringUtils::AlphaNumericCompare(const wchar_t *left, const wchar_t *right) -{ - wchar_t *l = (wchar_t *)left; - wchar_t *r = (wchar_t *)right; - wchar_t *ld, *rd; - wchar_t lc, rc; - int64_t lnum, rnum; - const collate& coll = use_facet< collate >( locale() ); - int cmp_res = 0; - while (*l != 0 && *r != 0) - { - // check if we have a numerical value - if (*l >= L'0' && *l <= L'9' && *r >= L'0' && *r <= L'9') - { - ld = l; - lnum = 0; - while (*ld >= L'0' && *ld <= L'9' && ld < l + 15) - { // compare only up to 15 digits - lnum *= 10; - lnum += *ld++ - '0'; - } - rd = r; - rnum = 0; - while (*rd >= L'0' && *rd <= L'9' && rd < r + 15) - { // compare only up to 15 digits - rnum *= 10; - rnum += *rd++ - L'0'; - } - // do we have numbers? - if (lnum != rnum) - { // yes - and they're different! - return lnum - rnum; - } - l = ld; - r = rd; - continue; - } - // do case less comparison - lc = *l; - if (lc >= L'A' && lc <= L'Z') - lc += L'a'-L'A'; - rc = *r; - if (rc >= L'A' && rc <= L'Z') - rc += L'a'- L'A'; - - // ok, do a normal comparison, taking current locale into account. Add special case stuff (eg '(' characters)) in here later - if ((cmp_res = coll.compare(&lc, &lc + 1, &rc, &rc + 1)) != 0) - { - return cmp_res; - } - l++; r++; - } - if (*r) - { // r is longer - return -1; - } - else if (*l) - { // l is longer - return 1; - } - return 0; // files are the same -} - -int StringUtils::DateStringToYYYYMMDD(const std::string &dateString) -{ - vector days = StringUtils::Split(dateString, "-"); - if (days.size() == 1) - return atoi(days[0].c_str()); - else if (days.size() == 2) - return atoi(days[0].c_str())*100+atoi(days[1].c_str()); - else if (days.size() == 3) - return atoi(days[0].c_str())*10000+atoi(days[1].c_str())*100+atoi(days[2].c_str()); - else - return -1; -} - -long StringUtils::TimeStringToSeconds(const std::string &timeString) -{ - std::string strCopy(timeString); - StringUtils::Trim(strCopy); - if(StringUtils::EndsWithNoCase(strCopy, " min")) - { - // this is imdb format of "XXX min" - return 60 * atoi(strCopy.c_str()); - } - else - { - vector secs = StringUtils::Split(strCopy, ":"); - int timeInSecs = 0; - for (unsigned int i = 0; i < 3 && i < secs.size(); i++) - { - timeInSecs *= 60; - timeInSecs += atoi(secs[i].c_str()); - } - return timeInSecs; - } -} - -std::string StringUtils::SecondsToTimeString(long lSeconds, TIME_FORMAT format) -{ - int hh = lSeconds / 3600; - lSeconds = lSeconds % 3600; - int mm = lSeconds / 60; - int ss = lSeconds % 60; - - if (format == TIME_FORMAT_GUESS) - format = (hh >= 1) ? TIME_FORMAT_HH_MM_SS : TIME_FORMAT_MM_SS; - std::string strHMS; - if (format & TIME_FORMAT_HH) - strHMS += StringUtils::Format("%02.2i", hh); - else if (format & TIME_FORMAT_H) - strHMS += StringUtils::Format("%i", hh); - if (format & TIME_FORMAT_MM) - strHMS += StringUtils::Format(strHMS.empty() ? "%02.2i" : ":%02.2i", mm); - if (format & TIME_FORMAT_SS) - strHMS += StringUtils::Format(strHMS.empty() ? "%02.2i" : ":%02.2i", ss); - return strHMS; -} - -bool StringUtils::IsNaturalNumber(const std::string& str) -{ - size_t i = 0, n = 0; - // allow whitespace,digits,whitespace - while (i < str.size() && isspace((unsigned char) str[i])) - i++; - while (i < str.size() && isdigit((unsigned char) str[i])) - { - i++; n++; - } - while (i < str.size() && isspace((unsigned char) str[i])) - i++; - return i == str.size() && n > 0; -} - -bool StringUtils::IsInteger(const std::string& str) -{ - size_t i = 0, n = 0; - // allow whitespace,-,digits,whitespace - while (i < str.size() && isspace((unsigned char) str[i])) - i++; - if (i < str.size() && str[i] == '-') - i++; - while (i < str.size() && isdigit((unsigned char) str[i])) - { - i++; n++; - } - while (i < str.size() && isspace((unsigned char) str[i])) - i++; - return i == str.size() && n > 0; -} - -int StringUtils::asciidigitvalue(char chr) -{ - if (!isasciidigit(chr)) - return -1; - - return chr - '0'; -} - -int StringUtils::asciixdigitvalue(char chr) -{ - int v = asciidigitvalue(chr); - if (v >= 0) - return v; - if (chr >= 'a' && chr <= 'f') - return chr - 'a' + 10; - if (chr >= 'A' && chr <= 'F') - return chr - 'A' + 10; - - return -1; -} - - -void StringUtils::RemoveCRLF(std::string& strLine) -{ - StringUtils::TrimRight(strLine, "\n\r"); -} - -std::string StringUtils::SizeToString(int64_t size) -{ - std::string strLabel; - const char prefixes[] = {' ','k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'}; - unsigned int i = 0; - double s = (double)size; - while (i < sizeof(prefixes)/sizeof(prefixes[0]) && s >= 1000.0) - { - s /= 1024.0; - i++; - } - - if (!i) - strLabel = StringUtils::Format("%.0lf %cB ", s, prefixes[i]); - else if (s >= 100.0) - strLabel = StringUtils::Format("%.1lf %cB", s, prefixes[i]); - else - strLabel = StringUtils::Format("%.2lf %cB", s, prefixes[i]); - - return strLabel; -} - -// return -1 if not, else return the utf8 char length. -int IsUTF8Letter(const unsigned char *str) -{ - // reference: - // unicode -> utf8 table: http://www.utf8-chartable.de/ - // latin characters in unicode: http://en.wikipedia.org/wiki/Latin_characters_in_Unicode - unsigned char ch = str[0]; - if (!ch) - return -1; - if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) - return 1; - if (!(ch & 0x80)) - return -1; - unsigned char ch2 = str[1]; - if (!ch2) - return -1; - // check latin 1 letter table: http://en.wikipedia.org/wiki/C1_Controls_and_Latin-1_Supplement - if (ch == 0xC3 && ch2 >= 0x80 && ch2 <= 0xBF && ch2 != 0x97 && ch2 != 0xB7) - return 2; - // check latin extended A table: http://en.wikipedia.org/wiki/Latin_Extended-A - if (ch >= 0xC4 && ch <= 0xC7 && ch2 >= 0x80 && ch2 <= 0xBF) - return 2; - // check latin extended B table: http://en.wikipedia.org/wiki/Latin_Extended-B - // and International Phonetic Alphabet: http://en.wikipedia.org/wiki/IPA_Extensions_(Unicode_block) - if (((ch == 0xC8 || ch == 0xC9) && ch2 >= 0x80 && ch2 <= 0xBF) - || (ch == 0xCA && ch2 >= 0x80 && ch2 <= 0xAF)) - return 2; - return -1; -} - -size_t StringUtils::FindWords(const char *str, const char *wordLowerCase) -{ - // NOTE: This assumes word is lowercase! - unsigned char *s = (unsigned char *)str; - do - { - // start with a compare - unsigned char *c = s; - unsigned char *w = (unsigned char *)wordLowerCase; - bool same = true; - while (same && *c && *w) - { - unsigned char lc = *c++; - if (lc >= 'A' && lc <= 'Z') - lc += 'a'-'A'; - - if (lc != *w++) // different - same = false; - } - if (same && *w == 0) // only the same if word has been exhausted - return (const char *)s - str; - - // otherwise, skip current word (composed by latin letters) or number - int l; - if (*s >= '0' && *s <= '9') - { - ++s; - while (*s >= '0' && *s <= '9') ++s; - } - else if ((l = IsUTF8Letter(s)) > 0) - { - s += l; - while ((l = IsUTF8Letter(s)) > 0) s += l; - } - else - ++s; - while (*s && *s == ' ') s++; - - // and repeat until we're done - } while (*s); - - return std::string::npos; -} - -// assumes it is called from after the first open bracket is found -int StringUtils::FindEndBracket(const std::string &str, char opener, char closer, int startPos) -{ - int blocks = 1; - for (unsigned int i = startPos; i < str.size(); i++) - { - if (str[i] == opener) - blocks++; - else if (str[i] == closer) - { - blocks--; - if (!blocks) - return i; - } - } - - return (int)std::string::npos; -} - -void StringUtils::WordToDigits(std::string &word) -{ - static const char word_to_letter[] = "22233344455566677778889999"; - StringUtils::ToLower(word); - for (unsigned int i = 0; i < word.size(); ++i) - { // NB: This assumes ascii, which probably needs extending at some point. - char letter = word[i]; - if ((letter >= 'a' && letter <= 'z')) // assume contiguous letter range - { - word[i] = word_to_letter[letter-'a']; - } - else if (letter < '0' || letter > '9') // We want to keep 0-9! - { - word[i] = ' '; // replace everything else with a space - } - } -} - -std::string StringUtils::CreateUUID() -{ - /* This function generate a DCE 1.1, ISO/IEC 11578:1996 and IETF RFC-4122 - * Version 4 conform local unique UUID based upon random number generation. - */ - char UuidStrTmp[40]; - char *pUuidStr = UuidStrTmp; - int i; - - static bool m_uuidInitialized = false; - if (!m_uuidInitialized) - { - /* use current time as the seed for rand()*/ - srand(time(NULL)); - m_uuidInitialized = true; - } - - /*Data1 - 8 characters.*/ - for(i = 0; i < 8; i++, pUuidStr++) - ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55; - - /*Data2 - 4 characters.*/ - *pUuidStr++ = '-'; - for(i = 0; i < 4; i++, pUuidStr++) - ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55; - - /*Data3 - 4 characters.*/ - *pUuidStr++ = '-'; - for(i = 0; i < 4; i++, pUuidStr++) - ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55; - - /*Data4 - 4 characters.*/ - *pUuidStr++ = '-'; - for(i = 0; i < 4; i++, pUuidStr++) - ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55; - - /*Data5 - 12 characters.*/ - *pUuidStr++ = '-'; - for(i = 0; i < 12; i++, pUuidStr++) - ((*pUuidStr = (rand() % 16)) < 10) ? *pUuidStr += 48 : *pUuidStr += 55; - - *pUuidStr = '\0'; - - m_lastUUID = UuidStrTmp; - return UuidStrTmp; -} - -double StringUtils::CompareFuzzy(const std::string &left, const std::string &right) -{ - return (0.5 + fstrcmp(left.c_str(), right.c_str(), 0.0) * (left.length() + right.length())) / 2.0; -} - -int StringUtils::FindBestMatch(const std::string &str, const vector &strings, double &matchscore) -{ - int best = -1; - matchscore = 0; - - int i = 0; - for (vector::const_iterator it = strings.begin(); it != strings.end(); ++it, i++) - { - int maxlength = max(str.length(), it->length()); - double score = StringUtils::CompareFuzzy(str, *it) / maxlength; - if (score > matchscore) - { - matchscore = score; - best = i; - } - } - return best; -} - -bool StringUtils::ContainsKeyword(const std::string &str, const vector &keywords) -{ - for (vector::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - if (str.find(*it) != str.npos) - return true; - } - return false; -} - -size_t StringUtils::utf8_strlen(const char *s) -{ - size_t length = 0; - while (*s) - { - if ((*s++ & 0xC0) != 0x80) - length++; - } - return length; -} - -std::string StringUtils::Paramify(const std::string ¶m) -{ - std::string result = param; - // escape backspaces - StringUtils::Replace(result, "\\", "\\\\"); - // escape double quotes - StringUtils::Replace(result, "\"", "\\\""); - - // add double quotes around the whole string - return "\"" + result + "\""; -} - -std::vector StringUtils::Tokenize(const std::string &input, const std::string &delimiters) -{ - std::vector tokens; - Tokenize(input, tokens, delimiters); - return tokens; -} - -void StringUtils::Tokenize(const std::string& input, std::vector& tokens, const std::string& delimiters) -{ - tokens.clear(); - // Skip delimiters at beginning. - std::string::size_type dataPos = input.find_first_not_of(delimiters); - while (dataPos != std::string::npos) - { - // Find next delimiter - const std::string::size_type nextDelimPos = input.find_first_of(delimiters, dataPos); - // Found a token, add it to the vector. - tokens.push_back(input.substr(dataPos, nextDelimPos - dataPos)); - // Skip delimiters. Note the "not_of" - dataPos = input.find_first_not_of(delimiters, nextDelimPos); - } -} diff -Nru kodiplatform-15.0.0/src/util/StringUtils.h kodiplatform-16.0.0/src/util/StringUtils.h --- kodiplatform-15.0.0/src/util/StringUtils.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/StringUtils.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ -//----------------------------------------------------------------------- -// -// File: StringUtils.h -// -// Purpose: ATL split string utility -// Author: Paul J. Weiss -// -// Modified to support J O'Leary's std::string class by kraqh3d -// -//------------------------------------------------------------------------ - -#include -#include -#include -#include - -/*! \brief TIME_FORMAT enum/bitmask used for formatting time strings - Note the use of bitmasking, e.g. - TIME_FORMAT_HH_MM_SS = TIME_FORMAT_HH | TIME_FORMAT_MM | TIME_FORMAT_SS - \sa StringUtils::SecondsToTimeString - */ -enum TIME_FORMAT { TIME_FORMAT_GUESS = 0, - TIME_FORMAT_SS = 1, - TIME_FORMAT_MM = 2, - TIME_FORMAT_MM_SS = 3, - TIME_FORMAT_HH = 4, - TIME_FORMAT_HH_SS = 5, // not particularly useful - TIME_FORMAT_HH_MM = 6, - TIME_FORMAT_HH_MM_SS = 7, - TIME_FORMAT_XX = 8, // AM/PM - TIME_FORMAT_HH_MM_XX = 14, - TIME_FORMAT_HH_MM_SS_XX = 15, - TIME_FORMAT_H = 16, - TIME_FORMAT_H_MM_SS = 19, - TIME_FORMAT_H_MM_SS_XX = 27}; - -class StringUtils -{ -public: - /*! \brief Get a formatted string similar to sprintf - - Beware that this does not support directly passing in - std::string objects. You need to call c_str() to pass - the const char* buffer representing the value of the - std::string object. - - \param fmt Format of the resulting string - \param ... variable number of value type arguments - \return Formatted string - */ - static std::string Format(const char *fmt, ...); - static std::string FormatV(const char *fmt, va_list args); - static std::wstring Format(const wchar_t *fmt, ...); - static std::wstring FormatV(const wchar_t *fmt, va_list args); - static void ToUpper(std::string &str); - static void ToUpper(std::wstring &str); - static void ToLower(std::string &str); - static void ToLower(std::wstring &str); - static bool EqualsNoCase(const std::string &str1, const std::string &str2); - static bool EqualsNoCase(const std::string &str1, const char *s2); - static bool EqualsNoCase(const char *s1, const char *s2); - static int CompareNoCase(const std::string &str1, const std::string &str2); - static int CompareNoCase(const char *s1, const char *s2); - static std::string Left(const std::string &str, size_t count); - static std::string Mid(const std::string &str, size_t first, size_t count = std::string::npos); - static std::string Right(const std::string &str, size_t count); - static std::string& Trim(std::string &str); - static std::string& Trim(std::string &str, const char* const chars); - static std::string& TrimLeft(std::string &str); - static std::string& TrimLeft(std::string &str, const char* const chars); - static std::string& TrimRight(std::string &str); - static std::string& TrimRight(std::string &str, const char* const chars); - static std::string& RemoveDuplicatedSpacesAndTabs(std::string& str); - static int Replace(std::string &str, char oldChar, char newChar); - static int Replace(std::string &str, const std::string &oldStr, const std::string &newStr); - static int Replace(std::wstring &str, const std::wstring &oldStr, const std::wstring &newStr); - static bool StartsWith(const std::string &str1, const std::string &str2); - static bool StartsWith(const std::string &str1, const char *s2); - static bool StartsWith(const char *s1, const char *s2); - static bool StartsWithNoCase(const std::string &str1, const std::string &str2); - static bool StartsWithNoCase(const std::string &str1, const char *s2); - static bool StartsWithNoCase(const char *s1, const char *s2); - static bool EndsWith(const std::string &str1, const std::string &str2); - static bool EndsWith(const std::string &str1, const char *s2); - static bool EndsWithNoCase(const std::string &str1, const std::string &str2); - static bool EndsWithNoCase(const std::string &str1, const char *s2); - - static std::string Join(const std::vector &strings, const std::string& delimiter); - /*! \brief Splits the given input string using the given delimiter into separate strings. - - If the given input string is empty the result will be an empty array (not - an array containing an empty string). - - \param input Input string to be split - \param delimiter Delimiter to be used to split the input string - \param iMaxStrings (optional) Maximum number of splitted strings - */ - static std::vector Split(const std::string& input, const std::string& delimiter, unsigned int iMaxStrings = 0); - static int FindNumber(const std::string& strInput, const std::string &strFind); - static int64_t AlphaNumericCompare(const wchar_t *left, const wchar_t *right); - static long TimeStringToSeconds(const std::string &timeString); - static void RemoveCRLF(std::string& strLine); - - /*! \brief utf8 version of strlen - skips any non-starting bytes in the count, thus returning the number of utf8 characters - \param s c-string to find the length of. - \return the number of utf8 characters in the string. - */ - static size_t utf8_strlen(const char *s); - - /*! \brief convert a time in seconds to a string based on the given time format - \param seconds time in seconds - \param format the format we want the time in. - \return the formatted time - \sa TIME_FORMAT - */ - static std::string SecondsToTimeString(long seconds, TIME_FORMAT format = TIME_FORMAT_GUESS); - - /*! \brief check whether a string is a natural number. - Matches [ \t]*[0-9]+[ \t]* - \param str the string to check - \return true if the string is a natural number, false otherwise. - */ - static bool IsNaturalNumber(const std::string& str); - - /*! \brief check whether a string is an integer. - Matches [ \t]*[\-]*[0-9]+[ \t]* - \param str the string to check - \return true if the string is an integer, false otherwise. - */ - static bool IsInteger(const std::string& str); - - /* The next several isasciiXX and asciiXXvalue functions are locale independent (US-ASCII only), - * as opposed to standard ::isXX (::isalpha, ::isdigit...) which are locale dependent. - * Next functions get parameter as char and don't need double cast ((int)(unsigned char) is required for standard functions). */ - inline static bool isasciidigit(char chr) // locale independent - { - return chr >= '0' && chr <= '9'; - } - inline static bool isasciixdigit(char chr) // locale independent - { - return (chr >= '0' && chr <= '9') || (chr >= 'a' && chr <= 'f') || (chr >= 'A' && chr <= 'F'); - } - static int asciidigitvalue(char chr); // locale independent - static int asciixdigitvalue(char chr); // locale independent - inline static bool isasciiuppercaseletter(char chr) // locale independent - { - return (chr >= 'A' && chr <= 'Z'); - } - inline static bool isasciilowercaseletter(char chr) // locale independent - { - return (chr >= 'a' && chr <= 'z'); - } - inline static bool isasciialphanum(char chr) // locale independent - { - return isasciiuppercaseletter(chr) || isasciilowercaseletter(chr) || isasciidigit(chr); - } - static std::string SizeToString(int64_t size); - static const std::string Empty; - static size_t FindWords(const char *str, const char *wordLowerCase); - static int FindEndBracket(const std::string &str, char opener, char closer, int startPos = 0); - static int DateStringToYYYYMMDD(const std::string &dateString); - static void WordToDigits(std::string &word); - static std::string CreateUUID(); - static double CompareFuzzy(const std::string &left, const std::string &right); - static int FindBestMatch(const std::string &str, const std::vector &strings, double &matchscore); - static bool ContainsKeyword(const std::string &str, const std::vector &keywords); - - /*! \brief Escapes the given string to be able to be used as a parameter. - - Escapes backslashes and double-quotes with an additional backslash and - adds double-quotes around the whole string. - - \param param String to escape/paramify - \return Escaped/Paramified string - */ - static std::string Paramify(const std::string ¶m); - - /*! \brief Split a string by the specified delimiters. - Splits a string using one or more delimiting characters, ignoring empty tokens. - Differs from Split() in two ways: - 1. The delimiters are treated as individual characters, rather than a single delimiting string. - 2. Empty tokens are ignored. - \return a vector of tokens - */ - static std::vector Tokenize(const std::string& input, const std::string& delimiters); - static void Tokenize(const std::string& input, std::vector& tokens, const std::string& delimiters); -private: - static std::string m_lastUUID; -}; diff -Nru kodiplatform-15.0.0/src/util/timeutils.h kodiplatform-16.0.0/src/util/timeutils.h --- kodiplatform-15.0.0/src/util/timeutils.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/timeutils.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../os.h" - -#if defined(__APPLE__) -#include -#include -#elif defined(__WINDOWS__) -#include -#else -#include -#endif - -namespace PLATFORM -{ - #if defined(__WINDOWS__) - struct timezone - { - int tz_minuteswest; - int tz_dsttime; - }; - - #define usleep(t) Sleep((DWORD)(t)/1000) - - inline int gettimeofday(struct timeval *pcur_time, struct timezone *tz) - { - if (pcur_time == NULL) - { - SetLastError(EFAULT); - return -1; - } - struct _timeb current; - - _ftime(¤t); - - pcur_time->tv_sec = (long) current.time; - pcur_time->tv_usec = current.millitm * 1000L; - if (tz) - { - tz->tz_minuteswest = current.timezone; /* minutes west of Greenwich */ - tz->tz_dsttime = current.dstflag; /* type of dst correction */ - } - return 0; - } - #endif - - inline int64_t GetTimeMs() - { - #if defined(__APPLE__) - return (int64_t) (CVGetCurrentHostTime() / (int64_t)(CVGetHostClockFrequency() * 0.001)); - #elif defined(__WINDOWS__) - LARGE_INTEGER tickPerSecond; - LARGE_INTEGER tick; - if (QueryPerformanceFrequency(&tickPerSecond)) - { - QueryPerformanceCounter(&tick); - return (int64_t) (tick.QuadPart / (tickPerSecond.QuadPart / 1000.)); - } - return -1; - #else - timespec time; - clock_gettime(CLOCK_MONOTONIC, &time); - return (int64_t)time.tv_sec * 1000 + time.tv_nsec / 1000000; - #endif - } - - template - inline T GetTimeSec() - { - return (T)GetTimeMs() / (T)1000.0; - } - - class CTimeout - { - public: - CTimeout(void) : m_iTarget(0) {} - CTimeout(uint32_t iTimeout) { Init(iTimeout); } - - bool IsSet(void) const { return m_iTarget > 0; } - void Init(uint32_t iTimeout) { m_iTarget = GetTimeMs() + iTimeout; } - - uint32_t TimeLeft(void) const - { - uint64_t iNow = GetTimeMs(); - return (iNow > m_iTarget) ? 0 : (uint32_t)(m_iTarget - iNow); - } - - private: - uint64_t m_iTarget; - }; -}; diff -Nru kodiplatform-15.0.0/src/util/util.h kodiplatform-16.0.0/src/util/util.h --- kodiplatform-15.0.0/src/util/util.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/util.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#ifndef SAFE_DELETE -#define SAFE_DELETE(p) do { delete (p); (p)=NULL; } while (0) -#endif -#ifndef SAFE_DELETE_ARRAY -#define SAFE_DELETE_ARRAY(p) do { delete[] (p); (p)=NULL; } while (0) -#endif diff -Nru kodiplatform-15.0.0/src/util/XMLUtils.h kodiplatform-16.0.0/src/util/XMLUtils.h --- kodiplatform-15.0.0/src/util/XMLUtils.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/util/XMLUtils.h 2015-05-18 12:43:10.000000000 +0000 @@ -21,7 +21,7 @@ * */ -#include "StdString.h" +#include #include "tinyxml.h" class XMLUtils diff -Nru kodiplatform-15.0.0/src/windows/dlfcn-win32.cpp kodiplatform-16.0.0/src/windows/dlfcn-win32.cpp --- kodiplatform-15.0.0/src/windows/dlfcn-win32.cpp 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/dlfcn-win32.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,263 +0,0 @@ -/* - * dlfcn-win32 - * Copyright (c) 2007 Ramiro Polla - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "dlfcn-win32.h" - -/* Note: - * MSDN says these functions are not thread-safe. We make no efforts to have - * any kind of thread safety. - */ - -/* I have no special reason to have set MAX_GLOBAL_OBJECTS to this value. Any - * comments are welcome. - */ -#define MAX_OBJECTS 255 - -static HMODULE global_objects[MAX_OBJECTS]; - -/* This function adds an object to the list of global objects. - * The implementation is very simple and slow. - * TODO: should failing this function be enough to fail the call to dlopen( )? - */ -static void global_object_add( HMODULE hModule ) -{ - int i; - - for( i = 0 ; i < MAX_OBJECTS ; i++ ) - { - if( !global_objects[i] ) - { - global_objects[i] = hModule; - break; - } - } -} - -static void global_object_rem( HMODULE hModule ) -{ - int i; - - for( i = 0 ; i < MAX_OBJECTS ; i++ ) - { - if( global_objects[i] == hModule ) - { - global_objects[i] = 0; - break; - } - } -} - -/* Argument to last function. Used in dlerror( ) */ -static char last_name[MAX_PATH]; - -static int copy_string( char *dest, int dest_size, const char *src ) -{ - int i = 0; - - if( src && dest ) - { - for( i = 0 ; i < dest_size-1 ; i++ ) - { - if( !src[i] ) - break; - else - dest[i] = src[i]; - } - } - dest[i] = '\0'; - - return i; -} - -void *dlopen( const char *file, int mode ) -{ - HMODULE hModule; - UINT uMode; - - /* Do not let Windows display the critical-error-handler message box */ - uMode = SetErrorMode( SEM_FAILCRITICALERRORS ); - - if( file == 0 ) - { - /* Save NULL pointer for error message */ - _snprintf_s( last_name, MAX_PATH, MAX_PATH, "0x%p", file ); - - /* POSIX says that if the value of file is 0, a handle on a global - * symbol object must be provided. That object must be able to access - * all symbols from the original program file, and any objects loaded - * with the RTLD_GLOBAL flag. - * The return value from GetModuleHandle( ) allows us to retrieve - * symbols only from the original program file. For objects loaded with - * the RTLD_GLOBAL flag, we create our own list later on. - */ - hModule = GetModuleHandle( NULL ); - } - else - { - char lpFileName[MAX_PATH]; - int i; - - /* MSDN says backslashes *must* be used instead of forward slashes. */ - for( i = 0 ; i < sizeof(lpFileName)-1 ; i++ ) - { - if( !file[i] ) - break; - else if( file[i] == '/' ) - lpFileName[i] = '\\'; - else - lpFileName[i] = file[i]; - } - lpFileName[i] = '\0'; - - /* Save file name for error message */ - copy_string( last_name, sizeof(last_name), lpFileName ); - - /* POSIX says the search path is implementation-defined. - * LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely - * to UNIX's search paths (start with system folders instead of current - * folder). - */ - hModule = LoadLibraryEx( (LPSTR) lpFileName, NULL, - LOAD_WITH_ALTERED_SEARCH_PATH ); - /* If the object was loaded with RTLD_GLOBAL, add it to list of global - * objects, so that its symbols may be retrieved even if the handle for - * the original program file is passed. POSIX says that if the same - * file is specified in multiple invocations, and any of them are - * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the - * symbols will remain global. - */ - - if( hModule && (mode & RTLD_GLOBAL) ) - global_object_add( hModule ); - } - - /* Return to previous state of the error-mode bit flags. */ - SetErrorMode( uMode ); - - return (void *) hModule; -} - -int dlclose( void *handle ) -{ - HMODULE hModule = (HMODULE) handle; - BOOL ret; - - /* Save handle for error message */ - _snprintf_s( last_name, MAX_PATH, MAX_PATH, "0x%p", handle ); - - ret = FreeLibrary( hModule ); - - /* If the object was loaded with RTLD_GLOBAL, remove it from list of global - * objects. - */ - if( ret ) - global_object_rem( hModule ); - - /* dlclose's return value in inverted in relation to FreeLibrary's. */ - ret = !ret; - - return (int) ret; -} - -void *dlsym( void *handle, const char *name ) -{ - FARPROC symbol; - HMODULE myhandle = (HMODULE) handle; - - /* Save symbol name for error message */ - copy_string( last_name, sizeof(last_name), name ); - - symbol = GetProcAddress( myhandle, name ); -#if 0 - if( symbol == NULL ) - { - HMODULE hModule; - - /* If the handle for the original program file is passed, also search - * in all globally loaded objects. - */ - - hModule = GetModuleHandle( NULL ); - - if( hModule == handle ) - { - int i; - - for( i = 0 ; i < MAX_OBJECTS ; i++ ) - { - if( global_objects[i] != 0 ) - { - symbol = GetProcAddress( global_objects[i], name ); - if( symbol != NULL ) - break; - } - } - } - - - CloseHandle( hModule ); - } -#endif - return (void*) symbol; -} - -char *dlerror( void ) -{ - DWORD dwMessageId; - /* POSIX says this function doesn't have to be thread-safe, so we use one - * static buffer. - * MSDN says the buffer cannot be larger than 64K bytes, so we set it to - * the limit. - */ - static char lpBuffer[65535]; - DWORD ret; - - dwMessageId = GetLastError( ); - - if( dwMessageId == 0 ) - return NULL; - - /* Format error message to: - * "": - */ - ret = copy_string( lpBuffer, sizeof(lpBuffer), "\"" ); - ret += copy_string( lpBuffer+ret, sizeof(lpBuffer)-ret, last_name ); - ret += copy_string( lpBuffer+ret, sizeof(lpBuffer)-ret, "\": " ); - ret += FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId, - MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), - lpBuffer+ret, sizeof(lpBuffer)-ret, NULL ); - - if( ret > 1 ) - { - /* POSIX says the string must not have trailing */ - if( lpBuffer[ret-2] == '\r' && lpBuffer[ret-1] == '\n' ) - lpBuffer[ret-2] = '\0'; - } - - /* POSIX says that invoking dlerror( ) a second time, immediately following - * a prior invocation, shall result in NULL being returned. - */ - SetLastError(0); - - return lpBuffer; -} - diff -Nru kodiplatform-15.0.0/src/windows/dlfcn-win32.h kodiplatform-16.0.0/src/windows/dlfcn-win32.h --- kodiplatform-15.0.0/src/windows/dlfcn-win32.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/dlfcn-win32.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -#pragma once -/* - * dlfcn-win32 - * Copyright (c) 2007 Ramiro Polla - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DLFCN_H -#define DLFCN_H - -/* POSIX says these are implementation-defined. - * To simplify use with Windows API, we treat them the same way. - */ - -#define RTLD_LAZY 0 -#define RTLD_NOW 0 - -#define RTLD_GLOBAL (1 << 1) -#define RTLD_LOCAL (1 << 2) - -/* These two were added in The Open Group Base Specifications Issue 6. - * Note: All other RTLD_* flags in any dlfcn.h are not standard compliant. - */ - -#define RTLD_DEFAULT 0 -#define RTLD_NEXT 0 - -void *dlopen ( const char *file, int mode ); -int dlclose( void *handle ); -void *dlsym ( void *handle, const char *name ); -char *dlerror( void ); - -#endif /* DLFCN-WIN32_H */ diff -Nru kodiplatform-15.0.0/src/windows/inttypes.h kodiplatform-16.0.0/src/windows/inttypes.h --- kodiplatform-15.0.0/src/windows/inttypes.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/inttypes.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,308 +0,0 @@ -// ISO C9x compliant inttypes.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_INTTYPES_H_ // [ -#define _MSC_INTTYPES_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include "stdint.h" - -// 7.8 Format conversion of integer types - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -// 7.8.1 Macros for format specifiers - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 - -// The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" - -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" - -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" - -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" - -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" - -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" - -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" - -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -#define PRIdS "Id" -#define PRIuS "Iu" - -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] - -#endif // __STDC_FORMAT_MACROS ] - -// 7.8.2 Functions for greatest-width integer types - -// 7.8.2.1 The imaxabs function -#define imaxabs _abs64 - -// 7.8.2.2 The imaxdiv function - -// This is modified version of div() function from Microsoft's div.c found -// in %MSVC.NET%\crt\src\div.c -#ifdef STATIC_IMAXDIV // [ -static -#else // STATIC_IMAXDIV ][ -_inline -#endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } - - return result; -} - -// 7.8.2.3 The strtoimax and strtoumax functions -#define strtoimax _strtoi64 -#define strtoumax _strtoui64 - -// 7.8.2.4 The wcstoimax and wcstoumax functions -#define wcstoimax _wcstoi64 -#define wcstoumax _wcstoui64 - - -#endif // _MSC_INTTYPES_H_ ] diff -Nru kodiplatform-15.0.0/src/windows/os-socket.h kodiplatform-16.0.0/src/windows/os-socket.h --- kodiplatform-15.0.0/src/windows/os-socket.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/os-socket.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,296 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../os.h" -#include "../util/timeutils.h" - -#include -#include -#include - -#define SHUT_RDWR SD_BOTH - -#ifndef ETIMEDOUT -#define ETIMEDOUT 138 -#endif - -namespace PLATFORM -{ - #ifndef MSG_WAITALL - #define MSG_WAITALL 0x8 - #endif - - inline int GetSocketError(void) - { - int error = WSAGetLastError(); - switch(error) - { - case WSAEINPROGRESS: return EINPROGRESS; - case WSAECONNRESET : return ECONNRESET; - case WSAETIMEDOUT : return ETIMEDOUT; - case WSAEWOULDBLOCK: return EAGAIN; - default : return error; - } - } - - // Serial port - //@{ - inline void SerialSocketClose(serial_socket_t socket) - { - if (socket != INVALID_HANDLE_VALUE) - CloseHandle(socket); - } - - inline ssize_t SerialSocketWrite(serial_socket_t socket, int *iError, void* data, size_t len) - { - if (len != (DWORD)len) - { - *iError = EINVAL; - return -1; - } - - DWORD iBytesWritten(0); - if (socket != INVALID_HANDLE_VALUE) - { - if (!WriteFile(socket, data, (DWORD)len, &iBytesWritten, NULL)) - { - *iError = GetLastError(); - return -1; - } - return (ssize_t)iBytesWritten; - } - - return -1; - } - - inline ssize_t SerialSocketRead(serial_socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/) - { - if (len != (DWORD)len) - { - *iError = EINVAL; - return -1; - } - - DWORD iBytesRead(0); - if (socket != INVALID_HANDLE_VALUE) - { - if(!ReadFile(socket, data, (DWORD)len, &iBytesRead, NULL) != 0) - { - *iError = GetLastError(); - return -1; - } - return (ssize_t)iBytesRead; - } - return -1; - } - //@} - - // TCP - //@{ - inline void TcpSocketSetBlocking(tcp_socket_t socket, bool bSetTo) - { - u_long iSetTo = bSetTo ? 0 : 1; - ioctlsocket(socket, FIONBIO, &iSetTo); - } - - inline void TcpSocketClose(tcp_socket_t socket) - { - closesocket(socket); - } - - inline void TcpSocketShutdown(tcp_socket_t socket) - { - if (socket != INVALID_SOCKET && - socket != SOCKET_ERROR) - shutdown(socket, SHUT_RDWR); - } - - inline ssize_t TcpSocketWrite(tcp_socket_t socket, int *iError, void* data, size_t len) - { - if (socket == INVALID_SOCKET || - socket == SOCKET_ERROR || - len != (int)len) - { - *iError = EINVAL; - return -1; - } - - ssize_t iReturn = send(socket, (char*)data, (int)len, 0); - if (iReturn < (ssize_t)len) - *iError = GetSocketError(); - return iReturn; - } - - inline ssize_t TcpSocketRead(tcp_socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/) - { - int64_t iNow(0), iTarget(0); - ssize_t iBytesRead(0); - *iError = 0; - - if (socket == INVALID_SOCKET || - socket == SOCKET_ERROR || - len != (int)len) - { - *iError = EINVAL; - return -1; - } - - if (iTimeoutMs > 0) - { - iNow = GetTimeMs(); - iTarget = iNow + (int64_t) iTimeoutMs; - } - - fd_set fd_read; - struct timeval tv; - while (iBytesRead >= 0 && iBytesRead < (ssize_t)len && (iTimeoutMs == 0 || iTarget > iNow) && *iError == 0) - { - if (iTimeoutMs > 0) - { - tv.tv_sec = (long)(iTimeoutMs / 1000); - tv.tv_usec = 1000 * (long)(iTimeoutMs % 1000); - - FD_ZERO(&fd_read); - FD_SET(socket, &fd_read); - - if (select((int)socket + 1, &fd_read, NULL, NULL, &tv) == 0) - { - *iError = ETIMEDOUT; - } - TcpSocketSetBlocking(socket, false); - } - - ssize_t iReadResult = (iTimeoutMs > 0) ? - recv(socket, (char*)data + iBytesRead, (int)(len - iBytesRead), 0) : - recv(socket, (char*)data, (int)len, MSG_WAITALL); - int iSocketError = GetSocketError(); - - if (iTimeoutMs > 0) - { - TcpSocketSetBlocking(socket, true); - iNow = GetTimeMs(); - } - - if (iReadResult < 0) - { - if (iSocketError == EAGAIN && iTimeoutMs > 0) - continue; - *iError = iSocketError; - return (iBytesRead > 0) ? iBytesRead : -iSocketError; - } - else if (iReadResult == 0 || (iReadResult != (ssize_t)len && iTimeoutMs == 0)) - { - *iError = ECONNRESET; - } - - iBytesRead += iReadResult; - } - - if (iBytesRead < (ssize_t)len && *iError == 0) - *iError = ETIMEDOUT; - - return iBytesRead; - } - - inline bool TcpResolveAddress(const char *strHost, uint16_t iPort, int *iError, struct addrinfo **info) - { - struct addrinfo hints; - char service[33]; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - sprintf(service, "%d", iPort); - - *iError = getaddrinfo(strHost, service, &hints, info); - return !(*iError); - } - - inline int TcpGetSocketError(tcp_socket_t socket) - { - int iReturn(0); - socklen_t optLen = sizeof(tcp_socket_t); - getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *)&iReturn, &optLen); - return iReturn; - } - - inline bool TcpSetNoDelay(tcp_socket_t socket) - { - int iSetTo(1); - setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&iSetTo, sizeof(iSetTo)); - return true; - } - - inline bool TcpConnectSocket(tcp_socket_t socket, struct addrinfo* addr, int *iError, uint64_t iTimeout = 0) - { - TcpSocketSetBlocking(socket, false); - - *iError = 0; - int iConnectResult = connect(socket, addr->ai_addr, (int)addr->ai_addrlen); - if (iConnectResult == -1) - { - if (GetSocketError() == EINPROGRESS || - GetSocketError() == EAGAIN) - { - fd_set fd_write, fd_except; - struct timeval tv; - tv.tv_sec = (long)(iTimeout / 1000); - tv.tv_usec = 1000 * (long)(iTimeout % 1000); - - FD_ZERO(&fd_write); - FD_ZERO(&fd_except); - FD_SET(socket, &fd_write); - FD_SET(socket, &fd_except); - - int iPollResult = select(sizeof(socket)*8, NULL, &fd_write, &fd_except, &tv); - if (iPollResult == 0) - *iError = ETIMEDOUT; - else if (iPollResult == -1) - *iError = GetSocketError(); - else - { - socklen_t errlen = sizeof(int); - getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *)iError, &errlen); - } - } - else - { - *iError = GetSocketError(); - } - } - - TcpSocketSetBlocking(socket, true); - - return *iError == 0; - } -} diff -Nru kodiplatform-15.0.0/src/windows/os-threads.cpp kodiplatform-16.0.0/src/windows/os-threads.cpp --- kodiplatform-15.0.0/src/windows/os-threads.cpp 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/os-threads.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../os.h" -#include "os-threads.h" -using namespace PLATFORM; - -static ConditionArg g_InitializeConditionVariable; -static ConditionArg g_WakeConditionVariable; -static ConditionArg g_WakeAllConditionVariable; -static ConditionMutexArg g_SleepConditionVariableCS; - -// check whether vista+ conditions are available at runtime -static bool CheckVistaConditionFunctions(void) -{ - static int iHasVistaConditionFunctions(-1); - if (iHasVistaConditionFunctions == -1) - { - HMODULE handle = GetModuleHandle("Kernel32"); - if (handle == NULL) - { - iHasVistaConditionFunctions = 0; - } - else - { - g_InitializeConditionVariable = (ConditionArg) GetProcAddress(handle,"InitializeConditionVariable"); - g_WakeConditionVariable = (ConditionArg) GetProcAddress(handle,"WakeConditionVariable"); - g_WakeAllConditionVariable = (ConditionArg) GetProcAddress(handle,"WakeAllConditionVariable"); - g_SleepConditionVariableCS = (ConditionMutexArg)GetProcAddress(handle,"SleepConditionVariableCS"); - - // 1 when everything is resolved, 0 otherwise - iHasVistaConditionFunctions = g_InitializeConditionVariable && - g_WakeConditionVariable && - g_WakeAllConditionVariable && - g_SleepConditionVariableCS ? 1 : 0; - } - } - return iHasVistaConditionFunctions == 1; -} - -CConditionImpl::CConditionImpl(void) -{ - m_bOnVista = CheckVistaConditionFunctions(); - if (m_bOnVista) - (*g_InitializeConditionVariable)(m_conditionVista = new CONDITION_VARIABLE); - else - m_conditionPreVista = ::CreateEvent(NULL, TRUE, FALSE, NULL); -} - -CConditionImpl::~CConditionImpl(void) -{ - if (m_bOnVista) - delete m_conditionVista; - else - ::CloseHandle(m_conditionPreVista); -} - -void CConditionImpl::Signal(void) -{ - if (m_bOnVista) - (*g_WakeConditionVariable)(m_conditionVista); - else - ::SetEvent(m_conditionPreVista); -} - -void CConditionImpl::Broadcast(void) -{ - if (m_bOnVista) - (*g_WakeAllConditionVariable)(m_conditionVista); - else - ::SetEvent(m_conditionPreVista); -} - -bool CConditionImpl::Wait(mutex_t &mutex) -{ - if (m_bOnVista) - { - return ((*g_SleepConditionVariableCS)(m_conditionVista, mutex, INFINITE) ? true : false); - } - else - { - ::ResetEvent(m_conditionPreVista); - MutexUnlock(mutex); - DWORD iWaitReturn = ::WaitForSingleObject(m_conditionPreVista, 1000); - MutexLock(mutex); - return (iWaitReturn == 0); - } -} - -bool CConditionImpl::Wait(mutex_t &mutex, uint32_t iTimeoutMs) -{ - if (iTimeoutMs == 0) - return Wait(mutex); - - if (m_bOnVista) - { - return ((*g_SleepConditionVariableCS)(m_conditionVista, mutex, iTimeoutMs) ? true : false); - } - else - { - ::ResetEvent(m_conditionPreVista); - MutexUnlock(mutex); - DWORD iWaitReturn = ::WaitForSingleObject(m_conditionPreVista, iTimeoutMs); - MutexLock(mutex); - return (iWaitReturn == 0); - } -} diff -Nru kodiplatform-15.0.0/src/windows/os-threads.h kodiplatform-16.0.0/src/windows/os-threads.h --- kodiplatform-15.0.0/src/windows/os-threads.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/os-threads.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -namespace PLATFORM -{ - #define thread_t HANDLE - #define ThreadsWait(thread, retVal) (::WaitForSingleObject(thread, INFINITE) < 0) - #define ThreadsCreate(thread, func, arg) ((thread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL)) == NULL ? false : true) - - typedef CRITICAL_SECTION* mutex_t; - #define MutexCreate(mutex) ::InitializeCriticalSection(mutex = new CRITICAL_SECTION) - #define MutexDelete(mutex) ::DeleteCriticalSection(mutex); delete mutex - #define MutexLock(mutex) ::EnterCriticalSection(mutex) - #define MutexTryLock(mutex) (::TryEnterCriticalSection(mutex) != 0) - #define MutexUnlock(mutex) ::LeaveCriticalSection(mutex) - - // windows vista+ conditions - typedef VOID (WINAPI *ConditionArg) (CONDITION_VARIABLE*); - typedef BOOL (WINAPI *ConditionMutexArg)(CONDITION_VARIABLE*, CRITICAL_SECTION*, DWORD); - - class CConditionImpl - { - public: - CConditionImpl(void); - virtual ~CConditionImpl(void); - void Signal(void); - void Broadcast(void); - bool Wait(mutex_t &mutex); - bool Wait(mutex_t &mutex, uint32_t iTimeoutMs); - - bool m_bOnVista; - CONDITION_VARIABLE *m_conditionVista; - HANDLE m_conditionPreVista; - }; -} diff -Nru kodiplatform-15.0.0/src/windows/os-types.h kodiplatform-16.0.0/src/windows/os-types.h --- kodiplatform-15.0.0/src/windows/os-types.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/os-types.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -#pragma once -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#if !defined(__WINDOWS__) -#define __WINDOWS__ -#endif - -#ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ -#endif - -#define WIN32_LEAN_AND_MEAN // Enable LEAN_AND_MEAN support -#ifndef NOMINMAX -#define NOMINMAX // don't define min() and max() to prevent a clash with std::min() and std::max -#endif -#include -#include - -/* Platform dependent path separator */ -#ifndef PATH_SEPARATOR_CHAR -#define PATH_SEPARATOR_CHAR '\\' -#define PATH_SEPARATOR_STRING "\\" -#endif - -/* Handling of 2-byte Windows wchar strings */ -#define WcsLen wcslen -#define WcsToMbs wcstombs -typedef wchar_t Wchar_t; /* sizeof(wchar_t) = 2 bytes on Windows */ - -#pragma warning(disable:4005) // Disable "warning C4005: '_WINSOCKAPI_' : macro redefinition" -#include -#pragma warning(default:4005) - -#include -#include -#include -#include -#include -#include -#include - -typedef SOCKET tcp_socket_t; -#define INVALID_SOCKET_VALUE INVALID_SOCKET -typedef HANDLE serial_socket_t; -#define INVALID_SERIAL_SOCKET_VALUE INVALID_HANDLE_VALUE - -#ifndef _SSIZE_T_DEFINED -#ifdef _WIN64 -typedef __int64 ssize_t; -#else -typedef _W64 int ssize_t; -#endif -#define _SSIZE_T_DEFINED -#endif - -/* Prevent deprecation warnings */ -#define snprintf _snprintf -#define strnicmp _strnicmp - -#if defined(_MSC_VER) -#pragma warning (push) -#endif - -#define NOGDI -#if defined(_MSC_VER) /* prevent inclusion of wingdi.h */ -#pragma warning (pop) -#endif - -#pragma warning(disable:4189) /* disable 'defined but not used' */ -#pragma warning(disable:4100) /* disable 'unreferenced formal parameter' */ diff -Nru kodiplatform-15.0.0/src/windows/serialport.cpp kodiplatform-16.0.0/src/windows/serialport.cpp --- kodiplatform-15.0.0/src/windows/serialport.cpp 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/serialport.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ -/* - * This file is part of the libCEC(R) library. - * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. - * libCEC(R) is an original work, containing original code. - * - * libCEC(R) is a trademark of Pulse-Eight Limited. - * - * This program is dual-licensed; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * - * Alternatively, you can license this library under a commercial license, - * please contact Pulse-Eight Licensing for more information. - * - * For more information contact: - * Pulse-Eight Licensing - * http://www.pulse-eight.com/ - * http://www.pulse-eight.net/ - */ - -#include "../sockets/serialport.h" -#include "../util/baudrate.h" -#include "../util/timeutils.h" - -using namespace std; -using namespace PLATFORM; - -void FormatWindowsError(int iErrorCode, CStdString &strMessage) -{ - if (iErrorCode != ERROR_SUCCESS) - { - char strAddMessage[1024]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, iErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), strAddMessage, 1024, NULL); - strMessage.append(": "); - strMessage.append(strAddMessage); - } -} - -bool SetTimeouts(serial_socket_t socket, int* iError, bool bBlocking) -{ - if (socket == INVALID_HANDLE_VALUE) - return false; - - COMMTIMEOUTS cto; - if (!GetCommTimeouts(socket, &cto)) - { - *iError = GetLastError(); - return false; - } - - if (bBlocking) - { - cto.ReadIntervalTimeout = 0; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } - else - { - cto.ReadIntervalTimeout = MAXDWORD; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } - - if (!SetCommTimeouts(socket, &cto)) - { - *iError = GetLastError(); - return false; - } - - return true; -} - -void CSerialSocket::Close(void) -{ - if (IsOpen()) - SerialSocketClose(m_socket); - m_socket = INVALID_SERIAL_SOCKET_VALUE; -} - -void CSerialSocket::Shutdown(void) -{ - if (IsOpen()) - SerialSocketClose(m_socket); - m_socket = INVALID_SERIAL_SOCKET_VALUE; -} - -ssize_t CSerialSocket::Write(void* data, size_t len) -{ - return IsOpen() ? SerialSocketWrite(m_socket, &m_iError, data, len) : -1; -} - -ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 */) -{ - return IsOpen() ? SerialSocketRead(m_socket, &m_iError, data, len, iTimeoutMs) : -1; -} - -bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) -{ - iTimeoutMs = 0; - if (IsOpen()) - return false; - - CStdString strComPath = "\\\\.\\" + m_strName; - CLockObject lock(m_mutex); - m_socket = CreateFile(strComPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (m_socket == INVALID_HANDLE_VALUE) - { - m_strError = "Unable to open COM port"; - FormatWindowsError(GetLastError(), m_strError); - return false; - } - - COMMCONFIG commConfig = {0}; - DWORD dwSize = sizeof(commConfig); - commConfig.dwSize = dwSize; - if (GetDefaultCommConfig(strComPath.c_str(), &commConfig,&dwSize)) - { - if (!SetCommConfig(m_socket, &commConfig,dwSize)) - { - m_strError = "unable to set default config"; - FormatWindowsError(GetLastError(), m_strError); - } - } - else - { - m_strError = "unable to get default config"; - FormatWindowsError(GetLastError(), m_strError); - } - - if (!SetupComm(m_socket, 64, 64)) - { - m_strError = "unable to set up the com port"; - FormatWindowsError(GetLastError(), m_strError); - } - - if (!SetBaudRate(m_iBaudrate)) - { - m_strError = "unable to set baud rate"; - FormatWindowsError(GetLastError(), m_strError); - Close(); - return false; - } - - if (!SetTimeouts(m_socket, &m_iError, false)) - { - m_strError = "unable to set timeouts"; - FormatWindowsError(GetLastError(), m_strError); - Close(); - return false; - } - - m_bIsOpen = true; - return m_bIsOpen; -} - -bool CSerialSocket::SetBaudRate(uint32_t baudrate) -{ - int32_t rate = IntToBaudrate(baudrate); - if (rate < 0) - m_iBaudrate = baudrate > 0 ? baudrate : 0; - else - m_iBaudrate = rate; - - DCB dcb; - memset(&dcb,0,sizeof(dcb)); - dcb.DCBlength = sizeof(dcb); - dcb.BaudRate = IntToBaudrate(m_iBaudrate); - dcb.fBinary = true; - dcb.fDtrControl = DTR_CONTROL_DISABLE; - dcb.fRtsControl = RTS_CONTROL_DISABLE; - dcb.fOutxCtsFlow = false; - dcb.fOutxDsrFlow = false; - dcb.fOutX = false; - dcb.fInX = false; - dcb.fAbortOnError = true; - - if (m_iParity == SERIAL_PARITY_NONE) - dcb.Parity = NOPARITY; - else if (m_iParity == SERIAL_PARITY_EVEN) - dcb.Parity = EVENPARITY; - else - dcb.Parity = ODDPARITY; - - if (m_iStopbits == SERIAL_STOP_BITS_TWO) - dcb.StopBits = TWOSTOPBITS; - else - dcb.StopBits = ONESTOPBIT; - - dcb.ByteSize = (BYTE)m_iDatabits; - - if(!SetCommState(m_socket,&dcb)) - { - m_strError = "SetCommState failed"; - FormatWindowsError(GetLastError(), m_strError); - return false; - } - - return true; -} diff -Nru kodiplatform-15.0.0/src/windows/stdint.h kodiplatform-16.0.0/src/windows/stdint.h --- kodiplatform-15.0.0/src/windows/stdint.h 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/src/windows/stdint.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff -Nru kodiplatform-15.0.0/UseMultiArch.cmake kodiplatform-16.0.0/UseMultiArch.cmake --- kodiplatform-15.0.0/UseMultiArch.cmake 2015-03-08 16:05:30.000000000 +0000 +++ kodiplatform-16.0.0/UseMultiArch.cmake 2015-05-18 12:43:10.000000000 +0000 @@ -14,7 +14,8 @@ # Fedora uses lib64/ for 64-bit systems, Debian uses lib/x86_64-linux-gnu; # Fedora put module files in lib64/ too, but Debian uses lib/ for that -if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") +if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux" AND + "${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr") # Debian or Ubuntu? if (EXISTS "/etc/debian_version") set (_libdir_def "lib/${CMAKE_LIBRARY_ARCHITECTURE}") @@ -28,10 +29,10 @@ endif (CMAKE_SIZEOF_VOID_P EQUAL 8) set (_libdir_def "${_libdir_noarch}") endif (EXISTS "/etc/debian_version") -else ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") +else () set (_libdir_def "lib") set (_libdir_noarch "lib") -endif ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") +endif () # let the user override if somewhere else is desirable set (CMAKE_INSTALL_LIBDIR "${_libdir_def}" CACHE PATH "Object code libraries")