diff options
author | Matthew Newhook <matthew@zeroc.com> | 2008-02-14 16:22:39 +0800 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2008-02-14 16:22:39 +0800 |
commit | 294ec25fda6e3785c54970d274b860b1ca837955 (patch) | |
tree | 26e5d1987ffdfde7bbacb87fdfb7b96bbef998e9 /cpp/src | |
parent | Merge branch 'bug2435' (diff) | |
download | ice-294ec25fda6e3785c54970d274b860b1ca837955.tar.bz2 ice-294ec25fda6e3785c54970d274b860b1ca837955.tar.xz ice-294ec25fda6e3785c54970d274b860b1ca837955.zip |
merged bug2615
Diffstat (limited to 'cpp/src')
35 files changed, 974 insertions, 652 deletions
diff --git a/cpp/src/FreezeScript/DumpDB.cpp b/cpp/src/FreezeScript/DumpDB.cpp index b47c45bf51d..676e3d0fd36 100644 --- a/cpp/src/FreezeScript/DumpDB.cpp +++ b/cpp/src/FreezeScript/DumpDB.cpp @@ -79,7 +79,11 @@ private: static void usage(const char* n) { - cerr << "Usage: " << n << " [options] [dbenv [db]]\n"; + cerr << "Usage:\n"; + cerr << "\n"; + cerr << n << " [options] dbenv db\n"; + cerr << n << " -c dbenv [db]\n"; + cerr << "\n"; cerr << "Options:\n" "-h, --help Show this message.\n" diff --git a/cpp/src/Ice/ConnectRequestHandler.cpp b/cpp/src/Ice/ConnectRequestHandler.cpp index c9b7a061e7c..94d22e2f11b 100644 --- a/cpp/src/Ice/ConnectRequestHandler.cpp +++ b/cpp/src/Ice/ConnectRequestHandler.cpp @@ -100,14 +100,9 @@ ConnectRequestHandler::connect() _reference->getConnection(this); Lock sync(*this); - if(_exception.get()) + if(initialized()) { - _exception->ice_throw(); - return 0; // Keep the compiler happy. - } - else if(_connection) - { - assert(_initialized); + assert(_connection); return new ConnectionRequestHandler(_reference, _connection, _compress); } else diff --git a/cpp/src/Ice/Makefile.mak b/cpp/src/Ice/Makefile.mak index 70d067a22b3..f5745c251d4 100644 --- a/cpp/src/Ice/Makefile.mak +++ b/cpp/src/Ice/Makefile.mak @@ -117,7 +117,7 @@ SDIR = $(slicedir)\Ice CPPFLAGS = -I.. $(CPPFLAGS) -DICE_API_EXPORTS -DFD_SETSIZE=1024 -DWIN32_LEAN_AND_MEAN SLICE2CPPFLAGS = --ice --include-dir Ice --dll-export ICE_API $(SLICE2CPPFLAGS) -LINKWITH = $(BASELIBS) $(BZIP2_LIBS) $(ICE_OS_LIBS) ws2_32.lib +LINKWITH = $(BASELIBS) $(BZIP2_LIBS) $(ICE_OS_LIBS) ws2_32.lib Iphlpapi.lib !if "$(CPP_COMPILER)" == "BCC2006" RES_FILE = ,, EventLoggerMsg.res diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 749b5683e27..36adc5b70fe 100644 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -11,10 +11,18 @@ // The following is required on HP-UX in order to bring in // the definition for the ip_mreq structure. // -#ifdef __hpux -#undef _XOPEN_SOURCE_EXTENDED -#define _XOPEN_SOURCE -#include <netinet/in.h> +#if defined(__hpux) +# undef _XOPEN_SOURCE_EXTENDED +# define _XOPEN_SOURCE +# include <netinet/in.h> +#endif + +// +// The following is required for the Vista PSDK to bring in +// the definitions of the IN6_IS_ADDR_* macros. +// +#if defined(_WIN32) && !defined(_WIN32_WINNT) +# define _WIN32_WINNT 0x0501 #endif #include <IceUtil/StringUtil.h> @@ -26,15 +34,15 @@ #if defined(_WIN32) # include <winsock2.h> # include <ws2tcpip.h> -#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__) +# include <iphlpapi.h> +#else # include <ifaddrs.h> # include <net/if.h> -#else # include <sys/ioctl.h> -# include <net/if.h> -# ifdef __sun -# include <sys/sockio.h> -# endif +#endif + +#ifdef __sun +# include <sys/sockio.h> #endif using namespace std; @@ -68,7 +76,7 @@ getLocalAddresses(ProtocolSupport protocol) vector<unsigned char> buffer; buffer.resize(1024); unsigned long len = 0; - DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, + DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, &buffer[0], static_cast<DWORD>(buffer.size()), &len, 0, 0); if(rs == SOCKET_ERROR) @@ -80,7 +88,7 @@ getLocalAddresses(ProtocolSupport protocol) if(getSocketErrno() == WSAEFAULT) { buffer.resize(len); - rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, + rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, &buffer[0], static_cast<DWORD>(buffer.size()), &len, 0, 0); } @@ -94,7 +102,7 @@ getLocalAddresses(ProtocolSupport protocol) } } - // + // // Add the local interface addresses. // SOCKET_ADDRESS_LIST* addrs = reinterpret_cast<SOCKET_ADDRESS_LIST*>(&buffer[0]); @@ -161,7 +169,7 @@ getLocalAddresses(ProtocolSupport protocol) } } } - + curr = curr->ifa_next; } @@ -195,7 +203,7 @@ getLocalAddresses(ProtocolSupport protocol) int bufsize = numaddrs * static_cast<int>(sizeof(struct ifreq)); ifc.ifc_len = bufsize; ifc.ifc_buf = (char*)malloc(bufsize); - + int rs = ioctl(fd, cmd, &ifc); if(rs == SOCKET_ERROR) { @@ -216,7 +224,7 @@ getLocalAddresses(ProtocolSupport protocol) { old_ifc_len = ifc.ifc_len; } - + numaddrs += 10; free(ifc.ifc_buf); } @@ -262,11 +270,11 @@ getAddressImpl(const string& host, int port, struct sockaddr_storage& addr, Prot // We now use getaddrinfo() on Windows. // // #ifdef _WIN32 - + // // // // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice. // // - + // // // // gethostbyname() is thread safe on Windows, with a separate hostent per thread // // @@ -277,7 +285,7 @@ getAddressImpl(const string& host, int port, struct sockaddr_storage& addr, Prot // entry = gethostbyname(host.c_str()); // } // while(entry == 0 && WSAGetLastError() == WSATRY_AGAIN && --retry >= 0); - + // if(entry == 0) // { // DNSException ex(__FILE__, __LINE__); @@ -293,7 +301,7 @@ getAddressImpl(const string& host, int port, struct sockaddr_storage& addr, Prot memset(&addr, 0, sizeof(struct sockaddr_storage)); struct addrinfo* info = 0; int retry = 5; - + struct addrinfo hints = { 0 }; if(server) @@ -301,7 +309,7 @@ getAddressImpl(const string& host, int port, struct sockaddr_storage& addr, Prot // // If host is empty, getaddrinfo will return the wildcard // address instead of the loopack address. - // + // hints.ai_flags |= AI_PASSIVE; } @@ -327,11 +335,11 @@ getAddressImpl(const string& host, int port, struct sockaddr_storage& addr, Prot } else { - rs = getaddrinfo(host.c_str(), 0, &hints, &info); + rs = getaddrinfo(host.c_str(), 0, &hints, &info); } } while(info == 0 && rs == EAI_AGAIN && --retry >= 0); - + if(rs != 0) { DNSException ex(__FILE__, __LINE__); @@ -389,6 +397,86 @@ isWildcard(const string& host, ProtocolSupport protocol) return false; } +int +getInterfaceIndex(const string& name) +{ + int index = 0; +#ifdef _WIN32 + IP_ADAPTER_ADDRESSES addrs; + ULONG buflen = 0; + if(::GetAdaptersAddresses(AF_INET6, 0, 0, &addrs, &buflen) == ERROR_BUFFER_OVERFLOW) + { + PIP_ADAPTER_ADDRESSES paddrs; + char* buf = new char[buflen]; + paddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(buf); + if(::GetAdaptersAddresses(AF_INET6, 0, 0, paddrs, &buflen) == NO_ERROR) + { + while(paddrs) + { + if(IceUtil::wstringToString(paddrs->FriendlyName) == name) + { + index = paddrs->Ipv6IfIndex; + break; + } + paddrs = paddrs->Next; + } + } + delete[] buf; + } +#else + index = if_nametoindex(name.c_str()); +#endif + + return index; +} + +struct in_addr +getInterfaceAddress(const string& name) +{ + struct in_addr addr; + addr.s_addr = INADDR_ANY; +#ifdef _WIN32 + IP_ADAPTER_ADDRESSES addrs; + ULONG buflen = 0; + if(::GetAdaptersAddresses(AF_INET, 0, 0, &addrs, &buflen) == ERROR_BUFFER_OVERFLOW) + { + PIP_ADAPTER_ADDRESSES paddrs; + char* buf = new char[buflen]; + paddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(buf); + if(::GetAdaptersAddresses(AF_INET, 0, 0, paddrs, &buflen) == NO_ERROR) + { + while(paddrs) + { + if(IceUtil::wstringToString(paddrs->FriendlyName) == name) + { + struct sockaddr_in addrin; + memcpy(&addrin, paddrs->FirstUnicastAddress->Address.lpSockaddr, + paddrs->FirstUnicastAddress->Address.iSockaddrLength); + addr = addrin.sin_addr; + break; + } + paddrs = paddrs->Next; + } + } + delete[] buf; + } +#else + ifreq if_address; + strcpy(if_address.ifr_name, name.c_str()); + + SOCKET fd = createSocket(false, AF_INET); + int rc = ioctl(fd, SIOCGIFADDR, &if_address); + closeSocketNoThrow(fd); + + if(rc != SOCKET_ERROR) + { + addr = reinterpret_cast<struct sockaddr_in*>(&if_address.ifr_addr)->sin_addr; + } +#endif + + return addr; +} + } int @@ -609,7 +697,7 @@ IceInternal::closeSocketNoThrow(SOCKET fd) errno = error; #endif } - + void IceInternal::shutdownSocketWrite(SOCKET fd) { @@ -645,7 +733,7 @@ IceInternal::shutdownSocketWrite(SOCKET fd) throw ex; } } - + void IceInternal::shutdownSocketReadWrite(SOCKET fd) { @@ -682,7 +770,7 @@ IceInternal::shutdownSocketReadWrite(SOCKET fd) throw ex; } } - + void IceInternal::setBlock(SOCKET fd, bool block) { @@ -746,7 +834,7 @@ IceInternal::setTcpNoDelay(SOCKET fd) throw ex; } } - + void IceInternal::setKeepAlive(SOCKET fd) { @@ -825,9 +913,16 @@ IceInternal::setMcastGroup(SOCKET fd, const struct sockaddr_storage& group, cons mreq.imr_interface.s_addr = INADDR_ANY; if(interface.size() > 0) { - struct sockaddr_storage addr; - getAddressForServer(interface, 0, addr, EnableIPv4); - mreq.imr_interface = reinterpret_cast<const struct sockaddr_in*>(&addr)->sin_addr; + // + // First see if it is the interface name. If not check if IP Address. + // + mreq.imr_interface = getInterfaceAddress(interface); + if(mreq.imr_interface.s_addr == INADDR_ANY) + { + struct sockaddr_storage addr; + getAddressForServer(interface, 0, addr, EnableIPv4); + mreq.imr_interface = reinterpret_cast<const struct sockaddr_in*>(&addr)->sin_addr; + } } rc = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, int(sizeof(mreq))); } @@ -835,13 +930,24 @@ IceInternal::setMcastGroup(SOCKET fd, const struct sockaddr_storage& group, cons { struct ipv6_mreq mreq; mreq.ipv6mr_multiaddr = reinterpret_cast<const struct sockaddr_in6*>(&group)->sin6_addr; - istringstream p(interface); - if(!(p >> mreq.ipv6mr_interface) || !p.eof()) + mreq.ipv6mr_interface = 0; + if(interface.size() != 0) { - closeSocketNoThrow(fd); - SocketException ex(__FILE__, __LINE__); - ex.error = 0; - throw ex; + // + // First check if it is the interface name. If not check if index. + // + mreq.ipv6mr_interface = getInterfaceIndex(interface); + if(mreq.ipv6mr_interface == 0) + { + istringstream p(interface); + if(!(p >> mreq.ipv6mr_interface) || !p.eof()) + { + closeSocketNoThrow(fd); + SocketException ex(__FILE__, __LINE__); + ex.error = 0; + throw ex; + } + } } rc = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&mreq, int(sizeof(mreq))); } @@ -860,14 +966,34 @@ IceInternal::setMcastInterface(SOCKET fd, const string& interface, bool IPv4) int rc; if(IPv4) { - struct sockaddr_storage addr; - getAddress(interface, 0, addr, EnableIPv4); - struct in_addr iface = reinterpret_cast<const struct sockaddr_in*>(&addr)->sin_addr; + // + // First see if it is the interface name. If not check if IP Address. + // + struct in_addr iface = getInterfaceAddress(interface); + if(iface.s_addr == INADDR_ANY) + { + struct sockaddr_storage addr; + getAddressForServer(interface, 0, addr, EnableIPv4); + iface = reinterpret_cast<const struct sockaddr_in*>(&addr)->sin_addr; + } rc = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char*)&iface, int(sizeof(iface))); } else { - int interfaceNum = atoi(interface.c_str()); + // + // First check if it is the interface name. If not check if index. + // + int interfaceNum = getInterfaceIndex(interface); + if(interfaceNum == 0) + { + istringstream p(interface); + if(!(p >> interfaceNum) || !p.eof()) + { + closeSocketNoThrow(fd); + SocketException ex(__FILE__, __LINE__); + ex.error = 0; + } + } rc = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char*)&interfaceNum, int(sizeof(int))); } if(rc == SOCKET_ERROR) @@ -958,7 +1084,7 @@ repeatListen: { goto repeatListen; } - + closeSocketNoThrow(fd); SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); @@ -991,7 +1117,7 @@ repeatConnect: { goto repeatConnect; } - + if(connectInProgress()) { if(timeout == 0) @@ -1010,7 +1136,7 @@ repeatConnect: } return true; } - + closeSocketNoThrow(fd); if(connectionRefused()) { @@ -1097,7 +1223,7 @@ IceInternal::doFinishConnect(SOCKET fd, int timeout) { goto repeatSelect; } - + SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; @@ -1121,7 +1247,7 @@ IceInternal::doFinishConnect(SOCKET fd, int timeout) ex.error = getSocketErrno(); throw ex; } - + if(val > 0) { #ifdef _WIN32 @@ -1209,27 +1335,27 @@ repeatAccept: pollFd[0].events = POLLIN; rs = ::poll(pollFd, 1, timeout); #endif - + if(rs == SOCKET_ERROR) { if(interrupted()) { goto repeatSelect; } - + SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; } - + if(rs == 0) { throw TimeoutException(__FILE__, __LINE__); } - + goto repeatAccept; } - + SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; @@ -1262,7 +1388,7 @@ IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol // // // // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice. // // - + // // // // gethostbyname() is thread safe on Windows, with a separate hostent per thread // // @@ -1274,7 +1400,7 @@ IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol // entry = gethostbyname(host.c_str()); // } // while(entry == 0 && h_errno == TRY_AGAIN && --retry >= 0); - + // if(entry == 0) // { // DNSException ex(__FILE__, __LINE__); @@ -1289,7 +1415,7 @@ IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol // memcpy(&addr.sin_addr, *p, entry->h_length); // result.push_back(addr); // p++; -// } +// } // #else @@ -1318,7 +1444,7 @@ IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol { hints.ai_flags = AI_NUMERICHOST; } - + int rs = 0; do { @@ -1435,7 +1561,7 @@ IceInternal::compareAddress(const struct sockaddr_storage& addr1, const struct s { return 1; } - + int res = memcmp(&addr1in->sin6_addr, &addr2in->sin6_addr, sizeof(struct in6_addr)); if(res < 0) { @@ -1457,7 +1583,7 @@ IceInternal::createPipe(SOCKET fds[2]) SOCKET fd = createSocket(false, AF_INET); setBlock(fd, true); - + struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr)); @@ -1465,7 +1591,7 @@ IceInternal::createPipe(SOCKET fds[2]) addrin->sin_family = AF_INET; addrin->sin_port = htons(0); addrin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - + doBind(fd, addr); doListen(fd, 1); @@ -1694,10 +1820,10 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto for(vector<struct sockaddr_storage>::const_iterator p = addrs.begin(); p != addrs.end(); ++p) { // - // NOTE: We don't publish link-local IPv6 addresses as these addresses can only + // NOTE: We don't publish link-local IPv6 addresses as these addresses can only // be accessed in general with a scope-id. // - if(p->ss_family != AF_INET6 || + if(p->ss_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&reinterpret_cast<const struct sockaddr_in6*>(&(*p))->sin6_addr)) { hosts.push_back(inetAddrToString(*p)); diff --git a/cpp/src/Ice/PluginManagerI.cpp b/cpp/src/Ice/PluginManagerI.cpp index 4a850896e5b..ec7bae151d0 100644 --- a/cpp/src/Ice/PluginManagerI.cpp +++ b/cpp/src/Ice/PluginManagerI.cpp @@ -161,56 +161,39 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) PropertiesPtr properties = _communicator->getProperties(); PropertyDict plugins = properties->getPropertiesForPrefix(prefix); - string loadOrder = properties->getProperty("Ice.PluginLoadOrder"); - string::size_type beg = 0; - if(!loadOrder.empty()) + StringSeq loadOrder = properties->getPropertyAsList("Ice.PluginLoadOrder"); + for(StringSeq::const_iterator p = loadOrder.begin(); p != loadOrder.end(); ++p) { - const string delim = ", \t\n"; - beg = loadOrder.find_first_not_of(delim, beg); - while(beg != string::npos) - { - string name; - string::size_type end = loadOrder.find_first_of(delim, beg); - if(end == string::npos) - { - name = loadOrder.substr(beg); - beg = end; - } - else - { - name = loadOrder.substr(beg, end - beg); - beg = loadOrder.find_first_not_of(delim, end); - } + string name = *p; - map<string, PluginPtr>::iterator p = _plugins.find(name); - if(p != _plugins.end()) - { - PluginInitializationException ex(__FILE__, __LINE__); - ex.reason = "plugin `" + name + "' already loaded"; - throw ex; - } + map<string, PluginPtr>::iterator p = _plugins.find(name); + if(p != _plugins.end()) + { + PluginInitializationException ex(__FILE__, __LINE__); + ex.reason = "plugin `" + name + "' already loaded"; + throw ex; + } - PropertyDict::iterator q = plugins.find("Ice.Plugin." + name + ".cpp"); - if(q == plugins.end()) - { - q = plugins.find("Ice.Plugin." + name); - } - else - { - plugins.erase("Ice.Plugin." + name); - } + PropertyDict::iterator q = plugins.find("Ice.Plugin." + name + ".cpp"); + if(q == plugins.end()) + { + q = plugins.find("Ice.Plugin." + name); + } + else + { + plugins.erase("Ice.Plugin." + name); + } - if(q != plugins.end()) - { - loadPlugin(name, q->second, cmdArgs); - plugins.erase(q); - } - else - { - PluginInitializationException ex(__FILE__, __LINE__); - ex.reason = "plugin `" + name + "' not defined"; - throw ex; - } + if(q != plugins.end()) + { + loadPlugin(name, q->second, cmdArgs); + plugins.erase(q); + } + else + { + PluginInitializationException ex(__FILE__, __LINE__); + ex.reason = "plugin `" + name + "' not defined"; + throw ex; } } diff --git a/cpp/src/Ice/PropertiesI.cpp b/cpp/src/Ice/PropertiesI.cpp index 94a8f0cf276..bf8840badbe 100644 --- a/cpp/src/Ice/PropertiesI.cpp +++ b/cpp/src/Ice/PropertiesI.cpp @@ -101,7 +101,7 @@ Ice::PropertiesI::getPropertyAsListWithDefault(const string& key, const StringSe p->second.used = true; StringSeq result; - if(!IceUtilInternal::splitString(p->second.value, " \t\n", result)) + if(!IceUtilInternal::splitString(p->second.value, ", \t\n", result)) { Warning out(getProcessLogger()); out << "mismatched quotes in property " << key << "'s value, returning default value"; @@ -406,49 +406,56 @@ Ice::PropertiesI::PropertiesI(StringSeq& args, const PropertiesPtr& defaults, co void Ice::PropertiesI::parseLine(const string& line, const StringConverterPtr& converter) { - const string delim = " \t\r\n"; string s = line; - string::size_type idx = s.find('#'); - if(idx != string::npos) - { - s.erase(idx); - } - - idx = s.find_last_not_of(delim); - if(idx != string::npos && idx + 1 < s.length()) - { - s.erase(idx + 1); - } - - string::size_type beg = s.find_first_not_of(delim); - if(beg == string::npos) + // + // Remove comments and unescape #'s + // + string::size_type idx = 0; + while((idx = s.find("#", idx)) != string::npos) { - return; + if(idx != 0 && s[idx - 1] == '\\') + { + s.erase(idx - 1, 1); + ++idx; + } + else + { + s.erase(idx); + break; + } } - - string::size_type end = s.find_first_of(delim + "=", beg); - if(end == string::npos) + + // + // Split key/value and unescape ='s + // + string::size_type split = string::npos; + idx = 0; + while((idx = s.find("=", idx)) != string::npos) { - return; + if(idx != 0 && s[idx - 1] == '\\') + { + s.erase(idx - 1, 1); + } + else if(split == string::npos) + { + split = idx; + } + ++idx; } - - string key = s.substr(beg, end - beg); - - end = s.find('=', end); - if(end == string::npos) + + if(split == 0 || split == string::npos) { + s = IceUtilInternal::trim(s); + if(s.length() != 0) + { + getProcessLogger()->warning("invalid config file entry: \"" + line + "\""); + } return; } - ++end; - string value; - beg = s.find_first_not_of(delim, end); - if(beg != string::npos) - { - end = s.length(); - value = s.substr(beg, end - beg); - } + string key = IceUtilInternal::trim(s.substr(0, split)); + string value = IceUtilInternal::trim(s.substr(split + 1, s.length() - split - 1)); if(converter) { @@ -479,29 +486,14 @@ Ice::PropertiesI::loadConfig() if(s && *s != '\0') { value = s; + setProperty("Ice.Config", value); } } - if(!value.empty()) + StringSeq files = getPropertyAsList("Ice.Config"); + for(StringSeq::const_iterator p = files.begin(); p != files.end(); ++p) { - const string delim = " \t\r\n"; - string::size_type beg = value.find_first_not_of(delim); - while(beg != string::npos) - { - string::size_type end = value.find(",", beg); - string file; - if(end == string::npos) - { - file = value.substr(beg); - beg = end; - } - else - { - file = value.substr(beg, end - beg); - beg = value.find_first_not_of("," + delim, end); - } - load(file); - } + load(*p); } PropertyValue pv(value, true); diff --git a/cpp/src/Ice/ProxyFactory.cpp b/cpp/src/Ice/ProxyFactory.cpp index f55a159bb6c..bd378d74896 100644 --- a/cpp/src/Ice/ProxyFactory.cpp +++ b/cpp/src/Ice/ProxyFactory.cpp @@ -223,53 +223,33 @@ IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, co IceInternal::ProxyFactory::ProxyFactory(const InstancePtr& instance) : _instance(instance) { - string str = _instance->initializationData().properties->getPropertyWithDefault("Ice.RetryIntervals", "0"); - - string::size_type beg; - string::size_type end = 0; - - while(true) + StringSeq retryValues = _instance->initializationData().properties->getPropertyAsList("Ice.RetryIntervals"); + if(retryValues.size() == 0) { - const string delim = " \t"; - - beg = str.find_first_not_of(delim, end); - if(beg == string::npos) + _retryIntervals.push_back(0); + } + else + { + for(StringSeq::const_iterator p = retryValues.begin(); p != retryValues.end(); ++p) { - if(_retryIntervals.empty()) + istringstream value(*p); + + int v; + if(!(value >> v) || !value.eof()) { - _retryIntervals.push_back(0); + v = 0; } - break; - } - - end = str.find_first_of(delim, beg); - if(end == string::npos) - { - end = str.length(); - } - - if(beg == end) - { - break; - } - - istringstream value(str.substr(beg, end - beg)); - int v; - if(!(value >> v) || !value.eof()) - { - v = 0; - } + // + // If -1 is the first value, no retry and wait intervals. + // + if(v == -1 && _retryIntervals.empty()) + { + break; + } - // - // If -1 is the first value, no retry and wait intervals. - // - if(v == -1 && _retryIntervals.empty()) - { - break; + _retryIntervals.push_back(v > 0 ? v : 0); } - - _retryIntervals.push_back(v > 0 ? v : 0); } } diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp index c59122ccdad..c4b60bce3e8 100755 --- a/cpp/src/Ice/Reference.cpp +++ b/cpp/src/Ice/Reference.cpp @@ -477,7 +477,7 @@ IceInternal::Reference::hashInit() const h = 5 * h + *p; } - _hashValue = 5 * _hashValue + static_cast<Int>(_secure); + h = 5 * h + static_cast<Int>(_secure); _hashValue = h; _hashInitialized = true; diff --git a/cpp/src/Ice/UdpEndpointI.cpp b/cpp/src/Ice/UdpEndpointI.cpp index e6664fe9d8e..e535a6c23af 100644 --- a/cpp/src/Ice/UdpEndpointI.cpp +++ b/cpp/src/Ice/UdpEndpointI.cpp @@ -82,10 +82,27 @@ IceInternal::UdpEndpointI::UdpEndpointI(const InstancePtr& instance, const strin if(argumentBeg != string::npos && str[argumentBeg] != '-') { beg = argumentBeg; - end = str.find_first_of(delim, beg); - if(end == string::npos) + if(str[beg] == '\"') { - end = str.length(); + end = str.find_first_of('\"', beg + 1); + if(end == string::npos) + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "udp " + str; + throw ex; + } + else + { + ++end; + } + } + else + { + end = str.find_first_of(delim, beg); + if(end == string::npos) + { + end = str.length(); + } } argument = str.substr(beg, end - beg); if(argument[0] == '\"' && argument[argument.size() - 1] == '\"') diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp index 4d2b904c185..146aebc0af3 100644 --- a/cpp/src/Ice/UdpTransceiver.cpp +++ b/cpp/src/Ice/UdpTransceiver.cpp @@ -7,6 +7,14 @@ // // ********************************************************************** +// +// The following is required for the Vista PSDK to bring in +// the definitions of the IN6_IS_ADDR_* macros. +// +#if defined(_WIN32) && !defined(_WIN32_WINNT) +# define _WIN32_WINNT 0x0501 +#endif + #include <Ice/UdpTransceiver.h> #include <Ice/Instance.h> #include <Ice/TraceLevels.h> @@ -131,7 +139,7 @@ repeat: ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&buf.b[0]), static_cast<int>(buf.b.size()), 0); #else ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&buf.b[0]), buf.b.size(), 0); -#endif +#endif if(ret == SOCKET_ERROR) { @@ -153,7 +161,7 @@ repeat: assert(_fd != INVALID_SOCKET); #ifdef _WIN32 FD_SET(_fd, &_wFdSet); - + if(timeout >= 0) { struct timeval tv; @@ -170,14 +178,14 @@ repeat: pollFd[0].fd = _fd; pollFd[0].events = POLLOUT; rs = ::poll(pollFd, 1, timeout); -#endif +#endif if(rs == SOCKET_ERROR) { if(interrupted()) { goto repeatSelect; } - + SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; @@ -187,10 +195,10 @@ repeat: { throw new Ice::TimeoutException(__FILE__, __LINE__); } - + goto repeat; } - + SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; @@ -201,7 +209,7 @@ repeat: Trace out(_logger, _traceLevels->networkCat); out << "sent " << ret << " bytes via udp\n" << toString(); } - + if(_stats) { _stats->bytesSent(type(), static_cast<Int>(ret)); @@ -289,7 +297,7 @@ repeat: { goto repeat; } - + if(wouldBlock()) { if(timeout == 0) @@ -298,7 +306,7 @@ repeat: } repeatSelect: - + assert(_fd != INVALID_SOCKET); #ifdef _WIN32 FD_SET(_fd, &_rFdSet); @@ -316,12 +324,12 @@ repeat: { goto repeatSelect; } - + SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; } - + if(rs == 0) { throw TimeoutException(__FILE__, __LINE__); @@ -346,7 +354,7 @@ repeat: ex.error = getSocketErrno(); throw ex; } - + if(_traceLevels->network >= 3) { Trace out(_logger, _traceLevels->networkCat); @@ -454,7 +462,7 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s setMcastTtl(_fd, mcastTtl, _addr.ss_family == AF_INET); } } - + if(_traceLevels->network >= 1) { Trace out(_logger, _traceLevels->networkCat); @@ -473,7 +481,7 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s #endif } -IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const string& host, int port, +IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const string& host, int port, const string& mcastInterface, bool connect) : _traceLevels(instance->traceLevels()), _logger(instance->initializationData().logger), @@ -545,7 +553,7 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s #endif doBind(_fd, _addr); } - + if(_traceLevels->network >= 1) { Trace out(_logger, _traceLevels->networkCat); @@ -567,7 +575,7 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s IceInternal::UdpTransceiver::~UdpTransceiver() { assert(_fd == INVALID_SOCKET); -} +} // // Set UDP receive and send buffer sizes. diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp index fecb1285761..759a9c58072 100644 --- a/cpp/src/IceBox/ServiceManagerI.cpp +++ b/cpp/src/IceBox/ServiceManagerI.cpp @@ -357,30 +357,6 @@ IceBox::ServiceManagerI::start() } // - // Parse the IceBox.LoadOrder property. - // - string order = properties->getProperty("IceBox.LoadOrder"); - StringSeq loadOrder; - if(!order.empty()) - { - string::size_type beg = order.find_first_not_of(",\t "); - while(beg != string::npos) - { - string::size_type end = order.find_first_of(",\t ", beg); - if(end == string::npos) - { - loadOrder.push_back(order.substr(beg)); - beg = end; - } - else - { - loadOrder.push_back(order.substr(beg, end - beg)); - beg = order.find_first_not_of(",\t ", end); - } - } - } - - // // Load and start the services defined in the property set // with the prefix "IceBox.Service.". These properties should // have the following format: @@ -393,6 +369,7 @@ IceBox::ServiceManagerI::start() const string prefix = "IceBox.Service."; PropertyDict services = properties->getPropertiesForPrefix(prefix); PropertyDict::iterator p; + StringSeq loadOrder = properties->getPropertyAsList("IceBox.LoadOrder"); for(StringSeq::const_iterator q = loadOrder.begin(); q != loadOrder.end(); ++q) { p = services.find(prefix + *q); diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp index 397cdc31c55..230847c56f9 100644 --- a/cpp/src/IceGrid/Activator.cpp +++ b/cpp/src/IceGrid/Activator.cpp @@ -359,9 +359,9 @@ Activator::activate(const string& name, if(_traceLevels->activator > 0) { Trace out(_traceLevels->logger, _traceLevels->activatorCat); - out << "cannot convert `" << path << "' into an absolute path"; + out << "couldn't find `" << path << "' executable."; } - throw string("The server executable path `" + path + "' can't be converted into an absolute path."); + throw string("Couldn't find `" + path + "' executable."); } path = absbuf; } diff --git a/cpp/src/IceGrid/Client.cpp b/cpp/src/IceGrid/Client.cpp index 3bbc3d03c19..3a20680cdd3 100644 --- a/cpp/src/IceGrid/Client.cpp +++ b/cpp/src/IceGrid/Client.cpp @@ -11,6 +11,7 @@ #include <IceUtil/Options.h> #include <IceUtil/CtrlCHandler.h> #include <IceUtil/Thread.h> +#include <IceUtil/StringUtil.h> #include <Ice/Ice.h> #include <Ice/SliceChecksums.h> #include <IceGrid/Parser.h> @@ -99,7 +100,6 @@ public: Ice::CommunicatorPtr communicator() const { return _communicator; } const char* appName() const { return _appName; } - string trim(const string&); string getPassword(const string&); private: @@ -380,7 +380,7 @@ Client::run(int argc, char* argv[]) { cout << "user id: " << flush; getline(cin, id); - id = trim(id); + id = IceUtilInternal::trim(id); } if(password.empty()) @@ -486,7 +486,7 @@ Client::run(int argc, char* argv[]) { cout << "user id: " << flush; getline(cin, id); - id = trim(id); + id = IceUtilInternal::trim(id); } if(password.empty()) @@ -615,18 +615,6 @@ Client::run(int argc, char* argv[]) } string -Client::trim(const string& s) -{ - static const string delims = "\t\r\n "; - string::size_type last = s.find_last_not_of(delims); - if(last != string::npos) - { - return s.substr(s.find_first_not_of(delims), last+1); - } - return s; -} - -string Client::getPassword(const string& prompt) { cout << prompt << flush; @@ -648,5 +636,5 @@ Client::getPassword(const string& prompt) } #endif cout << endl; - return trim(password); + return IceUtilInternal::trim(password); } diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp index 575c4120c89..9f997d2b577 100644 --- a/cpp/src/IceGrid/IceGridNode.cpp +++ b/cpp/src/IceGrid/IceGridNode.cpp @@ -9,6 +9,7 @@ #include <IceUtil/UUID.h> #include <IceUtil/Timer.h> +#include <IceUtil/StringUtil.h> #include <Ice/Ice.h> #include <Ice/Locator.h> #include <Ice/Service.h> @@ -83,7 +84,6 @@ protected: private: void usage(const std::string&); - string trim(const string&); ActivatorPtr _activator; IceUtil::TimerPtr _timer; @@ -583,14 +583,14 @@ NodeService::start(int argc, char* argv[]) { cout << "user id: " << flush; getline(cin, id); - id = trim(id); + id = IceUtilInternal::trim(id); } if(password.empty()) { cout << "password: " << flush; getline(cin, password); - password = trim(password); + password = IceUtilInternal::trim(password); } session = registry->createAdminSession(id, password); @@ -812,18 +812,6 @@ NodeService::usage(const string& appName) print("Usage: " + appName + " [options]\n" + options); } -string -NodeService::trim(const string& s) -{ - static const string delims = "\t\r\n "; - string::size_type last = s.find_last_not_of(delims); - if(last != string::npos) - { - return s.substr(s.find_first_not_of(delims), last+1); - } - return s; -} - int main(int argc, char* argv[]) { diff --git a/cpp/src/IceGrid/NodeI.cpp b/cpp/src/IceGrid/NodeI.cpp index 1d3629245c9..899511f95a9 100644 --- a/cpp/src/IceGrid/NodeI.cpp +++ b/cpp/src/IceGrid/NodeI.cpp @@ -228,65 +228,45 @@ NodeI::NodeI(const Ice::ObjectAdapterPtr& adapter, // // Parse the properties override property. // - string overrides = props->getProperty("IceGrid.Node.PropertiesOverride"); - Ice::StringSeq propsAsArgs; - if(!overrides.empty()) + Ice::StringSeq overrides = props->getPropertyAsList("IceGrid.Node.PropertiesOverride"); + for(Ice::StringSeq::const_iterator p = overrides.begin(); p != overrides.end(); ++p) { - string::size_type end = 0; - while(end != string::npos) - { - const string delim = " \t\r\n"; - - string::size_type beg = overrides.find_first_not_of(delim, end); - if(beg == string::npos) - { - break; - } - - end = overrides.find_first_of(delim, beg); - string arg; - if(end == string::npos) - { - arg = overrides.substr(beg); - } - else - { - arg = overrides.substr(beg, end - beg); - } + string arg = *p; - if(arg.find("--") == 0) - { - arg = arg.substr(2); - } + const string delim = " \t\r\n"; - // - // Extract the key/value - // - string::size_type argEnd = arg.find_first_of(delim + "="); - if(argEnd == string::npos) - { - continue; - } - - string key = arg.substr(0, argEnd); - - argEnd = arg.find('=', argEnd); - if(argEnd == string::npos) - { - return; - } - ++argEnd; - - string value; - string::size_type argBeg = arg.find_first_not_of(delim, argEnd); - if(argBeg != string::npos) - { - argEnd = arg.length(); - value = arg.substr(argBeg, argEnd - argBeg); - } + if(arg.find("--") == 0) + { + arg = arg.substr(2); + } - _propertiesOverride.push_back(createProperty(key, value)); + // + // Extract the key/value + // + string::size_type argEnd = arg.find_first_of(delim + "="); + if(argEnd == string::npos) + { + continue; + } + + string key = arg.substr(0, argEnd); + + argEnd = arg.find('=', argEnd); + if(argEnd == string::npos) + { + return; } + ++argEnd; + + string value; + string::size_type argBeg = arg.find_first_not_of(delim, argEnd); + if(argBeg != string::npos) + { + argEnd = arg.length(); + value = arg.substr(argBeg, argEnd - argBeg); + } + + _propertiesOverride.push_back(createProperty(key, value)); } } diff --git a/cpp/src/IceGrid/Parser.cpp b/cpp/src/IceGrid/Parser.cpp index c36bfd4eeb2..9ab3f547738 100644 --- a/cpp/src/IceGrid/Parser.cpp +++ b/cpp/src/IceGrid/Parser.cpp @@ -2017,8 +2017,8 @@ Parser::getInput(char* buf, int& result, int maxSize) } else { -#if defined(_MSC_VER) && !defined(_STLP_MSVC) - // COMPILERBUG: Stupid Visual C++ defines min and max as macros +#if defined(_MSC_VER) && _MSC_VER < 1500 && !defined(_STLP_MSVC) + // COMPILERBUG: Visual C++ defines min and max as macros result = _MIN(maxSize, static_cast<int>(_commands.length())); #else result = min(maxSize, static_cast<int>(_commands.length())); diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp index 50ae4a9f516..b0109240528 100644 --- a/cpp/src/IceSSL/Instance.cpp +++ b/cpp/src/IceSSL/Instance.cpp @@ -146,7 +146,7 @@ IceSSL::Instance::initialize() // Select protocols. // { - string protocols = properties->getProperty(propPrefix + "Protocols"); + StringSeq protocols = properties->getPropertyAsList(propPrefix + "Protocols"); if(!protocols.empty()) { parseProtocols(protocols); @@ -841,30 +841,12 @@ IceSSL::Instance::traceConnection(SSL* ssl, bool incoming) } void -IceSSL::Instance::parseProtocols(const string& val) +IceSSL::Instance::parseProtocols(const StringSeq& protocols) { - const string delim = ", "; bool sslv3 = false, tlsv1 = false; - string::size_type pos = 0; - while(pos != string::npos) + for(Ice::StringSeq::const_iterator p = protocols.begin(); p != protocols.end(); ++p) { - pos = val.find_first_not_of(delim, pos); - if(pos == string::npos) - { - break; - } - - string prot; - string::size_type end = val.find_first_of(delim, pos); - if(end == string::npos) - { - prot = val.substr(pos); - } - else - { - prot = val.substr(pos, end - pos); - } - pos = end; + string prot = *p; if(prot == "ssl3" || prot == "sslv3") { diff --git a/cpp/src/IceSSL/Instance.h b/cpp/src/IceSSL/Instance.h index 39a81808013..4cf354760f2 100644 --- a/cpp/src/IceSSL/Instance.h +++ b/cpp/src/IceSSL/Instance.h @@ -18,6 +18,7 @@ #include <Ice/ProtocolPluginFacadeF.h> #include <IceSSL/Plugin.h> #include <IceSSL/TrustManagerF.h> +#include <Ice/BuiltinSequences.h> namespace IceSSL { @@ -62,7 +63,7 @@ public: private: - void parseProtocols(const std::string&); + void parseProtocols(const Ice::StringSeq&); Ice::LoggerPtr _logger; IceInternal::ProtocolPluginFacadePtr _facade; diff --git a/cpp/src/IceStorm/Parser.cpp b/cpp/src/IceStorm/Parser.cpp index facd21440cf..58c8d6c0976 100644 --- a/cpp/src/IceStorm/Parser.cpp +++ b/cpp/src/IceStorm/Parser.cpp @@ -305,8 +305,8 @@ Parser::getInput(char* buf, int& result, int maxSize) } else { -#if defined(_MSC_VER) && !defined(_STLP_MSVC) - // COMPILERBUG: Stupid Visual C++ defines min and max as macros +#if defined(_MSC_VER) && _MSC_VER < 1500 && !defined(_STLP_MSVC) + // COMPILERBUG: Visual C++ defines min and max as macros result = _MIN(maxSize, static_cast<int>(_commands.length())); #else result = min(maxSize, static_cast<int>(_commands.length())); diff --git a/cpp/src/IceUtil/StringUtil.cpp b/cpp/src/IceUtil/StringUtil.cpp index 62bd9e1f44d..e087e5586dc 100644 --- a/cpp/src/IceUtil/StringUtil.cpp +++ b/cpp/src/IceUtil/StringUtil.cpp @@ -364,6 +364,23 @@ IceUtilInternal::splitString(const string& str, const string& delim, vector<stri return true; } +// +// Trim white space (" \t\r\n") +// +string +IceUtilInternal::trim(const string& s) +{ + static const string delim = " \t\r\n"; + string::size_type beg = s.find_first_not_of(delim); + if(beg == string::npos) + { + return ""; + } + else + { + return s.substr(beg, s.find_last_not_of(delim) - beg + 1); + } +} // // If a single or double quotation mark is found at the start position, diff --git a/cpp/src/Slice/DotNetNames.cpp b/cpp/src/Slice/DotNetNames.cpp index 0d672548d7a..689949a0234 100755 --- a/cpp/src/Slice/DotNetNames.cpp +++ b/cpp/src/Slice/DotNetNames.cpp @@ -65,25 +65,12 @@ static const Node ExceptionNode = ExceptionNames, &ExceptionParents[0] }; -static const char* ApplicationExceptionNames[] = - { - 0 - }; -static const Node* ApplicationExceptionParents[] = - { - &ExceptionNode, 0 - }; -static const Node ApplicationExceptionNode = - { - ApplicationExceptionNames, &ApplicationExceptionParents[0] - }; - // // Must be kept in same order as definition of BaseType in header file! // static const Node* nodes[] = { - &ObjectNode, &ICloneableNode, &ExceptionNode, &ApplicationExceptionNode + &ObjectNode, &ICloneableNode, &ExceptionNode }; static bool diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 98c6582635d..2557a048c1b 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -922,10 +922,18 @@ Slice::Container::createDictionary(const string& name, const TypePtr& keyType, c checkForGlobalDef(name, "dictionary"); // Don't return here -- we create the dictionary anyway. } - if(nt == Real && !Dictionary::legalKeyType(keyType)) + if(nt == Real) { - _unit->error("dictionary `" + name + "' uses an illegal key type"); - return 0; + bool containsSequence = false; + if(!Dictionary::legalKeyType(keyType, containsSequence)) + { + _unit->error("dictionary `" + name + "' uses an illegal key type"); + return 0; + } + if(containsSequence) + { + _unit->warning("use of sequences in dictionary keys has been deprecated"); + } } if(!local) @@ -3894,8 +3902,11 @@ Slice::Dictionary::recDependencies(set<ConstructedPtr>& dependencies) // integral types, string, and sequences and structs containing only // other legal key types. // +// Note: Allowing sequences in dictionary keys has been deprecated as +// of Ice 3.3.0. +// bool -Slice::Dictionary::legalKeyType(const TypePtr& type) +Slice::Dictionary::legalKeyType(const TypePtr& type, bool& containsSequence) { BuiltinPtr bp = BuiltinPtr::dynamicCast(type); if(bp) @@ -3932,9 +3943,13 @@ Slice::Dictionary::legalKeyType(const TypePtr& type) } SequencePtr seqp = SequencePtr::dynamicCast(type); - if(seqp && legalKeyType(seqp->type())) + if(seqp) { - return true; + containsSequence = true; + if(legalKeyType(seqp->type(), containsSequence)) + { + return true; + } } StructPtr strp = StructPtr::dynamicCast(type); @@ -3943,7 +3958,7 @@ Slice::Dictionary::legalKeyType(const TypePtr& type) DataMemberList dml = strp->dataMembers(); for(DataMemberList::const_iterator mem = dml.begin(); mem != dml.end(); ++mem) { - if(!legalKeyType((*mem)->type())) + if(!legalKeyType((*mem)->type(), containsSequence)) { return false; } diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp index 7b3acd99500..869dc5ca760 100755 --- a/cpp/src/Slice/Preprocessor.cpp +++ b/cpp/src/Slice/Preprocessor.cpp @@ -284,14 +284,7 @@ Slice::Preprocessor::printMakefileDependencies(Language lang, const vector<strin while((end = unprocessed.find(".ice", pos)) != string::npos) { end += 4; - string file = unprocessed.substr(pos, end - pos); - - // - // Strip white space from the file name. - // - size_t b = file.find_first_not_of(" \t"); - size_t e = file.find_last_not_of(" \t"); - file = file.substr(b, e - b + 1); + string file = IceUtilInternal::trim(unprocessed.substr(pos, end - pos)); // // Normalize paths if not relative path. diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp index 75ed5d400b8..517fabbbdf5 100644 --- a/cpp/src/Slice/PythonUtil.cpp +++ b/cpp/src/Slice/PythonUtil.cpp @@ -526,6 +526,15 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) _out.inc(); _out << nl << "return '" << scoped << "'"; _out.dec(); + + // + // ice_staticId + // + _out << sp << nl << "def ice_staticId():"; + _out.inc(); + _out << nl << "return '" << scoped << "'"; + _out.dec(); + _out << nl << "ice_staticId = staticmethod(ice_staticId)"; } if(!ops.empty()) diff --git a/cpp/src/Slice/RubyUtil.cpp b/cpp/src/Slice/RubyUtil.cpp index 3322899a24e..2f861a8e283 100644 --- a/cpp/src/Slice/RubyUtil.cpp +++ b/cpp/src/Slice/RubyUtil.cpp @@ -407,6 +407,12 @@ Slice::Ruby::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) _out << nl << "class " << name; _out.inc(); _out << nl << "include " << name << "_mixin"; + _out << nl; + _out << nl << "def " << name << ".ice_staticId()"; + _out.inc(); + _out << nl << "'" << scoped << "'"; + _out.dec(); + _out << nl << "end"; _out.dec(); _out << nl << "end"; } @@ -422,6 +428,12 @@ Slice::Ruby::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) } _out.inc(); _out << nl << "include " << name << "_mixin"; + _out << nl; + _out << nl << "def " << name << ".ice_staticId()"; + _out.inc(); + _out << nl << "'" << scoped << "'"; + _out.dec(); + _out << nl << "end"; // // initialize diff --git a/cpp/src/iceserviceinstall/Install.cpp b/cpp/src/iceserviceinstall/Install.cpp index d9f0a476bde..124961b9e83 100755 --- a/cpp/src/iceserviceinstall/Install.cpp +++ b/cpp/src/iceserviceinstall/Install.cpp @@ -186,17 +186,17 @@ Install::usage() const "Valid properties:\n" "ImagePath Full path to <service>.exe. The default value is\n" " <directory of " << appName() << ">\\<service>.exe\n" - "DisplayName Display name for the service\n" - "Description Description for the service\n" - "AutoStart When non 0, the service is started automatically when\n" - " the computer starts up. The default value is 1\n" + "DisplayName Display name of the service.\n" + "Description Description of the service.\n" + "AutoStart If non-zero, the service is started automatically when\n" + " the computer starts up. The default value is 1.\n" "ObjectName Account used to run the service. Defaults to\n" - " NT Authority\\LocalService\n" - "Password Password for ObjectName\n" - "DependOnRegistry When non 0, the service depends on the IceGrid registry\n" + " NT Authority\\LocalService.\n" + "Password Password for ObjectName.\n" + "DependOnRegistry If non-zero, the service depends on the IceGrid registry\n" " service (the IceGrid registry service name is computed\n" " using Ice.Default.Locator in <config-file>).\n" "EventLog The name of the EventLog used by this service;\n" - " the default is Application\n" + " the default is Application.\n" ; } diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 921ecd031f0..42a39edd084 100755 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -4881,6 +4881,25 @@ Slice::Gen::ImplVisitor::visitModuleStart(const ModulePtr& p) _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + set<string> includes; + ClassList classes = p->classes(); + for(ClassList::const_iterator q = classes.begin(); q != classes.end(); ++q) + { + ClassList bases = (*q)->bases(); + for(ClassList::const_iterator r = bases.begin(); r != bases.end(); ++r) + { + if((*r)->isAbstract()) + { + includes.insert((*r)->name()); + } + } + } + + for(set<string>::const_iterator it = includes.begin(); it != includes.end(); ++it) + { + H << nl << "#include <" << *it << "I.h>"; + } + string name = fixKwd(p->name()); H << sp << nl << "namespace " << name << nl << '{'; @@ -4911,13 +4930,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) string scope = fixKwd(p->scope()); string cls = scope.substr(2) + name + "I"; string classScopedAMD = scope + "AMD_" + name; - ClassList bases = p->bases(); - ClassDefPtr base; - if(!bases.empty() && !bases.front()->isInterface()) - { - base = bases.front(); - } H << sp; H << nl << "class " << name << "I : "; diff --git a/cpp/src/slice2cppe/Gen.cpp b/cpp/src/slice2cppe/Gen.cpp index 920da32a79d..9ecaf80640a 100644 --- a/cpp/src/slice2cppe/Gen.cpp +++ b/cpp/src/slice2cppe/Gen.cpp @@ -2626,6 +2626,25 @@ Slice::Gen::ImplVisitor::visitModuleStart(const ModulePtr& p) _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + set<string> includes; + ClassList classes = p->classes(); + for(ClassList::const_iterator q = classes.begin(); q != classes.end(); ++q) + { + ClassList bases = (*q)->bases(); + for(ClassList::const_iterator r = bases.begin(); r != bases.end(); ++r) + { + if((*r)->isAbstract()) + { + includes.insert((*r)->name()); + } + } + } + + for(set<string>::const_iterator it = includes.begin(); it != includes.end(); ++it) + { + H << nl << "#include <" << *it << "I.h>"; + } + string name = fixKwd(p->name()); H << sp << nl << "namespace " << name << nl << '{'; diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp index 8d38d699204..aa41bd24aa2 100755 --- a/cpp/src/slice2cs/Gen.cpp +++ b/cpp/src/slice2cs/Gen.cpp @@ -1855,7 +1855,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sb; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - string name = fixId((*q)->name(), DotNet::ApplicationException, false); + string name = fixId((*q)->name(), DotNet::Exception, false); _out << nl << "this." << name << " = " << fixId((*q)->name()) << ';'; } _out << eb; @@ -1902,22 +1902,15 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sp << nl << "public override int GetHashCode()"; _out << sb; - _out << nl << "int h__ = 0;"; - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + if(p->base()) { - string memberName = fixId((*q)->name(), DotNet::ApplicationException); - bool isValue = isValueType((*q)->type()); - if(!isValue) - { - _out << nl << "if((object)" << memberName << " != null)"; - _out << sb; - } - _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; - if(!isValue) - { - _out << eb; - } + _out << nl << "int h__ = base.GetHashCode();"; } + else + { + _out << nl << "int h__ = 0;"; + } + writeMemberHashCode(dataMembers, DotNet::Exception); _out << nl << "return h__;"; _out << eb; @@ -1935,31 +1928,18 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sb; _out << nl << "return false;"; _out << eb; - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + if(p->base()) { - string memberName = fixId((*q)->name(), DotNet::ApplicationException); - bool isValue = isValueType((*q)->type()); - if(!isValue) - { - _out << nl << "if(" << memberName << " == null)"; - _out << sb; - _out << nl << "if(((" << name << ")other__)." << memberName << " != null)"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - _out << eb; - _out << nl << "else"; - _out << sb; - } - _out << nl << "if(!" << memberName << ".Equals(((" << name << ")other__)." << memberName << "))"; + _out << nl << "if(!base.Equals(other__))"; _out << sb; _out << nl << "return false;"; _out << eb; - if(!isValue) - { - _out << eb; - } } + if(!dataMembers.empty()) + { + _out << nl << name << " o__ = (" << name << ")other__;"; + } + writeMemberEquals(dataMembers, DotNet::Exception); _out << nl << "return true;"; _out << eb; @@ -1993,7 +1973,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << nl << "os__.startWriteSlice();"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, DotNet::ApplicationException), + writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, DotNet::Exception), true, false, false); } _out << nl << "os__.endWriteSlice();"; @@ -2045,7 +2025,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << nl << "case " << memberCount << ":"; _out.inc(); } - string memberName = fixId((*q)->name(), DotNet::ApplicationException); + string memberName = fixId((*q)->name(), DotNet::Exception); string memberType = typeToString((*q)->type()); _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; ContainedPtr contained = ContainedPtr::dynamicCast((*q)->type()); @@ -2098,7 +2078,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) patchParams << ", " << classMemberCount++; } } - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::ApplicationException), + writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), false, false, false, patchParams.str()); } _out << nl << "is__.endReadSlice();"; @@ -2116,7 +2096,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << nl << "outS__.startSlice();"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::ApplicationException), + writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), true, true, false); } _out << nl << "outS__.endSlice();"; @@ -2146,7 +2126,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) patchParams << ", " << classMemberCount++; } } - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::ApplicationException), + writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), false, true, false, patchParams.str()); } _out << nl << "inS__.endSlice();"; @@ -2301,21 +2281,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) _out << sp << nl << "public override int GetHashCode()"; _out << sb; _out << nl << "int h__ = 0;"; - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) - { - string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0); - bool isValue = isValueType((*q)->type()); - if(!isValue) - { - _out << nl << "if(" << memberName << " != null)"; - _out << sb; - } - _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; - if(!isValue) - { - _out << eb; - } - } + writeMemberHashCode(dataMembers, isClass ? DotNet::ICloneable : 0); _out << nl << "return h__;"; _out << eb; @@ -2347,34 +2313,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) { _out << nl << name << " o__ = (" << name << ")other__;"; } - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) - { - string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0); - if(!isValueType((*q)->type())) - { - _out << nl << "if(" << memberName << " == null)"; - _out << sb; - _out << nl << "if(o__." << memberName << " != null)"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - _out << eb; - _out << nl << "else"; - _out << sb; - _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - _out << eb; - } - else - { - _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - } - } + writeMemberEquals(dataMembers, isClass ? DotNet::ICloneable : 0); _out << nl << "return true;"; _out << eb; @@ -2731,7 +2670,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) } else if(ExceptionPtr::dynamicCast(cont)) { - baseTypes = DotNet::ApplicationException; + baseTypes = DotNet::Exception; } else if(ClassDefPtr::dynamicCast(cont)) { @@ -2796,6 +2735,168 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) _out << eb; } +void +Slice::Gen::TypesVisitor::writeMemberHashCode(const DataMemberList& dataMembers, int baseTypes) +{ + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixId((*q)->name(), baseTypes); + TypePtr memberType = (*q)->type(); + bool isValue = isValueType(memberType); + if(!isValue) + { + _out << nl << "if(" << memberName << " != null)"; + _out << sb; + } + SequencePtr seq = SequencePtr::dynamicCast(memberType); + if(seq) + { + string genericType; + bool isGeneric = seq->findMetaData("clr:generic:", genericType); + bool isArray = !isGeneric && !seq->hasMetaData("clr:collection"); + if(isArray) + { + // + // GetHashCode() for native arrays does not have value semantics. + // + _out << nl << "h__ = 5 * h__ + IceUtilInternal.Arrays.GetHashCode(" << memberName << ");"; + } + else if(isGeneric) + { + // + // GetHashCode() for generic types does not have value semantics. + // + _out << nl << "h__ = 5 * h__ + IceUtilInternal.Collections.SequenceGetHashCode(" << memberName << ");"; + } + else + { + // + // GetHashCode() for CollectionBase has value semantics. + // + _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; + } + } + else + { + DictionaryPtr dict = DictionaryPtr::dynamicCast(memberType); + if(dict) + { + if(dict->hasMetaData("clr:collection")) + { + // + // GetHashCode() for DictionaryBase has value semantics. + // + _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; + } + else + { + // + // GetHashCode() for generic types does not have value semantics. + // + _out << nl << "h__ = 5 * h__ + IceUtilInternal.Collections.DictionaryGetHashCode(" << memberName + << ");"; + } + } + else + { + _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; + } + } + if(!isValue) + { + _out << eb; + } + } +} + +void +Slice::Gen::TypesVisitor::writeMemberEquals(const DataMemberList& dataMembers, int baseTypes) +{ + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixId((*q)->name(), baseTypes); + TypePtr memberType = (*q)->type(); + if(!isValueType(memberType)) + { + _out << nl << "if(" << memberName << " == null)"; + _out << sb; + _out << nl << "if(o__." << memberName << " != null)"; + _out << sb; + _out << nl << "return false;"; + _out << eb; + _out << eb; + _out << nl << "else"; + _out << sb; + SequencePtr seq = SequencePtr::dynamicCast(memberType); + if(seq) + { + string genericType; + bool isGeneric = seq->findMetaData("clr:generic:", genericType); + bool isArray = !isGeneric && !seq->hasMetaData("clr:collection"); + if(isArray) + { + // + // Equals() for native arrays does not have value semantics. + // + _out << nl << "if(!IceUtilInternal.Arrays.Equals(" << memberName << ", o__." << memberName << "))"; + } + else if(isGeneric) + { + // + // Equals() for generic types does not have value semantics. + // + _out << nl << "if(!IceUtilInternal.Collections.SequenceEquals(" << memberName << ", o__." + << memberName << "))"; + } + else + { + // + // Equals() for CollectionBase has value semantics. + // + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + } + } + else + { + DictionaryPtr dict = DictionaryPtr::dynamicCast(memberType); + if(dict) + { + if(dict->hasMetaData("clr:collection")) + { + // + // Equals() for DictionaryBase has value semantics. + // + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + } + else + { + // + // Equals() for generic types does not have value semantics. + // + _out << nl << "if(!IceUtilInternal.Collections.DictionaryEquals(" << memberName << ", o__." + << memberName << "))"; + } + } + else + { + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + } + } + _out << sb; + _out << nl << "return false;"; + _out << eb; + _out << eb; + } + else + { + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + _out << sb; + _out << nl << "return false;"; + _out << eb; + } + } +} + Slice::Gen::ProxyVisitor::ProxyVisitor(IceUtilInternal::Output& out) : CsVisitor(out) { diff --git a/cpp/src/slice2cs/Gen.h b/cpp/src/slice2cs/Gen.h index 4962bb438d7..c33257945ae 100644 --- a/cpp/src/slice2cs/Gen.h +++ b/cpp/src/slice2cs/Gen.h @@ -112,6 +112,9 @@ private: private: + void writeMemberHashCode(const DataMemberList&, int); + void writeMemberEquals(const DataMemberList&, int); + bool _stream; }; diff --git a/cpp/src/slice2freeze/Main.cpp b/cpp/src/slice2freeze/Main.cpp index 5136997cc4f..4bf091353ab 100644 --- a/cpp/src/slice2freeze/Main.cpp +++ b/cpp/src/slice2freeze/Main.cpp @@ -1003,11 +1003,16 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c return false; } - if(!Dictionary::legalKeyType(valueType)) + bool containsSequence = false; + if(!Dictionary::legalKeyType(valueType, containsSequence)) { cerr << n << ": `" << dict.value << "' is not a valid index type" << endl; return false; } + if(containsSequence) + { + cerr << n << ": warning: use of sequences in dictionary keys has been deprecated" << endl; + } if(index.caseSensitive == false) @@ -1071,11 +1076,17 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c TypePtr dataMemberType = dataMember->type(); - if(!Dictionary::legalKeyType(dataMemberType)) + bool containsSequence = false; + if(!Dictionary::legalKeyType(dataMemberType, containsSequence)) { cerr << n << ": `" << index.member << "' cannot be used as an index" << endl; return false; } + if(containsSequence) + { + cerr << n << ": warning: use of sequences in dictionary keys has been deprecated" << endl; + } + if(index.caseSensitive == false) { diff --git a/cpp/src/slice2freezej/Main.cpp b/cpp/src/slice2freezej/Main.cpp index 4494fe94e0e..f8c51ab112b 100644 --- a/cpp/src/slice2freezej/Main.cpp +++ b/cpp/src/slice2freezej/Main.cpp @@ -254,11 +254,16 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) return false; } - if(!Dictionary::legalKeyType(valueType)) + bool containsSequence = false; + if(!Dictionary::legalKeyType(valueType, containsSequence)) { cerr << _prog << ": `" << dict.value << "' is not a valid index type" << endl; return false; } + if(containsSequence) + { + cerr << _prog << ": warning: use of sequences in dictionary keys has been deprecated" << endl; + } if(index.caseSensitive == false) { @@ -320,11 +325,16 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) TypePtr dataMemberType = dataMember->type(); - if(!Dictionary::legalKeyType(dataMemberType)) + bool containsSequence = false; + if(!Dictionary::legalKeyType(dataMemberType, containsSequence)) { cerr << _prog << ": `" << index.member << "' cannot be used as an index" << endl; return false; } + if(containsSequence) + { + cerr << _prog << ": warning: use of sequences in dictionary keys has been deprecated" << endl; + } if(index.caseSensitive == false) { diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp index 86150620aad..504cd6f6e31 100644 --- a/cpp/src/slice2java/Gen.cpp +++ b/cpp/src/slice2java/Gen.cpp @@ -2830,100 +2830,105 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) if(java2) { out << nl << "public final class " << name; + out << sb; + + out << nl << "private static " << name << "[] __values = new " << name << "[" << sz << "];"; + out << nl << "private int __value;"; + + out << sp; + int n; + for(en = enumerators.begin(), n = 0; en != enumerators.end(); ++en, ++n) + { + string member = fixKwd((*en)->name()); + out << nl << "public static final int _" << member << " = " << n << ';'; + out << nl << "public static final " << name << ' ' << fixKwd(member) + << " = new " << name << "(_" << member << ");"; + } + + out << sp << nl << "public static " << name << nl << "convert(int val)"; + out << sb; + out << nl << "assert val >= 0 && val < " << sz << ';'; + out << nl << "return __values[val];"; + out << eb; + + out << sp << nl << "public static " << name << nl << "convert(String val)"; + out << sb; + out << nl << "for(int __i = 0; __i < __values.length; ++__i)"; + out << sb; + out << nl << "if(__values[__i].toString().equals(val))"; + out << sb; + out << nl << "return __values[__i];"; + out << eb; + out << eb; + out << nl << "assert false;"; + out << nl << "return null;"; + out << eb; + + out << sp << nl << "public int" << nl << "value()"; + out << sb; + out << nl << "return __value;"; + out << eb; + + out << sp << nl << "public String" << nl << "toString()"; + out << sb; + out << nl << "return __T[__value];"; + out << eb; + + out << sp << nl << "private" << nl << name << "(int val)"; + out << sb; + out << nl << "__value = val;"; + out << nl << "__values[val] = this;"; + out << eb; } else { out << nl << "public enum " << name; - } - out << sb; + out << sb; - if(!java2) - { - int n; - for(en = enumerators.begin(), n = 0; en != enumerators.end(); ++en, ++n) + for(en = enumerators.begin(); en != enumerators.end(); ++en) { if(en != enumerators.begin()) { out << ','; } - out << nl << fixKwd((*en)->name()) << '(' << n << ')'; + out << nl << fixKwd((*en)->name()); } out << ';'; - out << sp; - } - out << nl << "private static " << name << "[] __values = new " << name << "[" << sz << "];"; - if(!java2) - { - out << nl << "static"; - out << sb; - int n; - for(en = enumerators.begin(), n = 0; en != enumerators.end(); ++en, ++n) - { - out << nl << "__values[" << n << "] = " << fixKwd((*en)->name()) << ';'; - } - out << eb; - } - out << nl << "private int __value;"; - - // - // For backward compatibility, we keep the integer member in the Java5 mapping. - // - { + // + // For backward compatibility, we keep the integer member in the Java5 mapping. + // out << sp; int n; for(en = enumerators.begin(), n = 0; en != enumerators.end(); ++en, ++n) { string member = fixKwd((*en)->name()); out << nl << "public static final int _" << member << " = " << n << ';'; - if(java2) - { - out << nl << "public static final " << name << ' ' << fixKwd(member) - << " = new " << name << "(_" << member << ");"; - } } - } - - out << sp << nl << "public static " << name << nl << "convert(int val)"; - out << sb; - out << nl << "assert val >= 0 && val < " << sz << ';'; - out << nl << "return __values[val];"; - out << eb; - - out << sp << nl << "public static " << name << nl << "convert(String val)"; - out << sb; - out << nl << "for(int __i = 0; __i < __values.length; ++__i)"; - out << sb; - out << nl << "if(__values[__i].toString().equals(val))"; - out << sb; - out << nl << "return __values[__i];"; - out << eb; - out << eb; - out << nl << "assert false;"; - out << nl << "return null;"; - out << eb; - out << sp << nl << "public int" << nl << "value()"; - out << sb; - out << nl << "return __value;"; - out << eb; + out << sp << nl << "public static " << name << nl << "convert(int val)"; + out << sb; + out << nl << "assert val >= 0 && val < " << sz << ';'; + out << nl << "return values()[val];"; + out << eb; - if(java2) - { - out << sp << nl << "public String" << nl << "toString()"; + out << sp << nl << "public static " << name << nl << "convert(String val)"; out << sb; - out << nl << "return __T[__value];"; + out << nl << "try"; + out << sb; + out << nl << "return valueOf(val);"; + out << eb; + out << nl << "catch(java.lang.IllegalArgumentException ex)"; + out << sb; + out << nl << "return null;"; + out << eb; out << eb; - } - out << sp << nl << "private" << nl << name << "(int val)"; - out << sb; - out << nl << "__value = val;"; - if(java2) - { - out << nl << "__values[val] = this;"; + out << sp << nl << "public int" << nl << "value()"; + out << sb; + out << nl << "return ordinal();"; + out << eb; } - out << eb; if(!p->isLocal()) { @@ -2931,15 +2936,15 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << sb; if(sz <= 0x7f) { - out << nl << "__os.writeByte((byte)__value);"; + out << nl << "__os.writeByte((byte)value());"; } else if(sz <= 0x7fff) { - out << nl << "__os.writeShort((short)__value);"; + out << nl << "__os.writeShort((short)value());"; } else { - out << nl << "__os.writeInt(__value);"; + out << nl << "__os.writeInt(value());"; } out << eb; @@ -2966,15 +2971,15 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << sb; if(sz <= 0x7f) { - out << nl << "__outS.writeByte((byte)__value);"; + out << nl << "__outS.writeByte((byte)value());"; } else if(sz <= 0x7fff) { - out << nl << "__outS.writeShort((short)__value);"; + out << nl << "__outS.writeShort((short)value());"; } else { - out << nl << "__outS.writeInt(__value);"; + out << nl << "__outS.writeInt(value());"; } out << eb; diff --git a/cpp/src/slice2sl/Gen.cpp b/cpp/src/slice2sl/Gen.cpp index 7e0d94b651f..516034513dc 100755 --- a/cpp/src/slice2sl/Gen.cpp +++ b/cpp/src/slice2sl/Gen.cpp @@ -1293,7 +1293,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sb; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - string name = fixId((*q)->name(), DotNet::ApplicationException, false); + string name = fixId((*q)->name(), DotNet::Exception, false); _out << nl << "this." << name << " = " << fixId((*q)->name()) << ';'; } _out << eb; @@ -1335,22 +1335,15 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sp << nl << "public override int GetHashCode()"; _out << sb; - _out << nl << "int h__ = 0;"; - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + if(p->base()) { - string memberName = fixId((*q)->name(), DotNet::ApplicationException); - bool isValue = isValueType((*q)->type()); - if(!isValue) - { - _out << nl << "if((object)" << memberName << " != null)"; - _out << sb; - } - _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; - if(!isValue) - { - _out << eb; - } + _out << nl << "int h__ = base.GetHashCode();"; } + else + { + _out << nl << "int h__ = 0;"; + } + writeMemberHashCode(dataMembers, DotNet::Exception); _out << nl << "return h__;"; _out << eb; @@ -1368,31 +1361,18 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << sb; _out << nl << "return false;"; _out << eb; - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + if(p->base()) { - string memberName = fixId((*q)->name(), DotNet::ApplicationException); - bool isValue = isValueType((*q)->type()); - if(!isValue) - { - _out << nl << "if(" << memberName << " == null)"; - _out << sb; - _out << nl << "if(((" << name << ")other__)." << memberName << " != null)"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - _out << eb; - _out << nl << "else"; - _out << sb; - } - _out << nl << "if(!" << memberName << ".Equals(((" << name << ")other__)." << memberName << "))"; + _out << nl << "if(!base.Equals(other__))"; _out << sb; _out << nl << "return false;"; _out << eb; - if(!isValue) - { - _out << eb; - } } + if(!dataMembers.empty()) + { + _out << nl << name << " o__ = (" << name << ")other__;"; + } + writeMemberEquals(dataMembers, DotNet::Exception); _out << nl << "return true;"; _out << eb; @@ -1425,7 +1405,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << nl << "os__.startWriteSlice();"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, DotNet::ApplicationException), + writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, DotNet::Exception), true, false, false); } _out << nl << "os__.endWriteSlice();"; @@ -1477,7 +1457,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) _out << nl << "case " << memberCount << ":"; _out.inc(); } - string memberName = fixId((*q)->name(), DotNet::ApplicationException); + string memberName = fixId((*q)->name(), DotNet::Exception); string memberType = typeToString((*q)->type()); _out << nl << "_instance." << memberName << " = (" << memberType << ")v;"; ContainedPtr contained = ContainedPtr::dynamicCast((*q)->type()); @@ -1530,7 +1510,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) patchParams << ", " << classMemberCount++; } } - writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::ApplicationException), + writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::Exception), false, false, false, patchParams.str()); } _out << nl << "is__.endReadSlice();"; @@ -1645,21 +1625,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) _out << sp << nl << "public override int GetHashCode()"; _out << sb; _out << nl << "int h__ = 0;"; - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) - { - string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0); - bool isValue = isValueType((*q)->type()); - if(!isValue) - { - _out << nl << "if(" << memberName << " != null)"; - _out << sb; - } - _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; - if(!isValue) - { - _out << eb; - } - } + writeMemberHashCode(dataMembers, isClass ? DotNet::ICloneable : 0); _out << nl << "return h__;"; _out << eb; @@ -1691,34 +1657,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) { _out << nl << name << " o__ = (" << name << ")other__;"; } - for(q = dataMembers.begin(); q != dataMembers.end(); ++q) - { - string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0); - if(!isValueType((*q)->type())) - { - _out << nl << "if(" << memberName << " == null)"; - _out << sb; - _out << nl << "if(o__." << memberName << " != null)"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - _out << eb; - _out << nl << "else"; - _out << sb; - _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - _out << eb; - } - else - { - _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; - _out << sb; - _out << nl << "return false;"; - _out << eb; - } - } + writeMemberEquals(dataMembers, isClass ? DotNet::ICloneable : 0); _out << nl << "return true;"; _out << eb; @@ -2023,7 +1962,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) } else if(ExceptionPtr::dynamicCast(cont)) { - baseTypes = DotNet::ApplicationException; + baseTypes = DotNet::Exception; } else if(ClassDefPtr::dynamicCast(cont)) { @@ -2088,6 +2027,168 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) _out << eb; } +void +Slice::Gen::TypesVisitor::writeMemberHashCode(const DataMemberList& dataMembers, int baseTypes) +{ + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixId((*q)->name(), baseTypes); + TypePtr memberType = (*q)->type(); + bool isValue = isValueType(memberType); + if(!isValue) + { + _out << nl << "if(" << memberName << " != null)"; + _out << sb; + } + SequencePtr seq = SequencePtr::dynamicCast(memberType); + if(seq) + { + string genericType; + bool isGeneric = seq->findMetaData("clr:generic:", genericType); + bool isArray = !isGeneric && !seq->hasMetaData("clr:collection"); + if(isArray) + { + // + // GetHashCode() for native arrays does not have value semantics. + // + _out << nl << "h__ = 5 * h__ + IceUtil.Arrays.GetHashCode(" << memberName << ");"; + } + else if(isGeneric) + { + // + // GetHashCode() for generic types does not have value semantics. + // + _out << nl << "h__ = 5 * h__ + IceUtil.Collections.SequenceGetHashCode(" << memberName << ");"; + } + else + { + // + // GetHashCode() for CollectionBase has value semantics. + // + _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; + } + } + else + { + DictionaryPtr dict = DictionaryPtr::dynamicCast(memberType); + if(dict) + { + if(dict->hasMetaData("clr:collection")) + { + // + // GetHashCode() for DictionaryBase has value semantics. + // + _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; + } + else + { + // + // GetHashCode() for generic types does not have value semantics. + // + _out << nl << "h__ = 5 * h__ + IceUtil.Collections.DictionaryGetHashCode(" << memberName + << ");"; + } + } + else + { + _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();"; + } + } + if(!isValue) + { + _out << eb; + } + } +} + +void +Slice::Gen::TypesVisitor::writeMemberEquals(const DataMemberList& dataMembers, int baseTypes) +{ + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixId((*q)->name(), baseTypes); + TypePtr memberType = (*q)->type(); + if(!isValueType(memberType)) + { + _out << nl << "if(" << memberName << " == null)"; + _out << sb; + _out << nl << "if(o__." << memberName << " != null)"; + _out << sb; + _out << nl << "return false;"; + _out << eb; + _out << eb; + _out << nl << "else"; + _out << sb; + SequencePtr seq = SequencePtr::dynamicCast(memberType); + if(seq) + { + string genericType; + bool isGeneric = seq->findMetaData("clr:generic:", genericType); + bool isArray = !isGeneric && !seq->hasMetaData("clr:collection"); + if(isArray) + { + // + // Equals() for native arrays does not have value semantics. + // + _out << nl << "if(!IceUtil.Arrays.Equals(" << memberName << ", o__." << memberName << "))"; + } + else if(isGeneric) + { + // + // Equals() for generic types does not have value semantics. + // + _out << nl << "if(!IceUtil.Collections.SequenceEquals(" << memberName << ", o__." + << memberName << "))"; + } + else + { + // + // Equals() for CollectionBase has value semantics. + // + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + } + } + else + { + DictionaryPtr dict = DictionaryPtr::dynamicCast(memberType); + if(dict) + { + if(dict->hasMetaData("clr:collection")) + { + // + // Equals() for DictionaryBase has value semantics. + // + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + } + else + { + // + // Equals() for generic types does not have value semantics. + // + _out << nl << "if(!IceUtil.Collections.DictionaryEquals(" << memberName << ", o__." + << memberName << "))"; + } + } + else + { + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + } + } + _out << sb; + _out << nl << "return false;"; + _out << eb; + _out << eb; + } + else + { + _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))"; + _out << sb; + _out << nl << "return false;"; + _out << eb; + } + } +} + Slice::Gen::ProxyVisitor::ProxyVisitor(IceUtilInternal::Output& out) : CsVisitor(out) { diff --git a/cpp/src/slice2sl/Gen.h b/cpp/src/slice2sl/Gen.h index c72a9e4b31d..c4d3292d072 100644 --- a/cpp/src/slice2sl/Gen.h +++ b/cpp/src/slice2sl/Gen.h @@ -99,6 +99,11 @@ private: virtual void visitEnum(const EnumPtr&); virtual void visitConst(const ConstPtr&); virtual void visitDataMember(const DataMemberPtr&); + + private: + + void writeMemberHashCode(const DataMemberList&, int); + void writeMemberEquals(const DataMemberList&, int); }; class ProxyVisitor : public CsVisitor |