From dff71be00b07d293b318fede3167b3c48f2270b8 Mon Sep 17 00:00:00 2001 From: Marc Laukien Date: Sun, 22 Sep 2002 15:57:38 +0000 Subject: dos2unix --- cpp/src/IceUtil/Base64.cpp | 542 ++++++++--------- cpp/src/IceUtil/Cond.cpp | 466 +++++++------- cpp/src/IceUtil/Exception.cpp | 198 +++--- cpp/src/IceUtil/InputUtil.cpp | 368 +++++------ cpp/src/IceUtil/OutputUtil.cpp | 1142 +++++++++++++++++------------------ cpp/src/IceUtil/RWRecMutex.cpp | 710 +++++++++++----------- cpp/src/IceUtil/RecMutex.cpp | 336 +++++------ cpp/src/IceUtil/Thread.cpp | 638 +++++++++---------- cpp/src/IceUtil/ThreadException.cpp | 200 +++--- cpp/src/IceUtil/Time.cpp | 284 ++++----- cpp/src/IceUtil/UUID.cpp | 100 +-- cpp/src/IceUtil/Unicode.cpp | 298 ++++----- 12 files changed, 2641 insertions(+), 2641 deletions(-) (limited to 'cpp/src') diff --git a/cpp/src/IceUtil/Base64.cpp b/cpp/src/IceUtil/Base64.cpp index 078448c8106..00ef4d55a68 100644 --- a/cpp/src/IceUtil/Base64.cpp +++ b/cpp/src/IceUtil/Base64.cpp @@ -1,271 +1,271 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include -#include - -using namespace std; - -string -IceUtil::Base64::encode(const vector& plainSeq) -{ - string retval; - - if(plainSeq.size() == 0) - { - return retval; - } - - // Reserve enough space for the returned base64 string - unsigned long base64Bytes = (((plainSeq.size() * 4) / 3) + 1); - unsigned long newlineBytes = (((base64Bytes * 2) / 76) + 1); - unsigned long totalBytes = base64Bytes + newlineBytes; - - retval.reserve(totalBytes); - - unsigned char by1 = 0; - unsigned char by2 = 0; - unsigned char by3 = 0; - unsigned char by4 = 0; - unsigned char by5 = 0; - unsigned char by6 = 0; - unsigned char by7 = 0; - - for(unsigned long i = 0; i < plainSeq.size(); i += 3) - { - by1 = plainSeq[i]; - by2 = 0; - by3 = 0; - - if((i + 1) < plainSeq.size()) - { - by2 = plainSeq[i+1]; - } - - if((i + 2) < plainSeq.size()) - { - by3 = plainSeq[i+2]; - } - - by4 = by1 >> 2; - by5 = ((by1 & 0x3) << 4) | (by2 >> 4); - by6 = ((by2 & 0xf) << 2) | (by3 >> 6); - by7 = by3 & 0x3f; - - retval += encode(by4); - retval += encode(by5); - - if((i + 1) < plainSeq.size()) - { - retval += encode(by6); - } - else - { - retval += "="; - } - - if((i + 2) < plainSeq.size()) - { - retval += encode(by7); - } - else - { - retval += "="; - } - } - - string outString; - outString.reserve(totalBytes); - string::iterator iter = retval.begin(); - - while((retval.end() - iter) > 76) - { - copy(iter, iter+76, back_inserter(outString)); - outString += "\r\n"; - iter += 76; - } - - copy(iter, retval.end(), back_inserter(outString)); - - return outString; -} - -vector -IceUtil::Base64::decode(const string& str) -{ - string newStr; - - newStr.reserve(str.length()); - - for(unsigned long j = 0; j < str.length(); j++) - { - if(isBase64(str[j])) - { - newStr += str[j]; - } - } - - vector retval; - - if(newStr.length() == 0) - { - return retval; - } - - // Note: This is how we were previously computing the size of the return - // sequence. The method below is more efficient (and correct). - // unsigned long lines = str.size() / 78; - // unsigned long totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4); - - // Figure out how long the final sequence is going to be. - unsigned long totalBytes = (newStr.size() * 3 / 4) + 1; - - retval.reserve(totalBytes); - - unsigned char by1 = 0; - unsigned char by2 = 0; - unsigned char by3 = 0; - unsigned char by4 = 0; - - char c1, c2, c3, c4; - - for(unsigned long i = 0; i < newStr.length(); i += 4) - { - c1 = 'A'; - c2 = 'A'; - c3 = 'A'; - c4 = 'A'; - - c1 = newStr[i]; - - if((i + 1) < newStr.length()) - { - c2 = newStr[i + 1]; - } - - if((i + 2) < newStr.length()) - { - c3 = newStr[i + 2]; - } - - if((i + 3) < newStr.length()) - { - c4 = newStr[i + 3]; - } - - by1 = decode(c1); - by2 = decode(c2); - by3 = decode(c3); - by4 = decode(c4); - - retval.push_back((by1 << 2) | (by2 >> 4)); - - if(c3 != '=') - { - retval.push_back(((by2 & 0xf) << 4) | (by3 >> 2)); - } - - if(c4 != '=') - { - retval.push_back(((by3 & 0x3) << 6) | by4); - } - } - - return retval; -} - -char -IceUtil::Base64::encode(unsigned char uc) -{ - if(uc < 26) - { - return 'A' + uc; - } - - if(uc < 52) - { - return 'a' + (uc - 26); - } - - if(uc < 62) - { - return '0' + (uc - 52); - } - - if(uc == 62) - { - return '+'; - } - - return '/'; -} - -unsigned char -IceUtil::Base64::decode(char c) -{ - if(c >= 'A' && c <= 'Z') - { - return c - 'A'; - } - - if(c >= 'a' && c <= 'z') - { - return c - 'a' + 26; - } - - if(c >= '0' && c <= '9') - { - return c - '0' + 52; - } - - if(c == '+') - { - return 62; - } - - return 63; -} - - -bool -IceUtil::Base64::isBase64(char c) -{ - if(c >= 'A' && c <= 'Z') - { - return true; - } - - if(c >= 'a' && c <= 'z') - { - return true; - } - - if(c >= '0' && c <= '9') - { - return true; - } - - if(c == '+') - { - return true; - } - - if(c == '/') - { - return true; - } - - if(c == '=') - { - return true; - } - - return false; -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include +#include + +using namespace std; + +string +IceUtil::Base64::encode(const vector& plainSeq) +{ + string retval; + + if(plainSeq.size() == 0) + { + return retval; + } + + // Reserve enough space for the returned base64 string + unsigned long base64Bytes = (((plainSeq.size() * 4) / 3) + 1); + unsigned long newlineBytes = (((base64Bytes * 2) / 76) + 1); + unsigned long totalBytes = base64Bytes + newlineBytes; + + retval.reserve(totalBytes); + + unsigned char by1 = 0; + unsigned char by2 = 0; + unsigned char by3 = 0; + unsigned char by4 = 0; + unsigned char by5 = 0; + unsigned char by6 = 0; + unsigned char by7 = 0; + + for(unsigned long i = 0; i < plainSeq.size(); i += 3) + { + by1 = plainSeq[i]; + by2 = 0; + by3 = 0; + + if((i + 1) < plainSeq.size()) + { + by2 = plainSeq[i+1]; + } + + if((i + 2) < plainSeq.size()) + { + by3 = plainSeq[i+2]; + } + + by4 = by1 >> 2; + by5 = ((by1 & 0x3) << 4) | (by2 >> 4); + by6 = ((by2 & 0xf) << 2) | (by3 >> 6); + by7 = by3 & 0x3f; + + retval += encode(by4); + retval += encode(by5); + + if((i + 1) < plainSeq.size()) + { + retval += encode(by6); + } + else + { + retval += "="; + } + + if((i + 2) < plainSeq.size()) + { + retval += encode(by7); + } + else + { + retval += "="; + } + } + + string outString; + outString.reserve(totalBytes); + string::iterator iter = retval.begin(); + + while((retval.end() - iter) > 76) + { + copy(iter, iter+76, back_inserter(outString)); + outString += "\r\n"; + iter += 76; + } + + copy(iter, retval.end(), back_inserter(outString)); + + return outString; +} + +vector +IceUtil::Base64::decode(const string& str) +{ + string newStr; + + newStr.reserve(str.length()); + + for(unsigned long j = 0; j < str.length(); j++) + { + if(isBase64(str[j])) + { + newStr += str[j]; + } + } + + vector retval; + + if(newStr.length() == 0) + { + return retval; + } + + // Note: This is how we were previously computing the size of the return + // sequence. The method below is more efficient (and correct). + // unsigned long lines = str.size() / 78; + // unsigned long totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4); + + // Figure out how long the final sequence is going to be. + unsigned long totalBytes = (newStr.size() * 3 / 4) + 1; + + retval.reserve(totalBytes); + + unsigned char by1 = 0; + unsigned char by2 = 0; + unsigned char by3 = 0; + unsigned char by4 = 0; + + char c1, c2, c3, c4; + + for(unsigned long i = 0; i < newStr.length(); i += 4) + { + c1 = 'A'; + c2 = 'A'; + c3 = 'A'; + c4 = 'A'; + + c1 = newStr[i]; + + if((i + 1) < newStr.length()) + { + c2 = newStr[i + 1]; + } + + if((i + 2) < newStr.length()) + { + c3 = newStr[i + 2]; + } + + if((i + 3) < newStr.length()) + { + c4 = newStr[i + 3]; + } + + by1 = decode(c1); + by2 = decode(c2); + by3 = decode(c3); + by4 = decode(c4); + + retval.push_back((by1 << 2) | (by2 >> 4)); + + if(c3 != '=') + { + retval.push_back(((by2 & 0xf) << 4) | (by3 >> 2)); + } + + if(c4 != '=') + { + retval.push_back(((by3 & 0x3) << 6) | by4); + } + } + + return retval; +} + +char +IceUtil::Base64::encode(unsigned char uc) +{ + if(uc < 26) + { + return 'A' + uc; + } + + if(uc < 52) + { + return 'a' + (uc - 26); + } + + if(uc < 62) + { + return '0' + (uc - 52); + } + + if(uc == 62) + { + return '+'; + } + + return '/'; +} + +unsigned char +IceUtil::Base64::decode(char c) +{ + if(c >= 'A' && c <= 'Z') + { + return c - 'A'; + } + + if(c >= 'a' && c <= 'z') + { + return c - 'a' + 26; + } + + if(c >= '0' && c <= '9') + { + return c - '0' + 52; + } + + if(c == '+') + { + return 62; + } + + return 63; +} + + +bool +IceUtil::Base64::isBase64(char c) +{ + if(c >= 'A' && c <= 'Z') + { + return true; + } + + if(c >= 'a' && c <= 'z') + { + return true; + } + + if(c >= '0' && c <= '9') + { + return true; + } + + if(c == '+') + { + return true; + } + + if(c == '/') + { + return true; + } + + if(c == '=') + { + return true; + } + + return false; +} diff --git a/cpp/src/IceUtil/Cond.cpp b/cpp/src/IceUtil/Cond.cpp index cffa290dc4a..551d81c2520 100644 --- a/cpp/src/IceUtil/Cond.cpp +++ b/cpp/src/IceUtil/Cond.cpp @@ -1,233 +1,233 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include - -#ifndef _WIN32 -# include -#endif - -#ifdef _WIN32 - -IceUtil::Semaphore::Semaphore(long initial) -{ - _sem = CreateSemaphore(0, initial, 0x7fffffff, 0); - if(_sem == INVALID_HANDLE_VALUE) - { - throw ThreadSyscallException(__FILE__, __LINE__); - } -} - -IceUtil::Semaphore::~Semaphore() -{ - CloseHandle(_sem); -} - -void -IceUtil::Semaphore::wait() const -{ - int rc = WaitForSingleObject(_sem, INFINITE); - if(rc != WAIT_OBJECT_0) - { - throw ThreadSyscallException(__FILE__, __LINE__); - } -} - -bool -IceUtil::Semaphore::timedWait(const Time& timeout) const -{ - timeval tv = timeout; - long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); - - int rc = WaitForSingleObject(_sem, msec); - if(rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0) - { - throw ThreadSyscallException(__FILE__, __LINE__); - } - return rc != WAIT_TIMEOUT; -} - -void -IceUtil::Semaphore::post(int count) const -{ - int rc = ReleaseSemaphore(_sem, count, 0); - if(rc == 0) - { - throw ThreadSyscallException(__FILE__, __LINE__); - } -} - -IceUtil::Cond::Cond() : - _gate(1), - _blocked(0), - _unblocked(0), - _toUnblock(0) -{ -} - -IceUtil::Cond::~Cond() -{ -} - -void -IceUtil::Cond::signal() -{ - wake(false); -} - -void -IceUtil::Cond::broadcast() -{ - wake(true); -} - -void -IceUtil::Cond::wake(bool broadcast) -{ - // - // Lock gate & mutex. - // - _gate.wait(); - _internal.lock(); - - if(_unblocked != 0) - { - _blocked -= _unblocked; - _unblocked = 0; - } - - if(_blocked > 0) - { - // - // Unblock some number of waiters. - // - _toUnblock = (broadcast) ? _blocked : 1; - _internal.unlock(); - _queue.post(); - } - else - { - // - // Otherwise no blocked waiters, release gate & mutex. - // - _gate.post(); - _internal.unlock(); - } -} - -void -IceUtil::Cond::preWait() const -{ - _gate.wait(); - _blocked++; - _gate.post(); -} - -void -IceUtil::Cond::postWait(bool timedOut) const -{ - _internal.lock(); - _unblocked++; - - if(_toUnblock != 0) - { - bool last = --_toUnblock == 0; - _internal.unlock(); - - if(timedOut) - { - _queue.wait(); - } - - if(last) - { - _gate.post(); - } - else - { - _queue.post(); - } - } - else - { - _internal.unlock(); - } -} - -void -IceUtil::Cond::dowait() const -{ - try - { - _queue.wait(); - postWait(false); - } - catch(...) - { - postWait(false); - throw; - } -} - -bool -IceUtil::Cond::timedDowait(const Time& timeout) const -{ - try - { - bool rc = _queue.timedWait(timeout); - postWait(!rc); - return rc; - } - catch(...) - { - postWait(false); - throw; - } -} - -#else - -IceUtil::Cond::Cond() -{ - int rc = pthread_cond_init(&_cond, 0); - if(rc != 0) - { - throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); - } -} - -IceUtil::Cond::~Cond() -{ - int rc = 0; - rc = pthread_cond_destroy(&_cond); - assert(rc == 0); -} - -void -IceUtil::Cond::signal() -{ - int rc = pthread_cond_signal(&_cond); - if(rc != 0) - { - throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); - } -} - -void -IceUtil::Cond::broadcast() -{ - int rc = pthread_cond_broadcast(&_cond); - if(rc != 0) - { - throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); - } -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include + +#ifndef _WIN32 +# include +#endif + +#ifdef _WIN32 + +IceUtil::Semaphore::Semaphore(long initial) +{ + _sem = CreateSemaphore(0, initial, 0x7fffffff, 0); + if(_sem == INVALID_HANDLE_VALUE) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } +} + +IceUtil::Semaphore::~Semaphore() +{ + CloseHandle(_sem); +} + +void +IceUtil::Semaphore::wait() const +{ + int rc = WaitForSingleObject(_sem, INFINITE); + if(rc != WAIT_OBJECT_0) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } +} + +bool +IceUtil::Semaphore::timedWait(const Time& timeout) const +{ + timeval tv = timeout; + long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); + + int rc = WaitForSingleObject(_sem, msec); + if(rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } + return rc != WAIT_TIMEOUT; +} + +void +IceUtil::Semaphore::post(int count) const +{ + int rc = ReleaseSemaphore(_sem, count, 0); + if(rc == 0) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } +} + +IceUtil::Cond::Cond() : + _gate(1), + _blocked(0), + _unblocked(0), + _toUnblock(0) +{ +} + +IceUtil::Cond::~Cond() +{ +} + +void +IceUtil::Cond::signal() +{ + wake(false); +} + +void +IceUtil::Cond::broadcast() +{ + wake(true); +} + +void +IceUtil::Cond::wake(bool broadcast) +{ + // + // Lock gate & mutex. + // + _gate.wait(); + _internal.lock(); + + if(_unblocked != 0) + { + _blocked -= _unblocked; + _unblocked = 0; + } + + if(_blocked > 0) + { + // + // Unblock some number of waiters. + // + _toUnblock = (broadcast) ? _blocked : 1; + _internal.unlock(); + _queue.post(); + } + else + { + // + // Otherwise no blocked waiters, release gate & mutex. + // + _gate.post(); + _internal.unlock(); + } +} + +void +IceUtil::Cond::preWait() const +{ + _gate.wait(); + _blocked++; + _gate.post(); +} + +void +IceUtil::Cond::postWait(bool timedOut) const +{ + _internal.lock(); + _unblocked++; + + if(_toUnblock != 0) + { + bool last = --_toUnblock == 0; + _internal.unlock(); + + if(timedOut) + { + _queue.wait(); + } + + if(last) + { + _gate.post(); + } + else + { + _queue.post(); + } + } + else + { + _internal.unlock(); + } +} + +void +IceUtil::Cond::dowait() const +{ + try + { + _queue.wait(); + postWait(false); + } + catch(...) + { + postWait(false); + throw; + } +} + +bool +IceUtil::Cond::timedDowait(const Time& timeout) const +{ + try + { + bool rc = _queue.timedWait(timeout); + postWait(!rc); + return rc; + } + catch(...) + { + postWait(false); + throw; + } +} + +#else + +IceUtil::Cond::Cond() +{ + int rc = pthread_cond_init(&_cond, 0); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } +} + +IceUtil::Cond::~Cond() +{ + int rc = 0; + rc = pthread_cond_destroy(&_cond); + assert(rc == 0); +} + +void +IceUtil::Cond::signal() +{ + int rc = pthread_cond_signal(&_cond); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } +} + +void +IceUtil::Cond::broadcast() +{ + int rc = pthread_cond_broadcast(&_cond); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } +} + +#endif diff --git a/cpp/src/IceUtil/Exception.cpp b/cpp/src/IceUtil/Exception.cpp index f239e8ba53b..18c25824027 100644 --- a/cpp/src/IceUtil/Exception.cpp +++ b/cpp/src/IceUtil/Exception.cpp @@ -1,99 +1,99 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include - -using namespace std; - -IceUtil::Exception::Exception() : - _file(0), - _line(0) -{ -} - -IceUtil::Exception::Exception(const char* file, int line) : - _file(file), - _line(line) -{ -} - -IceUtil::Exception::~Exception() -{ -} - -string -IceUtil::Exception::ice_name() const -{ - return "IceUtil::Exception"; -} - -void -IceUtil::Exception::ice_print(ostream& out) const -{ - if(_file && _line > 0) - { - out << _file << ':' << _line << ": "; - } - out << ice_name(); -} - -IceUtil::Exception* -IceUtil::Exception::ice_clone() const -{ - return new Exception(*this); -} - -void -IceUtil::Exception::ice_throw() const -{ - throw *this; -} - -const char* -IceUtil::Exception::ice_file() const -{ - return _file; -} - -int -IceUtil::Exception::ice_line() const -{ - return _line; -} - -ostream& -IceUtil::operator<<(ostream& out, const IceUtil::Exception& ex) -{ - ex.ice_print(out); - return out; -} - -IceUtil::NullHandleException::NullHandleException(const char* file, int line) : - Exception(file, line) -{ -} - -string -IceUtil::NullHandleException::ice_name() const -{ - return "IceUtil::NullHandleException"; -} - -IceUtil::Exception* -IceUtil::NullHandleException::ice_clone() const -{ - return new NullHandleException(*this); -} - -void -IceUtil::NullHandleException::ice_throw() const -{ - throw *this; -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include + +using namespace std; + +IceUtil::Exception::Exception() : + _file(0), + _line(0) +{ +} + +IceUtil::Exception::Exception(const char* file, int line) : + _file(file), + _line(line) +{ +} + +IceUtil::Exception::~Exception() +{ +} + +string +IceUtil::Exception::ice_name() const +{ + return "IceUtil::Exception"; +} + +void +IceUtil::Exception::ice_print(ostream& out) const +{ + if(_file && _line > 0) + { + out << _file << ':' << _line << ": "; + } + out << ice_name(); +} + +IceUtil::Exception* +IceUtil::Exception::ice_clone() const +{ + return new Exception(*this); +} + +void +IceUtil::Exception::ice_throw() const +{ + throw *this; +} + +const char* +IceUtil::Exception::ice_file() const +{ + return _file; +} + +int +IceUtil::Exception::ice_line() const +{ + return _line; +} + +ostream& +IceUtil::operator<<(ostream& out, const IceUtil::Exception& ex) +{ + ex.ice_print(out); + return out; +} + +IceUtil::NullHandleException::NullHandleException(const char* file, int line) : + Exception(file, line) +{ +} + +string +IceUtil::NullHandleException::ice_name() const +{ + return "IceUtil::NullHandleException"; +} + +IceUtil::Exception* +IceUtil::NullHandleException::ice_clone() const +{ + return new NullHandleException(*this); +} + +void +IceUtil::NullHandleException::ice_throw() const +{ + throw *this; +} diff --git a/cpp/src/IceUtil/InputUtil.cpp b/cpp/src/IceUtil/InputUtil.cpp index 32959cb3fca..322dc195955 100644 --- a/cpp/src/IceUtil/InputUtil.cpp +++ b/cpp/src/IceUtil/InputUtil.cpp @@ -1,184 +1,184 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include -#include -#include - -using namespace std; - -namespace IceUtil -{ - -// -// strToInt64 emulates strtoll() for Windows -// - -Int64 -strToInt64(const char* s, char** endptr, int base) -{ -#if defined(_WIN32) - // - // Assume nothing will be there to convert for now - // - if(endptr) - { - *endptr = const_cast(s); - } - - // - // Skip leading whitespace - // - while(*s && isspace(*s)) - { - ++s; - } - - // - // Check for sign - // - int sign = 1; - if(*s == '+') - { - ++s; - } - else if(*s == '-') - { - sign = -1; - ++s; - } - - // - // Check that base is valid - // - if(base == 0) - { - if(*s == '0') - { - base = 8; - if(*++s == 'x' || *s == 'X') - { - base = 16; - ++s; - } - } - else - { - base = 10; - } - } - else if(base < 2 || base > 36) - { - errno = EINVAL; - return 0; - } - - // - // Check that we have something left to parse - // - if(*s == '/0') - { - return 0; - } - - static const string allDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - const string validDigits(allDigits.begin(), allDigits.begin() + base); - - // - // Table to convert ASCII digits/letters into their value (100 for unused slots) - // - static const char digitVal[] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0' - '9' - 100, 100, 100, 100, 100, 100, 100, // punctuation - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, // 'A' - 'J' - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, // 'K' - 'T' - 30, 31, 32, 33, 34, 35 // 'U' - 'Z' - }; - - Int64 result = 0; - bool overflow = false; - while(*s && validDigits.find_first_of(toupper(*s)) != validDigits.npos) - { - if(!overflow) - { - int digit = digitVal[toupper(*s) - '0']; - assert(digit != 100); - if(result < Int64Max / base) - { - result *= base; - result += digit; - } - else if((digit <= Int64Max % base) || (sign == -1 && digit == Int64Max % base + 1)) - { - result *= base; - result += digit; - } - else - { - overflow = true; - result = sign == -1 ? Int64Min : Int64Max; - } - } - ++s; - } - - if(overflow) - { - errno = ERANGE; - } - else - { - result *= sign; - } - - if(endptr) - { - *endptr = const_cast(s); - } - - return result; - -#else - return strtoll(s, endptr, base); -#endif -} - -bool -stringToInt64(const string& stringToParse, Int64& result, string::size_type& pos) -{ - string::const_iterator i = stringToParse.begin(); - while(i != stringToParse.end() && isspace(*i)) - { - ++i; - } - if(i == stringToParse.end()) // String empty or nothing but whitespace - { - result = 0; - pos = string::npos; - return false; - } - string::const_reverse_iterator j = stringToParse.rbegin(); - while(isspace(*j)) - { - ++j; - } // j now points at last non-whitespace char - - string nonWhite(i, j.base()); // nonWhite has trailing whitespace stripped - - errno = 0; - const char* startp = nonWhite.c_str(); - char* endp; - result = strToInt64(startp, &endp, 0); - pos = *endp == '\0' ? string::npos : (i - stringToParse.begin()) + (endp - startp); - return startp != endp && errno != ERANGE && errno != EINVAL; -} - -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include +#include +#include + +using namespace std; + +namespace IceUtil +{ + +// +// strToInt64 emulates strtoll() for Windows +// + +Int64 +strToInt64(const char* s, char** endptr, int base) +{ +#if defined(_WIN32) + // + // Assume nothing will be there to convert for now + // + if(endptr) + { + *endptr = const_cast(s); + } + + // + // Skip leading whitespace + // + while(*s && isspace(*s)) + { + ++s; + } + + // + // Check for sign + // + int sign = 1; + if(*s == '+') + { + ++s; + } + else if(*s == '-') + { + sign = -1; + ++s; + } + + // + // Check that base is valid + // + if(base == 0) + { + if(*s == '0') + { + base = 8; + if(*++s == 'x' || *s == 'X') + { + base = 16; + ++s; + } + } + else + { + base = 10; + } + } + else if(base < 2 || base > 36) + { + errno = EINVAL; + return 0; + } + + // + // Check that we have something left to parse + // + if(*s == '/0') + { + return 0; + } + + static const string allDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const string validDigits(allDigits.begin(), allDigits.begin() + base); + + // + // Table to convert ASCII digits/letters into their value (100 for unused slots) + // + static const char digitVal[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0' - '9' + 100, 100, 100, 100, 100, 100, 100, // punctuation + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, // 'A' - 'J' + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, // 'K' - 'T' + 30, 31, 32, 33, 34, 35 // 'U' - 'Z' + }; + + Int64 result = 0; + bool overflow = false; + while(*s && validDigits.find_first_of(toupper(*s)) != validDigits.npos) + { + if(!overflow) + { + int digit = digitVal[toupper(*s) - '0']; + assert(digit != 100); + if(result < Int64Max / base) + { + result *= base; + result += digit; + } + else if((digit <= Int64Max % base) || (sign == -1 && digit == Int64Max % base + 1)) + { + result *= base; + result += digit; + } + else + { + overflow = true; + result = sign == -1 ? Int64Min : Int64Max; + } + } + ++s; + } + + if(overflow) + { + errno = ERANGE; + } + else + { + result *= sign; + } + + if(endptr) + { + *endptr = const_cast(s); + } + + return result; + +#else + return strtoll(s, endptr, base); +#endif +} + +bool +stringToInt64(const string& stringToParse, Int64& result, string::size_type& pos) +{ + string::const_iterator i = stringToParse.begin(); + while(i != stringToParse.end() && isspace(*i)) + { + ++i; + } + if(i == stringToParse.end()) // String empty or nothing but whitespace + { + result = 0; + pos = string::npos; + return false; + } + string::const_reverse_iterator j = stringToParse.rbegin(); + while(isspace(*j)) + { + ++j; + } // j now points at last non-whitespace char + + string nonWhite(i, j.base()); // nonWhite has trailing whitespace stripped + + errno = 0; + const char* startp = nonWhite.c_str(); + char* endp; + result = strToInt64(startp, &endp, 0); + pos = *endp == '\0' ? string::npos : (i - stringToParse.begin()) + (endp - startp); + return startp != endp && errno != ERANGE && errno != EINVAL; +} + +} diff --git a/cpp/src/IceUtil/OutputUtil.cpp b/cpp/src/IceUtil/OutputUtil.cpp index ddb7e8d0a42..b29ecd1a9be 100644 --- a/cpp/src/IceUtil/OutputUtil.cpp +++ b/cpp/src/IceUtil/OutputUtil.cpp @@ -1,571 +1,571 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include - -using namespace std; -using namespace IceUtil; - -namespace IceUtil -{ - -NextLine nl; -StartBlock sb; -EndBlock eb; -Separator sp; -EndElement ee; -StartEscapes startEscapes; -EndEscapes endEscapes; - -} - -// ---------------------------------------------------------------------- -// OutputBase -// ---------------------------------------------------------------------- - -IceUtil::OutputBase::OutputBase() : - _out(_fout), - _pos(0), - _indent(0), - _indentSize(4), - _useTab(true), - _separator(true) -{ -} - -IceUtil::OutputBase::OutputBase(ostream& os) : - _out(os), - _pos(0), - _indent(0), - _indentSize(4), - _useTab(true), - _separator(true) -{ -} - - -IceUtil::OutputBase::OutputBase(const char* s) : - _out(_fout), - _pos(0), - _indent(0), - _indentSize(4), - _useTab(true), - _separator(true) -{ - open(s); -} - -IceUtil::OutputBase::~OutputBase() -{ -} - -void -IceUtil::OutputBase::open(const char* s) -{ - _fout.open(s); -} - -void -IceUtil::OutputBase::print(const char* s) -{ - for(unsigned int i = 0; i < strlen(s); ++i) - { - if(s[i] == '\n') - { - _pos = 0; - } - else - { - ++_pos; - } - } - - _out << s; -} - -void -IceUtil::OutputBase::inc() -{ - _indent += _indentSize; -} - -void -IceUtil::OutputBase::dec() -{ - assert(_indent >= _indentSize); - _indent -= _indentSize; -} - -void -IceUtil::OutputBase::useCurrentPosAsIndent() -{ - _indentSave.push(_indent); - _indent = _pos; -} - -void -IceUtil::OutputBase::zeroIndent() -{ - _indentSave.push(_indent); - _indent = 0; -} - -void -IceUtil::OutputBase::restoreIndent() -{ - assert(!_indentSave.empty()); - _indent = _indentSave.top(); - _indentSave.pop(); -} - -void -IceUtil::OutputBase::setIndent(int indentSize) -{ - _indentSize = indentSize; -} - -void -IceUtil::OutputBase::setUseTab(bool useTab) -{ - _useTab = useTab; -} - -void -IceUtil::OutputBase::nl() -{ - _out << '\n'; - _pos = 0; - _separator = true; - - int indent = _indent; - - if(_useTab) - { - while(indent >= 8) - { - indent -= 8; - _out << '\t'; - _pos += 8; - } - } - else - { - while(indent >= _indentSize) - { - indent -= _indentSize; - _out << " "; - _pos += _indentSize; - } - } - - while(indent > 0) - { - --indent; - _out << ' '; - ++_pos; - } - - _out.flush(); -} - -void -IceUtil::OutputBase::sp() -{ - if(_separator) - { - _out << '\n'; - } -} - -bool -IceUtil::OutputBase::operator!() const -{ - return !_out; -} - -streamsize -IceUtil::OutputBase::width() const -{ - return _out.width(); -} - -streamsize -IceUtil::OutputBase::width(streamsize newWidth) -{ - return _out.width(newWidth); -} - -ios_base::fmtflags -IceUtil::OutputBase::flags() const -{ - return _out.flags(); -} - -ios_base::fmtflags -IceUtil::OutputBase::flags(ios_base::fmtflags newFlags) -{ - return _out.flags(newFlags); -} - -ostream::char_type -IceUtil::OutputBase::fill() const -{ - return _out.fill(); -} - -ostream::char_type -IceUtil::OutputBase::fill(ostream::char_type newFill) -{ - return _out.fill(newFill); -} - -// ---------------------------------------------------------------------- -// Output -// ---------------------------------------------------------------------- - -IceUtil::Output::Output() : - OutputBase(), - _blockStart("{"), - _blockEnd("}") -{ -} - -IceUtil::Output::Output(ostream& os) : - OutputBase(os), - _blockStart("{"), - _blockEnd("}") -{ -} - -IceUtil::Output::Output(const char* s) : - OutputBase(s), - _blockStart("{"), - _blockEnd("}") -{ -} - -void -IceUtil::Output::setBeginBlock(const char *bb) -{ - _blockStart = bb; -} - -void -IceUtil::Output::setEndBlock(const char *eb) -{ - _blockEnd = eb; -} - -void -IceUtil::Output::sb() -{ - if(_blockStart.length()) - { - nl(); - _out << _blockStart; - } - ++_pos; - inc(); - _separator = false; -} - -void -IceUtil::Output::eb() -{ - dec(); - if(_blockEnd.length()) - { - nl(); - _out << _blockEnd; - } - --_pos; -} - -Output& -IceUtil::operator<<(Output& out, ios_base& (*val)(ios_base&)) -{ - ostringstream s; - s << val; - out.print(s.str().c_str()); - return out; -} - -// ---------------------------------------------------------------------- -// XMLOutput -// ---------------------------------------------------------------------- - -IceUtil::XMLOutput::XMLOutput() : - OutputBase(), - _se(false), - _text(false), - _sgml(false), - _escape(false) -{ -} - -IceUtil::XMLOutput::XMLOutput(ostream& os) : - OutputBase(os), - _se(false), - _text(false), - _sgml(false), - _escape(false) -{ -} - -IceUtil::XMLOutput::XMLOutput(const char* s) : - OutputBase(s), - _se(false), - _text(false), - _sgml(false), - _escape(false) -{ -} - -void -IceUtil::XMLOutput::setSGML(bool sgml) -{ - _sgml = true; -} - -void -IceUtil::XMLOutput::print(const char* s) -{ - if(_se) - { - _out << '>'; - _se = false; - } - _text = true; - - if(_escape) - { - string escaped = escape(s); - OutputBase::print(escaped.c_str()); - } - else - { - OutputBase::print(s); - } -} - -void -IceUtil::XMLOutput::nl() -{ - if(_se) - { - _se = false; - _out << '>'; - } - OutputBase::nl(); -} - -void -IceUtil::XMLOutput::se(const string& element) -{ - nl(); - - // - // If we're not in SGML mode the output of the '>' character is - // deferred until either the //end-element (in which case a /> is - // emitted) or until something //is displayed. - // - if(_escape) - { - _out << '<' << escape(element); - } - else - { - _out << '<' << element; - } - _se = true; - _text = false; - - string::size_type pos = element.find_first_of(" \t"); - if(pos == string::npos) - { - _elementStack.push(element); - } - else - { - _elementStack.push(element.substr(0, pos)); - } - - ++_pos; // TODO: ??? - inc(); - _separator = false; -} - -void -IceUtil::XMLOutput::ee() -{ - string element = _elementStack.top(); - _elementStack.pop(); - - dec(); - if(_se) - { - // - // SGML (docbook) doesn't support . - // - if(_sgml) - { - _out << ">'; - } - else - { - _out << "/>"; - } - } - else - { - if(!_text) - { - nl(); - } - _out << "'; - } - --_pos; // TODO: ??? - - _se = false; - _text = false; -} - -void -IceUtil::XMLOutput::attr(const string& name, const string& value) -{ - // - // Precondition: Attributes can only be attached to elements. - // - assert(_se); - _out << " " << name << "=\"" << escape(value) << '"'; -} - -void -IceUtil::XMLOutput::startEscapes() -{ - _escape = true; -} - -void -IceUtil::XMLOutput::endEscapes() -{ - _escape = false; -} - -string -IceUtil::XMLOutput::currentElement() const -{ - if(_elementStack.size() > 0) - { - return _elementStack.top(); - } - else - { - return string(); - } -} - -string -IceUtil::XMLOutput::escape(const string& input) const -{ - string v = input; - - // - // Find out whether there is a reserved character to avoid - // conversion if not necessary. - // - static const string allReserved = "<>'\"&"; - if(v.find_first_of(allReserved) != string::npos) - { - // - // First convert all & to & - // - size_t pos = 0; - while((pos = v.find_first_of('&', pos)) != string::npos) - { - v.insert(pos+1, "amp;"); - pos += 4; - } - - // - // Next convert remaining reserved characters. - // - static const string reserved = "<>'\""; - pos = 0; - while((pos = v.find_first_of(reserved, pos)) != string::npos) - { - string replace; - switch(v[pos]) - { - case '>': - replace = ">"; - break; - - case '<': - replace = "<"; - break; - - case '\'': - replace = "'"; - break; - - case '"': - replace = """; - break; - - default: - assert(false); - } - - v.erase(pos, 1); - v.insert(pos, replace); - pos += replace.size(); - } - } - return v; -} - -XMLOutput& -IceUtil::operator<<(XMLOutput& out, ios_base& (*val)(ios_base&)) -{ - ostringstream s; - s << val; - out.print(s.str().c_str()); - return out; -} - -IceUtil::StartElement::StartElement(const string& name) : - _name(name) -{ -} - -const string& -IceUtil::StartElement::getName() const -{ - return _name; -} - -IceUtil::Attribute::Attribute(const string& name, const string& value) : - _name(name), - _value(value) -{ -} - -const string& -IceUtil::Attribute::getName() const -{ - return _name; -} - -const string& -IceUtil::Attribute::getValue() const -{ - return _value; -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include + +using namespace std; +using namespace IceUtil; + +namespace IceUtil +{ + +NextLine nl; +StartBlock sb; +EndBlock eb; +Separator sp; +EndElement ee; +StartEscapes startEscapes; +EndEscapes endEscapes; + +} + +// ---------------------------------------------------------------------- +// OutputBase +// ---------------------------------------------------------------------- + +IceUtil::OutputBase::OutputBase() : + _out(_fout), + _pos(0), + _indent(0), + _indentSize(4), + _useTab(true), + _separator(true) +{ +} + +IceUtil::OutputBase::OutputBase(ostream& os) : + _out(os), + _pos(0), + _indent(0), + _indentSize(4), + _useTab(true), + _separator(true) +{ +} + + +IceUtil::OutputBase::OutputBase(const char* s) : + _out(_fout), + _pos(0), + _indent(0), + _indentSize(4), + _useTab(true), + _separator(true) +{ + open(s); +} + +IceUtil::OutputBase::~OutputBase() +{ +} + +void +IceUtil::OutputBase::open(const char* s) +{ + _fout.open(s); +} + +void +IceUtil::OutputBase::print(const char* s) +{ + for(unsigned int i = 0; i < strlen(s); ++i) + { + if(s[i] == '\n') + { + _pos = 0; + } + else + { + ++_pos; + } + } + + _out << s; +} + +void +IceUtil::OutputBase::inc() +{ + _indent += _indentSize; +} + +void +IceUtil::OutputBase::dec() +{ + assert(_indent >= _indentSize); + _indent -= _indentSize; +} + +void +IceUtil::OutputBase::useCurrentPosAsIndent() +{ + _indentSave.push(_indent); + _indent = _pos; +} + +void +IceUtil::OutputBase::zeroIndent() +{ + _indentSave.push(_indent); + _indent = 0; +} + +void +IceUtil::OutputBase::restoreIndent() +{ + assert(!_indentSave.empty()); + _indent = _indentSave.top(); + _indentSave.pop(); +} + +void +IceUtil::OutputBase::setIndent(int indentSize) +{ + _indentSize = indentSize; +} + +void +IceUtil::OutputBase::setUseTab(bool useTab) +{ + _useTab = useTab; +} + +void +IceUtil::OutputBase::nl() +{ + _out << '\n'; + _pos = 0; + _separator = true; + + int indent = _indent; + + if(_useTab) + { + while(indent >= 8) + { + indent -= 8; + _out << '\t'; + _pos += 8; + } + } + else + { + while(indent >= _indentSize) + { + indent -= _indentSize; + _out << " "; + _pos += _indentSize; + } + } + + while(indent > 0) + { + --indent; + _out << ' '; + ++_pos; + } + + _out.flush(); +} + +void +IceUtil::OutputBase::sp() +{ + if(_separator) + { + _out << '\n'; + } +} + +bool +IceUtil::OutputBase::operator!() const +{ + return !_out; +} + +streamsize +IceUtil::OutputBase::width() const +{ + return _out.width(); +} + +streamsize +IceUtil::OutputBase::width(streamsize newWidth) +{ + return _out.width(newWidth); +} + +ios_base::fmtflags +IceUtil::OutputBase::flags() const +{ + return _out.flags(); +} + +ios_base::fmtflags +IceUtil::OutputBase::flags(ios_base::fmtflags newFlags) +{ + return _out.flags(newFlags); +} + +ostream::char_type +IceUtil::OutputBase::fill() const +{ + return _out.fill(); +} + +ostream::char_type +IceUtil::OutputBase::fill(ostream::char_type newFill) +{ + return _out.fill(newFill); +} + +// ---------------------------------------------------------------------- +// Output +// ---------------------------------------------------------------------- + +IceUtil::Output::Output() : + OutputBase(), + _blockStart("{"), + _blockEnd("}") +{ +} + +IceUtil::Output::Output(ostream& os) : + OutputBase(os), + _blockStart("{"), + _blockEnd("}") +{ +} + +IceUtil::Output::Output(const char* s) : + OutputBase(s), + _blockStart("{"), + _blockEnd("}") +{ +} + +void +IceUtil::Output::setBeginBlock(const char *bb) +{ + _blockStart = bb; +} + +void +IceUtil::Output::setEndBlock(const char *eb) +{ + _blockEnd = eb; +} + +void +IceUtil::Output::sb() +{ + if(_blockStart.length()) + { + nl(); + _out << _blockStart; + } + ++_pos; + inc(); + _separator = false; +} + +void +IceUtil::Output::eb() +{ + dec(); + if(_blockEnd.length()) + { + nl(); + _out << _blockEnd; + } + --_pos; +} + +Output& +IceUtil::operator<<(Output& out, ios_base& (*val)(ios_base&)) +{ + ostringstream s; + s << val; + out.print(s.str().c_str()); + return out; +} + +// ---------------------------------------------------------------------- +// XMLOutput +// ---------------------------------------------------------------------- + +IceUtil::XMLOutput::XMLOutput() : + OutputBase(), + _se(false), + _text(false), + _sgml(false), + _escape(false) +{ +} + +IceUtil::XMLOutput::XMLOutput(ostream& os) : + OutputBase(os), + _se(false), + _text(false), + _sgml(false), + _escape(false) +{ +} + +IceUtil::XMLOutput::XMLOutput(const char* s) : + OutputBase(s), + _se(false), + _text(false), + _sgml(false), + _escape(false) +{ +} + +void +IceUtil::XMLOutput::setSGML(bool sgml) +{ + _sgml = true; +} + +void +IceUtil::XMLOutput::print(const char* s) +{ + if(_se) + { + _out << '>'; + _se = false; + } + _text = true; + + if(_escape) + { + string escaped = escape(s); + OutputBase::print(escaped.c_str()); + } + else + { + OutputBase::print(s); + } +} + +void +IceUtil::XMLOutput::nl() +{ + if(_se) + { + _se = false; + _out << '>'; + } + OutputBase::nl(); +} + +void +IceUtil::XMLOutput::se(const string& element) +{ + nl(); + + // + // If we're not in SGML mode the output of the '>' character is + // deferred until either the //end-element (in which case a /> is + // emitted) or until something //is displayed. + // + if(_escape) + { + _out << '<' << escape(element); + } + else + { + _out << '<' << element; + } + _se = true; + _text = false; + + string::size_type pos = element.find_first_of(" \t"); + if(pos == string::npos) + { + _elementStack.push(element); + } + else + { + _elementStack.push(element.substr(0, pos)); + } + + ++_pos; // TODO: ??? + inc(); + _separator = false; +} + +void +IceUtil::XMLOutput::ee() +{ + string element = _elementStack.top(); + _elementStack.pop(); + + dec(); + if(_se) + { + // + // SGML (docbook) doesn't support . + // + if(_sgml) + { + _out << ">'; + } + else + { + _out << "/>"; + } + } + else + { + if(!_text) + { + nl(); + } + _out << "'; + } + --_pos; // TODO: ??? + + _se = false; + _text = false; +} + +void +IceUtil::XMLOutput::attr(const string& name, const string& value) +{ + // + // Precondition: Attributes can only be attached to elements. + // + assert(_se); + _out << " " << name << "=\"" << escape(value) << '"'; +} + +void +IceUtil::XMLOutput::startEscapes() +{ + _escape = true; +} + +void +IceUtil::XMLOutput::endEscapes() +{ + _escape = false; +} + +string +IceUtil::XMLOutput::currentElement() const +{ + if(_elementStack.size() > 0) + { + return _elementStack.top(); + } + else + { + return string(); + } +} + +string +IceUtil::XMLOutput::escape(const string& input) const +{ + string v = input; + + // + // Find out whether there is a reserved character to avoid + // conversion if not necessary. + // + static const string allReserved = "<>'\"&"; + if(v.find_first_of(allReserved) != string::npos) + { + // + // First convert all & to & + // + size_t pos = 0; + while((pos = v.find_first_of('&', pos)) != string::npos) + { + v.insert(pos+1, "amp;"); + pos += 4; + } + + // + // Next convert remaining reserved characters. + // + static const string reserved = "<>'\""; + pos = 0; + while((pos = v.find_first_of(reserved, pos)) != string::npos) + { + string replace; + switch(v[pos]) + { + case '>': + replace = ">"; + break; + + case '<': + replace = "<"; + break; + + case '\'': + replace = "'"; + break; + + case '"': + replace = """; + break; + + default: + assert(false); + } + + v.erase(pos, 1); + v.insert(pos, replace); + pos += replace.size(); + } + } + return v; +} + +XMLOutput& +IceUtil::operator<<(XMLOutput& out, ios_base& (*val)(ios_base&)) +{ + ostringstream s; + s << val; + out.print(s.str().c_str()); + return out; +} + +IceUtil::StartElement::StartElement(const string& name) : + _name(name) +{ +} + +const string& +IceUtil::StartElement::getName() const +{ + return _name; +} + +IceUtil::Attribute::Attribute(const string& name, const string& value) : + _name(name), + _value(value) +{ +} + +const string& +IceUtil::Attribute::getName() const +{ + return _name; +} + +const string& +IceUtil::Attribute::getValue() const +{ + return _value; +} diff --git a/cpp/src/IceUtil/RWRecMutex.cpp b/cpp/src/IceUtil/RWRecMutex.cpp index ef632a347ec..7cde5079a98 100644 --- a/cpp/src/IceUtil/RWRecMutex.cpp +++ b/cpp/src/IceUtil/RWRecMutex.cpp @@ -1,355 +1,355 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include -#include -#include - -#include - -IceUtil::RWRecMutex::RWRecMutex() : - _count(0), - _waitingWriters(0) -{ -} - -IceUtil::RWRecMutex::~RWRecMutex() -{ -} - -void -IceUtil::RWRecMutex::readlock() const -{ - Mutex::Lock lock(_mutex); - - // - // Wait while a writer holds the lock or while writers are waiting - // to get the lock. - // - while(_count < 0 || _waitingWriters != 0) - { - _readers.wait(lock); - } - _count++; -} - -void -IceUtil::RWRecMutex::tryReadlock() const -{ - Mutex::Lock lock(_mutex); - - // - // Would block if a writer holds the lock or if writers are - // waiting to get the lock. - // - if(_count < 0 || _waitingWriters != 0) - { - throw ThreadLockedException(__FILE__, __LINE__); - } - _count++; -} - -void -IceUtil::RWRecMutex::timedTryReadlock(const Time& timeout) const -{ - Mutex::Lock lock(_mutex); - - // - // Wait while a writer holds the lock or while writers are waiting - // to get the lock. - // - Time end = Time::now() + timeout; - while(_count < 0 || _waitingWriters != 0) - { - Time remainder = end - Time::now(); - if(remainder > Time()) - { - _readers.timedWait(lock, remainder); - } - else - { - throw ThreadLockedException(__FILE__, __LINE__); - } - } - - _count++; -} - -void -IceUtil::RWRecMutex::writelock() const -{ - Mutex::Lock lock(_mutex); - - // - // If the mutex is already write locked by this writer then - // decrement _count, and return. - // - if(_count < 0 && _writerControl == ThreadControl()) - { - --_count; - return; - } - - // - // Wait for the lock to become available and increment the number - // of waiting writers. - // - while(_count != 0) - { - _waitingWriters++; - try - { - _writers.wait(lock); - } - catch(...) - { - --_waitingWriters; - throw; - } - _waitingWriters--; - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; -} - -void -IceUtil::RWRecMutex::tryWritelock() const -{ - Mutex::Lock lock(_mutex); - - // - // If the mutex is already write locked by this writer then - // decrement _count, and return. - // - if(_count < 0 && _writerControl == ThreadControl()) - { - --_count; - return; - } - - // - // If there are readers or other writers then the call would block. - // - if(_count != 0) - { - throw ThreadLockedException(__FILE__, __LINE__); - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; -} - -void -IceUtil::RWRecMutex::timedTryWritelock(const Time& timeout) const -{ - Mutex::Lock lock(_mutex); - - // - // If the mutex is already write locked by this writer then - // decrement _count, and return. - // - if(_count < 0 && _writerControl == ThreadControl()) - { - --_count; - return; - } - - // - // Wait for the lock to become available and increment the number - // of waiting writers. - // - Time end = Time::now() + timeout; - while(_count != 0) - { - Time remainder = end - Time::now(); - if(remainder > Time()) - { - _waitingWriters++; - try - { - _writers.timedWait(lock, remainder); - } - catch(...) - { - --_waitingWriters; - throw; - } - _waitingWriters--; - } - else - { - throw ThreadLockedException(__FILE__, __LINE__); - } - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; -} - -void -IceUtil::RWRecMutex::unlock() const -{ - bool ww; - bool wr; - { - Mutex::Lock lock(_mutex); - - assert(_count != 0); - - // - // If _count < 0, the calling thread is a writer that holds the - // lock, so release the lock. Otherwise, _count is guaranteed to - // be > 0, so the calling thread is a reader releasing the lock. - // - if(_count < 0) - { - // - // Writer called unlock - // - ++_count; - - // - // If the write lock wasn't totally released we're done. - // - if(_count != 0) - { - return; - } - } - else - { - // - // Reader called unlock - // - --_count; - } - - // - // Writers are waiting (ww) if _waitingWriters > 0. In that - // case, it's OK to let another writer into the region once there - // are no more readers (_count == 0). Otherwise, no writers are - // waiting but readers may be waiting (wr). - // - ww = (_waitingWriters != 0 && _count == 0); - wr = (_waitingWriters == 0); - } - - // - // Wake up a waiting writer if there is one. If not, wake up all - // readers (just in case -- there may be none). - // - if(ww) - { - // - // Wake writer - // - _writers.signal(); - } - else if(wr) - { - // - // Wake readers - // - _readers.broadcast(); - } -} - -void -IceUtil::RWRecMutex::upgrade() const -{ - Mutex::Lock lock(_mutex); - - // - // Reader called unlock - // - assert(_count > 0); - --_count; - - // - // Wait to acquire the write lock. - // - while(_count != 0) - { - _waitingWriters++; - try - { - _writers.wait(lock); - } - catch(...) - { - --_waitingWriters; - throw; - } - _waitingWriters--; - - - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; -} - -void -IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const -{ - Mutex::Lock lock(_mutex); - - // - // Reader called unlock - // - assert(_count > 0); - --_count; - - // - // Wait to acquire the write lock. - // - Time end = Time::now() + timeout; - while(_count != 0) - { - Time remainder = end - Time::now(); - if(remainder > Time()) - { - _waitingWriters++; - try - { - _writers.timedWait(lock, remainder); - } - catch(...) - { - --_waitingWriters; - throw; - } - _waitingWriters--; - } - else - { - // - // If a timeout occurred then the lock wasn't acquired. Ensure - // that the _count is increased again before returning. - // - ++_count; - throw ThreadLockedException(__FILE__, __LINE__); - } - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include +#include +#include + +#include + +IceUtil::RWRecMutex::RWRecMutex() : + _count(0), + _waitingWriters(0) +{ +} + +IceUtil::RWRecMutex::~RWRecMutex() +{ +} + +void +IceUtil::RWRecMutex::readlock() const +{ + Mutex::Lock lock(_mutex); + + // + // Wait while a writer holds the lock or while writers are waiting + // to get the lock. + // + while(_count < 0 || _waitingWriters != 0) + { + _readers.wait(lock); + } + _count++; +} + +void +IceUtil::RWRecMutex::tryReadlock() const +{ + Mutex::Lock lock(_mutex); + + // + // Would block if a writer holds the lock or if writers are + // waiting to get the lock. + // + if(_count < 0 || _waitingWriters != 0) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + _count++; +} + +void +IceUtil::RWRecMutex::timedTryReadlock(const Time& timeout) const +{ + Mutex::Lock lock(_mutex); + + // + // Wait while a writer holds the lock or while writers are waiting + // to get the lock. + // + Time end = Time::now() + timeout; + while(_count < 0 || _waitingWriters != 0) + { + Time remainder = end - Time::now(); + if(remainder > Time()) + { + _readers.timedWait(lock, remainder); + } + else + { + throw ThreadLockedException(__FILE__, __LINE__); + } + } + + _count++; +} + +void +IceUtil::RWRecMutex::writelock() const +{ + Mutex::Lock lock(_mutex); + + // + // If the mutex is already write locked by this writer then + // decrement _count, and return. + // + if(_count < 0 && _writerControl == ThreadControl()) + { + --_count; + return; + } + + // + // Wait for the lock to become available and increment the number + // of waiting writers. + // + while(_count != 0) + { + _waitingWriters++; + try + { + _writers.wait(lock); + } + catch(...) + { + --_waitingWriters; + throw; + } + _waitingWriters--; + } + + // + // Got the lock, indicate it's held by a writer. + // + _count = -1; +} + +void +IceUtil::RWRecMutex::tryWritelock() const +{ + Mutex::Lock lock(_mutex); + + // + // If the mutex is already write locked by this writer then + // decrement _count, and return. + // + if(_count < 0 && _writerControl == ThreadControl()) + { + --_count; + return; + } + + // + // If there are readers or other writers then the call would block. + // + if(_count != 0) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + + // + // Got the lock, indicate it's held by a writer. + // + _count = -1; +} + +void +IceUtil::RWRecMutex::timedTryWritelock(const Time& timeout) const +{ + Mutex::Lock lock(_mutex); + + // + // If the mutex is already write locked by this writer then + // decrement _count, and return. + // + if(_count < 0 && _writerControl == ThreadControl()) + { + --_count; + return; + } + + // + // Wait for the lock to become available and increment the number + // of waiting writers. + // + Time end = Time::now() + timeout; + while(_count != 0) + { + Time remainder = end - Time::now(); + if(remainder > Time()) + { + _waitingWriters++; + try + { + _writers.timedWait(lock, remainder); + } + catch(...) + { + --_waitingWriters; + throw; + } + _waitingWriters--; + } + else + { + throw ThreadLockedException(__FILE__, __LINE__); + } + } + + // + // Got the lock, indicate it's held by a writer. + // + _count = -1; +} + +void +IceUtil::RWRecMutex::unlock() const +{ + bool ww; + bool wr; + { + Mutex::Lock lock(_mutex); + + assert(_count != 0); + + // + // If _count < 0, the calling thread is a writer that holds the + // lock, so release the lock. Otherwise, _count is guaranteed to + // be > 0, so the calling thread is a reader releasing the lock. + // + if(_count < 0) + { + // + // Writer called unlock + // + ++_count; + + // + // If the write lock wasn't totally released we're done. + // + if(_count != 0) + { + return; + } + } + else + { + // + // Reader called unlock + // + --_count; + } + + // + // Writers are waiting (ww) if _waitingWriters > 0. In that + // case, it's OK to let another writer into the region once there + // are no more readers (_count == 0). Otherwise, no writers are + // waiting but readers may be waiting (wr). + // + ww = (_waitingWriters != 0 && _count == 0); + wr = (_waitingWriters == 0); + } + + // + // Wake up a waiting writer if there is one. If not, wake up all + // readers (just in case -- there may be none). + // + if(ww) + { + // + // Wake writer + // + _writers.signal(); + } + else if(wr) + { + // + // Wake readers + // + _readers.broadcast(); + } +} + +void +IceUtil::RWRecMutex::upgrade() const +{ + Mutex::Lock lock(_mutex); + + // + // Reader called unlock + // + assert(_count > 0); + --_count; + + // + // Wait to acquire the write lock. + // + while(_count != 0) + { + _waitingWriters++; + try + { + _writers.wait(lock); + } + catch(...) + { + --_waitingWriters; + throw; + } + _waitingWriters--; + + + } + + // + // Got the lock, indicate it's held by a writer. + // + _count = -1; +} + +void +IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const +{ + Mutex::Lock lock(_mutex); + + // + // Reader called unlock + // + assert(_count > 0); + --_count; + + // + // Wait to acquire the write lock. + // + Time end = Time::now() + timeout; + while(_count != 0) + { + Time remainder = end - Time::now(); + if(remainder > Time()) + { + _waitingWriters++; + try + { + _writers.timedWait(lock, remainder); + } + catch(...) + { + --_waitingWriters; + throw; + } + _waitingWriters--; + } + else + { + // + // If a timeout occurred then the lock wasn't acquired. Ensure + // that the _count is increased again before returning. + // + ++_count; + throw ThreadLockedException(__FILE__, __LINE__); + } + } + + // + // Got the lock, indicate it's held by a writer. + // + _count = -1; +} diff --git a/cpp/src/IceUtil/RecMutex.cpp b/cpp/src/IceUtil/RecMutex.cpp index 2f617b2d51d..0a976db7bf1 100644 --- a/cpp/src/IceUtil/RecMutex.cpp +++ b/cpp/src/IceUtil/RecMutex.cpp @@ -1,168 +1,168 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include -#include - -using namespace std; - -#ifdef _WIN32 - -IceUtil::RecMutex::RecMutex() : - _count(0) -{ - InitializeCriticalSection(&_mutex); -} - -IceUtil::RecMutex::~RecMutex() -{ - assert(_count == 0); - DeleteCriticalSection(&_mutex); -} - -bool -IceUtil::RecMutex::lock() const -{ - EnterCriticalSection(&_mutex); - if(++_count > 1) - { - LeaveCriticalSection(&_mutex); - return false; - } - return true; -} - -bool -IceUtil::RecMutex::trylock() const -{ - if(!TryEnterCriticalSection(&_mutex)) - { - throw ThreadLockedException(__FILE__, __LINE__); - } - if(++_count > 1) - { - LeaveCriticalSection(&_mutex); - return false; - } - return true; -} - -bool -IceUtil::RecMutex::unlock() const -{ - if(--_count == 0) - { - LeaveCriticalSection(&_mutex); - return true; - } - return false; -} - -void -IceUtil::RecMutex::unlock(LockState& state) const -{ - state.count = _count; - _count = 0; - LeaveCriticalSection(&_mutex); -} - -void -IceUtil::RecMutex::lock(LockState& state) const -{ - EnterCriticalSection(&_mutex); - _count = state.count; -} -#else - -IceUtil::RecMutex::RecMutex() : - _count(0) -{ - const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP }; - int rc = pthread_mutex_init(&_mutex, &attr); - if(rc != 0) - { - throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); - } -} - -IceUtil::RecMutex::~RecMutex() -{ - assert(_count == 0); - int rc = 0; - rc = pthread_mutex_destroy(&_mutex); - assert(rc == 0); -} - -bool -IceUtil::RecMutex::lock() const -{ - int rc = pthread_mutex_lock(&_mutex); - if(rc != 0) - { - throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); - } - if(++_count > 1) - { - rc = pthread_mutex_unlock(&_mutex); - assert(rc == 0); - return false; - } - return true; -} - -bool -IceUtil::RecMutex::trylock() const -{ - int rc = pthread_mutex_trylock(&_mutex); - if(rc != 0) - { - if(rc == EBUSY) - { - throw ThreadLockedException(__FILE__, __LINE__); - } - throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); - } - if(++_count > 1) - { - rc = pthread_mutex_unlock(&_mutex); - assert(rc == 0); - return false; - } - return true; -} - -bool -IceUtil::RecMutex::unlock() const -{ - if(--_count == 0) - { - int rc = 0; // Prevent warnings when NDEBUG is defined. - rc = pthread_mutex_unlock(&_mutex); - assert(rc == 0); - return true; - } - return false; -} - -void -IceUtil::RecMutex::unlock(LockState& state) const -{ - state.mutex = &_mutex; - state.count = _count; - _count = 0; -} - -void -IceUtil::RecMutex::lock(LockState& state) const -{ - _count = state.count; -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include +#include + +using namespace std; + +#ifdef _WIN32 + +IceUtil::RecMutex::RecMutex() : + _count(0) +{ + InitializeCriticalSection(&_mutex); +} + +IceUtil::RecMutex::~RecMutex() +{ + assert(_count == 0); + DeleteCriticalSection(&_mutex); +} + +bool +IceUtil::RecMutex::lock() const +{ + EnterCriticalSection(&_mutex); + if(++_count > 1) + { + LeaveCriticalSection(&_mutex); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::trylock() const +{ + if(!TryEnterCriticalSection(&_mutex)) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + if(++_count > 1) + { + LeaveCriticalSection(&_mutex); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::unlock() const +{ + if(--_count == 0) + { + LeaveCriticalSection(&_mutex); + return true; + } + return false; +} + +void +IceUtil::RecMutex::unlock(LockState& state) const +{ + state.count = _count; + _count = 0; + LeaveCriticalSection(&_mutex); +} + +void +IceUtil::RecMutex::lock(LockState& state) const +{ + EnterCriticalSection(&_mutex); + _count = state.count; +} +#else + +IceUtil::RecMutex::RecMutex() : + _count(0) +{ + const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP }; + int rc = pthread_mutex_init(&_mutex, &attr); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } +} + +IceUtil::RecMutex::~RecMutex() +{ + assert(_count == 0); + int rc = 0; + rc = pthread_mutex_destroy(&_mutex); + assert(rc == 0); +} + +bool +IceUtil::RecMutex::lock() const +{ + int rc = pthread_mutex_lock(&_mutex); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } + if(++_count > 1) + { + rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::trylock() const +{ + int rc = pthread_mutex_trylock(&_mutex); + if(rc != 0) + { + if(rc == EBUSY) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } + if(++_count > 1) + { + rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::unlock() const +{ + if(--_count == 0) + { + int rc = 0; // Prevent warnings when NDEBUG is defined. + rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); + return true; + } + return false; +} + +void +IceUtil::RecMutex::unlock(LockState& state) const +{ + state.mutex = &_mutex; + state.count = _count; + _count = 0; +} + +void +IceUtil::RecMutex::lock(LockState& state) const +{ + _count = state.count; +} + +#endif diff --git a/cpp/src/IceUtil/Thread.cpp b/cpp/src/IceUtil/Thread.cpp index 31049c5cae0..37bf99a95f3 100644 --- a/cpp/src/IceUtil/Thread.cpp +++ b/cpp/src/IceUtil/Thread.cpp @@ -1,319 +1,319 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include -#include -#include - -using namespace std; - -#ifdef _WIN32 - -IceUtil::ThreadControl::ThreadControl() : - _handle(new HandleWrapper(0)), - _id(GetCurrentThreadId()) -{ - HANDLE proc = GetCurrentProcess(); - HANDLE current = GetCurrentThread(); - int rc = DuplicateHandle(proc, current, proc, &_handle->handle, SYNCHRONIZE, TRUE, 0); - if(rc == 0) - { - throw ThreadSyscallException(__FILE__, __LINE__); - } -} - -IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, unsigned id) : - _handle(handle), - _id(id) -{ -} - -bool -IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const -{ - return _id == rhs._id; -} - -bool -IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const -{ - return _id != rhs._id; -} - -bool -IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const -{ - return _id != rhs._id; -} - -void -IceUtil::ThreadControl::join() -{ - if(_handle->handle) - { - int rc = WaitForSingleObject(_handle->handle, INFINITE); - if(rc != WAIT_OBJECT_0) - { - throw ThreadSyscallException(__FILE__, __LINE__); - } - } -} - -void -IceUtil::ThreadControl::sleep(const Time& timeout) -{ - timeval tv = timeout; - long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); - Sleep(msec); -} - -void -IceUtil::ThreadControl::yield() -{ - // - // A value of zero causes the thread to relinquish the remainder - // of its time slice to any other thread of equal priority that is - // ready to run. - // - Sleep(0); -} - -IceUtil::Thread::Thread() : - _id(0), - _handle(new HandleWrapper(0)) -{ -} - -IceUtil::Thread::~Thread() -{ -} - -static void* -startHook(void* arg) -{ - try - { - IceUtil::Thread* rawThread = static_cast(arg); - - // - // Ensure that the thread doesn't go away until run() has - // completed. - // - IceUtil::ThreadPtr thread = rawThread; - - // - // See the comment in IceUtil::Thread::start() for details. - // - rawThread->__decRef(); - thread->run(); - } - catch(const IceUtil::Exception& e) - { - cerr << "IceUtil::Thread::run(): uncaught exception: "; - cerr << e << endl; - } - return 0; -} - -#include - -IceUtil::ThreadControl -IceUtil::Thread::start() -{ - // - // It's necessary to increment the reference count since - // pthread_create won't necessarily call the thread function until - // later. If the user does (new MyThread)->start() then the thread - // object could be deleted before the thread object takes - // ownership. It's also necessary to increment the reference count - // prior to calling pthread_create since the thread itself calls - // __decRef(). - // - __incRef(); - - _handle->handle = (HANDLE)_beginthreadex(0, 0, (unsigned (__stdcall*)(void*))startHook, (LPVOID)this, 0, &_id); - if(_handle->handle == 0) - { - __decRef(); - throw ThreadSyscallException(__FILE__, __LINE__); - } - - return ThreadControl(_handle, _id); -} - -IceUtil::ThreadControl -IceUtil::Thread::getThreadControl() -{ - return ThreadControl(_handle, _id); -} - -bool -IceUtil::Thread::operator==(const Thread& rhs) const -{ - return _id == rhs._id; -} - -bool -IceUtil::Thread::operator!=(const Thread& rhs) const -{ - return _id != rhs._id; -} - -bool -IceUtil::Thread::operator<(const Thread& rhs) const -{ - return _id < rhs._id; -} - -#else - -IceUtil::ThreadControl::ThreadControl(pthread_t id) : - _id(id) -{ -} - -IceUtil::ThreadControl::ThreadControl() : - _id(pthread_self()) -{ -} - -bool -IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const -{ - return pthread_equal(_id, rhs._id); -} - -bool -IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const -{ - return !pthread_equal(_id, rhs._id); -} - -bool -IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const -{ - // NOTE: Linux specific - return _id < rhs._id; -} - -void -IceUtil::ThreadControl::join() -{ - if(_id) - { - void* ignore = 0; - int rc = pthread_join(_id, &ignore); - if(rc != 0) - { - throw ThreadSyscallException(__FILE__, __LINE__); - } - } -} - -void -IceUtil::ThreadControl::sleep(const Time& timeout) -{ - struct timeval tv = timeout; - struct timespec ts; - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000L; - nanosleep(&ts, 0); -} - -void -IceUtil::ThreadControl::yield() -{ - sched_yield(); -} - -IceUtil::Thread::Thread() -{ -} - -IceUtil::Thread::~Thread() -{ -} - -static void* -startHook(void* arg) -{ - try - { - IceUtil::Thread* rawThread = static_cast(arg); - - // - // Ensure that the thread doesn't go away until run() has - // completed. - // - IceUtil::ThreadPtr thread = rawThread; - - // - // See the comment in IceUtil::Thread::start() for details. - // - rawThread->__decRef(); - thread->run(); - } - catch(const IceUtil::Exception& e) - { - cerr << "IceUtil::Thread::run(): uncaught exception: "; - cerr << e << endl; - } - return 0; -} - -IceUtil::ThreadControl -IceUtil::Thread::start() -{ - // - // It's necessary to increment the reference count since - // pthread_create won't necessarily call the thread function until - // later. If the user does (new MyThread)->start() then the thread - // object could be deleted before the thread object takes - // ownership. It's also necessary to increment the reference count - // prior to calling pthread_create since the thread itself calls - // __decRef(). - // - __incRef(); - int rc = pthread_create(&_id, 0, startHook, this); - if(rc != 0) - { - __decRef(); - throw ThreadSyscallException(__FILE__, __LINE__); - } - return ThreadControl(_id); -} - -IceUtil::ThreadControl -IceUtil::Thread::getThreadControl() -{ - return ThreadControl(_id); -} - -bool -IceUtil::Thread::operator==(const Thread& rhs) const -{ - return pthread_equal(_id, rhs._id); -} - -bool -IceUtil::Thread::operator!=(const Thread& rhs) const -{ - return !pthread_equal(_id, rhs._id); -} - -bool -IceUtil::Thread::operator<(const Thread& rhs) const -{ - // NOTE: Linux specific - return _id < rhs._id; -} - -#endif - +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include +#include +#include + +using namespace std; + +#ifdef _WIN32 + +IceUtil::ThreadControl::ThreadControl() : + _handle(new HandleWrapper(0)), + _id(GetCurrentThreadId()) +{ + HANDLE proc = GetCurrentProcess(); + HANDLE current = GetCurrentThread(); + int rc = DuplicateHandle(proc, current, proc, &_handle->handle, SYNCHRONIZE, TRUE, 0); + if(rc == 0) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } +} + +IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, unsigned id) : + _handle(handle), + _id(id) +{ +} + +bool +IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const +{ + return _id == rhs._id; +} + +bool +IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const +{ + return _id != rhs._id; +} + +bool +IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const +{ + return _id != rhs._id; +} + +void +IceUtil::ThreadControl::join() +{ + if(_handle->handle) + { + int rc = WaitForSingleObject(_handle->handle, INFINITE); + if(rc != WAIT_OBJECT_0) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } + } +} + +void +IceUtil::ThreadControl::sleep(const Time& timeout) +{ + timeval tv = timeout; + long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); + Sleep(msec); +} + +void +IceUtil::ThreadControl::yield() +{ + // + // A value of zero causes the thread to relinquish the remainder + // of its time slice to any other thread of equal priority that is + // ready to run. + // + Sleep(0); +} + +IceUtil::Thread::Thread() : + _id(0), + _handle(new HandleWrapper(0)) +{ +} + +IceUtil::Thread::~Thread() +{ +} + +static void* +startHook(void* arg) +{ + try + { + IceUtil::Thread* rawThread = static_cast(arg); + + // + // Ensure that the thread doesn't go away until run() has + // completed. + // + IceUtil::ThreadPtr thread = rawThread; + + // + // See the comment in IceUtil::Thread::start() for details. + // + rawThread->__decRef(); + thread->run(); + } + catch(const IceUtil::Exception& e) + { + cerr << "IceUtil::Thread::run(): uncaught exception: "; + cerr << e << endl; + } + return 0; +} + +#include + +IceUtil::ThreadControl +IceUtil::Thread::start() +{ + // + // It's necessary to increment the reference count since + // pthread_create won't necessarily call the thread function until + // later. If the user does (new MyThread)->start() then the thread + // object could be deleted before the thread object takes + // ownership. It's also necessary to increment the reference count + // prior to calling pthread_create since the thread itself calls + // __decRef(). + // + __incRef(); + + _handle->handle = (HANDLE)_beginthreadex(0, 0, (unsigned (__stdcall*)(void*))startHook, (LPVOID)this, 0, &_id); + if(_handle->handle == 0) + { + __decRef(); + throw ThreadSyscallException(__FILE__, __LINE__); + } + + return ThreadControl(_handle, _id); +} + +IceUtil::ThreadControl +IceUtil::Thread::getThreadControl() +{ + return ThreadControl(_handle, _id); +} + +bool +IceUtil::Thread::operator==(const Thread& rhs) const +{ + return _id == rhs._id; +} + +bool +IceUtil::Thread::operator!=(const Thread& rhs) const +{ + return _id != rhs._id; +} + +bool +IceUtil::Thread::operator<(const Thread& rhs) const +{ + return _id < rhs._id; +} + +#else + +IceUtil::ThreadControl::ThreadControl(pthread_t id) : + _id(id) +{ +} + +IceUtil::ThreadControl::ThreadControl() : + _id(pthread_self()) +{ +} + +bool +IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const +{ + return pthread_equal(_id, rhs._id); +} + +bool +IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const +{ + return !pthread_equal(_id, rhs._id); +} + +bool +IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const +{ + // NOTE: Linux specific + return _id < rhs._id; +} + +void +IceUtil::ThreadControl::join() +{ + if(_id) + { + void* ignore = 0; + int rc = pthread_join(_id, &ignore); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } + } +} + +void +IceUtil::ThreadControl::sleep(const Time& timeout) +{ + struct timeval tv = timeout; + struct timespec ts; + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000L; + nanosleep(&ts, 0); +} + +void +IceUtil::ThreadControl::yield() +{ + sched_yield(); +} + +IceUtil::Thread::Thread() +{ +} + +IceUtil::Thread::~Thread() +{ +} + +static void* +startHook(void* arg) +{ + try + { + IceUtil::Thread* rawThread = static_cast(arg); + + // + // Ensure that the thread doesn't go away until run() has + // completed. + // + IceUtil::ThreadPtr thread = rawThread; + + // + // See the comment in IceUtil::Thread::start() for details. + // + rawThread->__decRef(); + thread->run(); + } + catch(const IceUtil::Exception& e) + { + cerr << "IceUtil::Thread::run(): uncaught exception: "; + cerr << e << endl; + } + return 0; +} + +IceUtil::ThreadControl +IceUtil::Thread::start() +{ + // + // It's necessary to increment the reference count since + // pthread_create won't necessarily call the thread function until + // later. If the user does (new MyThread)->start() then the thread + // object could be deleted before the thread object takes + // ownership. It's also necessary to increment the reference count + // prior to calling pthread_create since the thread itself calls + // __decRef(). + // + __incRef(); + int rc = pthread_create(&_id, 0, startHook, this); + if(rc != 0) + { + __decRef(); + throw ThreadSyscallException(__FILE__, __LINE__); + } + return ThreadControl(_id); +} + +IceUtil::ThreadControl +IceUtil::Thread::getThreadControl() +{ + return ThreadControl(_id); +} + +bool +IceUtil::Thread::operator==(const Thread& rhs) const +{ + return pthread_equal(_id, rhs._id); +} + +bool +IceUtil::Thread::operator!=(const Thread& rhs) const +{ + return !pthread_equal(_id, rhs._id); +} + +bool +IceUtil::Thread::operator<(const Thread& rhs) const +{ + // NOTE: Linux specific + return _id < rhs._id; +} + +#endif + diff --git a/cpp/src/IceUtil/ThreadException.cpp b/cpp/src/IceUtil/ThreadException.cpp index f0e9acea3b9..88c3413c9fd 100644 --- a/cpp/src/IceUtil/ThreadException.cpp +++ b/cpp/src/IceUtil/ThreadException.cpp @@ -1,100 +1,100 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include - -using namespace std; - -IceUtil::ThreadSyscallException::ThreadSyscallException(const char* file, int line) : - Exception(file, line), -#ifdef _WIN32 - _error(GetLastError()) -#else - _error(errno) -#endif -{ -} - -string -IceUtil::ThreadSyscallException::ice_name() const -{ - return "IceUtil::ThreadSyscallException"; -} - -void -IceUtil::ThreadSyscallException::ice_print(ostream& os) const -{ - Exception::ice_print(os); - if(_error != 0) - { - os << ":\nthread syscall exception: "; -#ifdef _WIN32 - LPVOID lpMsgBuf = 0; - DWORD ok = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - _error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR)&lpMsgBuf, - 0, - NULL); - - if(ok) - { - LPCTSTR msg = (LPCTSTR)lpMsgBuf; - assert(msg && strlen(msg) > 0); - os << msg; - LocalFree(lpMsgBuf); - } - else - { - os << "unknown thread error"; - } -#else - os << strerror(_error); -#endif - } -} - -IceUtil::Exception* -IceUtil::ThreadSyscallException::ice_clone() const -{ - return new ThreadSyscallException(*this); -} - -void -IceUtil::ThreadSyscallException::ice_throw() const -{ - throw *this; -} - -IceUtil::ThreadLockedException::ThreadLockedException(const char* file, int line) : - Exception(file, line) -{ -} - -string -IceUtil::ThreadLockedException::ice_name() const -{ - return "IceUtil::ThreadLockedException"; -} - -IceUtil::Exception* -IceUtil::ThreadLockedException::ice_clone() const -{ - return new ThreadLockedException(*this); -} - -void -IceUtil::ThreadLockedException::ice_throw() const -{ - throw *this; -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include + +using namespace std; + +IceUtil::ThreadSyscallException::ThreadSyscallException(const char* file, int line) : + Exception(file, line), +#ifdef _WIN32 + _error(GetLastError()) +#else + _error(errno) +#endif +{ +} + +string +IceUtil::ThreadSyscallException::ice_name() const +{ + return "IceUtil::ThreadSyscallException"; +} + +void +IceUtil::ThreadSyscallException::ice_print(ostream& os) const +{ + Exception::ice_print(os); + if(_error != 0) + { + os << ":\nthread syscall exception: "; +#ifdef _WIN32 + LPVOID lpMsgBuf = 0; + DWORD ok = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + _error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&lpMsgBuf, + 0, + NULL); + + if(ok) + { + LPCTSTR msg = (LPCTSTR)lpMsgBuf; + assert(msg && strlen(msg) > 0); + os << msg; + LocalFree(lpMsgBuf); + } + else + { + os << "unknown thread error"; + } +#else + os << strerror(_error); +#endif + } +} + +IceUtil::Exception* +IceUtil::ThreadSyscallException::ice_clone() const +{ + return new ThreadSyscallException(*this); +} + +void +IceUtil::ThreadSyscallException::ice_throw() const +{ + throw *this; +} + +IceUtil::ThreadLockedException::ThreadLockedException(const char* file, int line) : + Exception(file, line) +{ +} + +string +IceUtil::ThreadLockedException::ice_name() const +{ + return "IceUtil::ThreadLockedException"; +} + +IceUtil::Exception* +IceUtil::ThreadLockedException::ice_clone() const +{ + return new ThreadLockedException(*this); +} + +void +IceUtil::ThreadLockedException::ice_throw() const +{ + throw *this; +} diff --git a/cpp/src/IceUtil/Time.cpp b/cpp/src/IceUtil/Time.cpp index 886edc4b6e8..6774ec97736 100644 --- a/cpp/src/IceUtil/Time.cpp +++ b/cpp/src/IceUtil/Time.cpp @@ -1,142 +1,142 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include - -#ifdef _WIN32 -# include -#else -# include -#endif - -using namespace IceUtil; - -Time::Time() : - _usec(0) -{ -} - -Time -IceUtil::Time::now() -{ -#ifdef WIN32 - struct _timeb tb; - _ftime(&tb); - return Time(tb.time * static_cast(1000000) + tb.millitm * static_cast(1000)); -#else - struct timeval tv; - gettimeofday(&tv, 0); - return Time(tv.tv_sec * static_cast(1000000) + tv.tv_usec); -#endif -} - -Time -IceUtil::Time::seconds(long t) -{ - return Time(t * static_cast(1000000)); -} - -Time -IceUtil::Time::milliSeconds(long t) -{ - return Time(t * static_cast(1000)); -} - -Time -IceUtil::Time::microSeconds(Int64 t) -{ - return Time(t); -} - -Time -IceUtil::Time::operator-() const -{ - return Time(-_usec); -} - -Time -IceUtil::Time::operator-(const Time& rhs) const -{ - return Time(_usec - rhs._usec); -} - -Time -IceUtil::Time::operator+(const Time& rhs) const -{ - return Time(_usec + rhs._usec); -} - -Time& -IceUtil::Time::operator+=(const Time& rhs) -{ - _usec += rhs._usec; - return *this; -} - -Time& -IceUtil::Time::operator-=(const Time& rhs) -{ - _usec -= rhs._usec; - return *this; -} - -bool -IceUtil::Time::operator<(const Time& rhs) const -{ - return _usec < rhs._usec; -} - -bool -IceUtil::Time::operator<=(const Time& rhs) const -{ - return _usec <= rhs._usec; -} - -bool -IceUtil::Time::operator>(const Time& rhs) const -{ - return _usec > rhs._usec; -} - -bool -IceUtil::Time::operator>=(const Time& rhs) const -{ - return _usec >= rhs._usec; -} - -bool -IceUtil::Time::operator==(const Time& rhs) const -{ - return _usec == rhs._usec; -} - -bool -IceUtil::Time::operator!=(const Time& rhs) const -{ - return _usec != rhs._usec; -} - -IceUtil::Time::operator timeval() const -{ - timeval tv; - tv.tv_sec = static_cast(_usec / 1000000); - tv.tv_usec = static_cast(_usec % 1000000); - return tv; -} - -IceUtil::Time::operator double() const -{ - return _usec / 1000000.0L; -} - -Time::Time(Int64 usec) : - _usec(usec) -{ -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include + +#ifdef _WIN32 +# include +#else +# include +#endif + +using namespace IceUtil; + +Time::Time() : + _usec(0) +{ +} + +Time +IceUtil::Time::now() +{ +#ifdef WIN32 + struct _timeb tb; + _ftime(&tb); + return Time(tb.time * static_cast(1000000) + tb.millitm * static_cast(1000)); +#else + struct timeval tv; + gettimeofday(&tv, 0); + return Time(tv.tv_sec * static_cast(1000000) + tv.tv_usec); +#endif +} + +Time +IceUtil::Time::seconds(long t) +{ + return Time(t * static_cast(1000000)); +} + +Time +IceUtil::Time::milliSeconds(long t) +{ + return Time(t * static_cast(1000)); +} + +Time +IceUtil::Time::microSeconds(Int64 t) +{ + return Time(t); +} + +Time +IceUtil::Time::operator-() const +{ + return Time(-_usec); +} + +Time +IceUtil::Time::operator-(const Time& rhs) const +{ + return Time(_usec - rhs._usec); +} + +Time +IceUtil::Time::operator+(const Time& rhs) const +{ + return Time(_usec + rhs._usec); +} + +Time& +IceUtil::Time::operator+=(const Time& rhs) +{ + _usec += rhs._usec; + return *this; +} + +Time& +IceUtil::Time::operator-=(const Time& rhs) +{ + _usec -= rhs._usec; + return *this; +} + +bool +IceUtil::Time::operator<(const Time& rhs) const +{ + return _usec < rhs._usec; +} + +bool +IceUtil::Time::operator<=(const Time& rhs) const +{ + return _usec <= rhs._usec; +} + +bool +IceUtil::Time::operator>(const Time& rhs) const +{ + return _usec > rhs._usec; +} + +bool +IceUtil::Time::operator>=(const Time& rhs) const +{ + return _usec >= rhs._usec; +} + +bool +IceUtil::Time::operator==(const Time& rhs) const +{ + return _usec == rhs._usec; +} + +bool +IceUtil::Time::operator!=(const Time& rhs) const +{ + return _usec != rhs._usec; +} + +IceUtil::Time::operator timeval() const +{ + timeval tv; + tv.tv_sec = static_cast(_usec / 1000000); + tv.tv_usec = static_cast(_usec % 1000000); + return tv; +} + +IceUtil::Time::operator double() const +{ + return _usec / 1000000.0L; +} + +Time::Time(Int64 usec) : + _usec(usec) +{ +} diff --git a/cpp/src/IceUtil/UUID.cpp b/cpp/src/IceUtil/UUID.cpp index 21bab48af46..95ddb2a1d38 100644 --- a/cpp/src/IceUtil/UUID.cpp +++ b/cpp/src/IceUtil/UUID.cpp @@ -1,50 +1,50 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include - -#ifdef _WIN32 -# include -#else -extern "C" // uuid/uuid.h seems to miss extern "C" declarations. -{ -# include -} -#endif - -using namespace std; - -string -IceUtil::generateUUID() -{ -#ifdef _WIN32 - - UUID uuid; - UuidCreate(&uuid); - - unsigned char* str; - UuidToString(&uuid, &str); - - string result(reinterpret_cast(str)); - RpcStringFree(&str); - return result; - -#else - - uuid_t uuid; - uuid_generate(uuid); - - char str[37]; - uuid_unparse(uuid, str); - - return str; - -#endif -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include + +#ifdef _WIN32 +# include +#else +extern "C" // uuid/uuid.h seems to miss extern "C" declarations. +{ +# include +} +#endif + +using namespace std; + +string +IceUtil::generateUUID() +{ +#ifdef _WIN32 + + UUID uuid; + UuidCreate(&uuid); + + unsigned char* str; + UuidToString(&uuid, &str); + + string result(reinterpret_cast(str)); + RpcStringFree(&str); + return result; + +#else + + uuid_t uuid; + uuid_generate(uuid); + + char str[37]; + uuid_unparse(uuid, str); + + return str; + +#endif +} diff --git a/cpp/src/IceUtil/Unicode.cpp b/cpp/src/IceUtil/Unicode.cpp index d440bb00fe5..2997a6e4dc7 100644 --- a/cpp/src/IceUtil/Unicode.cpp +++ b/cpp/src/IceUtil/Unicode.cpp @@ -1,149 +1,149 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include -#include - -using namespace std; - -string -IceUtil::wstringToString(const wstring& str) -{ - string result; - result.reserve(str.length() * 2); - - for(unsigned int i = 0; i < str.length(); ++i) - { - wchar_t wc; - wc = str[i]; - - if(wc < 0x80) - { - result += static_cast(wc); - } - else if(wc < 0x800) - { - result += 0xc0 | (wc>>6); - result += 0x80 | (wc & 0x3f); - } - else if(wc < 0x10000) - { - result += 0xe0 | (wc>>12); - result += 0x80 | ((wc>>6) & 0x3f); - result += 0x80 | (wc & 0x3f); - } - else if(wc < 0x10FFFF) - { - result += 0xf0 | (wc>>18); - result += 0x80 | ((wc>>12) & 0x3f); - result += 0x80 | ((wc>>6) & 0x3f); - result += 0x80 | (wc & 0x3f); - } - else - { - return result; // Error, not encodable. - } - } - - return result; -} - -wstring -IceUtil::stringToWstring(const string& str) -{ - wstring result; - result.reserve(str.length()); - - unsigned int len; - for(unsigned int i = 0; i < str.length(); i += len) - { - unsigned char c = str[i]; - wchar_t wc; - int minval; - - if(c < 0x80) - { - wc = c; - len = 1; - minval = 0; - } - else if(c < 0xc0) // Lead byte must not be 10xxxxxx - { - return result; // Error, not encodable. - } - else if(c < 0xe0) // 110xxxxx - { - wc = c & 0x1f; - len = 2; - minval = 0x80; - } - else if(c < 0xf0) // 1110xxxx - { - wc = c & 0xf; - len = 3; - minval = 0x800; - } -#if SIZEOF_WCHAR_T >= 4 - else if(c < 0xf8) // 11110xxx - { - wc = c & 7; - len = 4; - minval = 0x10000; - } - else if(c < 0xfc) // 111110xx - { - // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001. - wc = c & 3; - len = 5; - minval = 0x110000; - } - else if(c < 0xfe) // 1111110x - { - // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001. - wc = c & 1; - len = 6; - minval = 0x4000000; - } -#endif - else - { - return result; // Error, not encodable. - } - - if(i + len - 1 < str.length()) - { - for(unsigned int j = 1; j < len; ++j) - { - if((str[i + j] & 0xc0) != 0x80) // All other bytes must be 10xxxxxx - { - return result; // Error, not encodable. - } - - wc <<= 6; - wc |= str[i + j] & 0x3f; - } - - if(wc < minval) - { - return result; // Error, non-shortest form. - } - else - { - result += wc; - } - } - else - { - return result; // Error, not encodable. - } - } - - return result; -} +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include +#include + +using namespace std; + +string +IceUtil::wstringToString(const wstring& str) +{ + string result; + result.reserve(str.length() * 2); + + for(unsigned int i = 0; i < str.length(); ++i) + { + wchar_t wc; + wc = str[i]; + + if(wc < 0x80) + { + result += static_cast(wc); + } + else if(wc < 0x800) + { + result += 0xc0 | (wc>>6); + result += 0x80 | (wc & 0x3f); + } + else if(wc < 0x10000) + { + result += 0xe0 | (wc>>12); + result += 0x80 | ((wc>>6) & 0x3f); + result += 0x80 | (wc & 0x3f); + } + else if(wc < 0x10FFFF) + { + result += 0xf0 | (wc>>18); + result += 0x80 | ((wc>>12) & 0x3f); + result += 0x80 | ((wc>>6) & 0x3f); + result += 0x80 | (wc & 0x3f); + } + else + { + return result; // Error, not encodable. + } + } + + return result; +} + +wstring +IceUtil::stringToWstring(const string& str) +{ + wstring result; + result.reserve(str.length()); + + unsigned int len; + for(unsigned int i = 0; i < str.length(); i += len) + { + unsigned char c = str[i]; + wchar_t wc; + int minval; + + if(c < 0x80) + { + wc = c; + len = 1; + minval = 0; + } + else if(c < 0xc0) // Lead byte must not be 10xxxxxx + { + return result; // Error, not encodable. + } + else if(c < 0xe0) // 110xxxxx + { + wc = c & 0x1f; + len = 2; + minval = 0x80; + } + else if(c < 0xf0) // 1110xxxx + { + wc = c & 0xf; + len = 3; + minval = 0x800; + } +#if SIZEOF_WCHAR_T >= 4 + else if(c < 0xf8) // 11110xxx + { + wc = c & 7; + len = 4; + minval = 0x10000; + } + else if(c < 0xfc) // 111110xx + { + // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001. + wc = c & 3; + len = 5; + minval = 0x110000; + } + else if(c < 0xfe) // 1111110x + { + // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001. + wc = c & 1; + len = 6; + minval = 0x4000000; + } +#endif + else + { + return result; // Error, not encodable. + } + + if(i + len - 1 < str.length()) + { + for(unsigned int j = 1; j < len; ++j) + { + if((str[i + j] & 0xc0) != 0x80) // All other bytes must be 10xxxxxx + { + return result; // Error, not encodable. + } + + wc <<= 6; + wc |= str[i + j] & 0x3f; + } + + if(wc < minval) + { + return result; // Error, non-shortest form. + } + else + { + result += wc; + } + } + else + { + return result; // Error, not encodable. + } + } + + return result; +} -- cgit v1.2.3