diff options
Diffstat (limited to 'third_party')
148 files changed, 3917 insertions, 19008 deletions
diff --git a/third_party/libevent/README.chromium b/third_party/libevent/README.chromium index 1cd6437..c9002be 100644 --- a/third_party/libevent/README.chromium +++ b/third_party/libevent/README.chromium @@ -7,8 +7,9 @@ Local Modifications: Rather than use libevent's own build system, we just build a Chrome static library using GYP. -1) Run configure and "make event-config.h" on a Linux and Mac box and - copy config.h and event-config.h to linux/ and mac/ respectively. +1) Run configure and "make event-config.h" on a Linux, FreeBSD, and + Mac box and copy config.h and event-config.h to linux/, freebsd/, + and mac/ respectively. 2) Add libevent.gyp. 3) chromium.patch is applied to allow libevent to be used without being installed. diff --git a/third_party/libevent/chromium.patch b/third_party/libevent/chromium.patch index 9685e6b..04a73b0 100644 --- a/third_party/libevent/chromium.patch +++ b/third_party/libevent/chromium.patch @@ -3,7 +3,7 @@ new file mode 100644 index 0000000..78a4727 --- /dev/null +++ b/third_party/libevent/event-config.h -@@ -0,0 +1,14 @@ +@@ -0,0 +1,16 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -15,6 +15,8 @@ index 0000000..78a4727 +#include "mac/event-config.h" +#elif defined(__linux__) +#include "linux/event-config.h" ++#elif defined(__FreeBSD__) ++#include "freebsd/event-config.h" +#else +#error generate event-config.h for your platform +#endif diff --git a/third_party/libevent/event-config.h b/third_party/libevent/event-config.h index d0b4ba5..0f280aa 100644 --- a/third_party/libevent/event-config.h +++ b/third_party/libevent/event-config.h @@ -11,6 +11,8 @@ #include "android/event-config.h" #elif defined(__linux__) #include "linux/event-config.h" +#elif defined(__FreeBSD__) +#include "freebsd/event-config.h" #else #error generate event-config.h for your platform #endif diff --git a/third_party/libjingle/source/CHANGELOG b/third_party/libjingle/source/CHANGELOG new file mode 100644 index 0000000..3dee65e --- /dev/null +++ b/third_party/libjingle/source/CHANGELOG @@ -0,0 +1,33 @@ +Libjingle + +0.5.0 - Sep 16, 2010 + - Implemented Jingle protocols XEP-166 and XEP-167. + - Backward compatible with Google Talk Call Signaling protocol implemented + in previous versions. + - Builds on Windows, Linux, and Mac OS X with swtoolkit. + - Removed GipsLiteMediaEngine. + - Added video support. + - Added FileMediaEngine to support both voice and video via RTP dump. + - Many bug fixes. + +0.4.0 - Feb 01, 2007 + - Updated protocol. + - Added relay server support. + - Added proxy detection support. + - Many other assorted changes. + +0.3.0 - Mar 16 2006 + - New GipsLiteMediaEngine included to make calls using the GIPS + VoiceEngine Lite media componentry on Windows. + +0.2.0 - Jan 27 2006 + - Windows build fixes with Visual Studio Express project files. + - Pseudo-TCP support provides TCP-like reliability over a P2PSocket + - TunnelSessionClient establishes sessions for reliably sending data + using Pseudo-TCP. + - A new pcp example application transfers files from one user to + another using TunnelSessionClient. + - TLS login support for both example applications. + +0.1.0 - Dec 15 2005 + - Initial release. diff --git a/third_party/libjingle/source/README b/third_party/libjingle/source/README index bdccd20..b127b56 100644 --- a/third_party/libjingle/source/README +++ b/third_party/libjingle/source/README @@ -10,18 +10,19 @@ compatible with Google Talk Call Signaling create several static libraries you may link to your projects as needed. -talk - No source files in talk/, just these subdirectories -|-base - Contains basic low-level portable utility functions for +|-base - Contains basic low-level portable utility functions for | things like threads and sockets |-p2p - The P2P stack |-base - Base p2p functionality |-client - Hooks to tie it into XMPP |-session - Signaling |-phone - Signaling code specific to making phone calls + |-testdata - Samples of RTP voice and video dump |-tunnel - Tunnel session and channel |-xmllite - XML parser |-xmpp - XMPP engine -In addition, this package contains two examples in talk/examples which +In addition, this package contains two examples in talk/examples which illustrate the basic concepts of how the provided classes work. 2. How to Build @@ -66,9 +67,17 @@ is a set of extensions to the open-source SCons build tool (www.scons.org). The built binaries are under talk/build/dbg/staging or talk/build/opt/staging, depending on the build mode. When the build is complete, you can run the -examples, login or call. Libjingle also builds two server tools, a relay server -and a STUN server. The relay server may be used to relay traffic when a direct -peer-to-peer connection could not be established. The STUN Server implements the -STUN protocol for Simple Traversal of UDP over NAT. See the Libjingle Developer -Guide at http://code.google.com/apis/talk/index.html for information about -configuring a client to use this relay server and this STUN server.
\ No newline at end of file +examples, login or call. For the call sample, you can specify the input and +output RTP dump for voice and video. This package provides two samples of input +RTP dump: voice.rtpdump is a single channel, 16Khz voice encoded with G722, and +video.rtpdump is 320x240 video encoded with H264 AVC at 30 frames per second. +These provided samples will inter-operate with Google Talk Video. If you use +other input RTP dump, you may need to change the codecs in call_main.cc, lines +215 - 222. + +Libjingle also builds two server tools, a relay server and a STUN server. The +relay server may be used to relay traffic when a direct peer-to-peer connection +could not be established. The STUN Server implements the STUN protocol for +Simple Traversal of UDP over NAT. See the Libjingle Developer Guide at +http://code.google.com/apis/talk/index.html for information about configuring a +client to use this relay server and this STUN server.
\ No newline at end of file diff --git a/third_party/libjingle/source/talk/base/asyncsocket.h b/third_party/libjingle/source/talk/base/asyncsocket.h index 1541894..3d12984 100644 --- a/third_party/libjingle/source/talk/base/asyncsocket.h +++ b/third_party/libjingle/source/talk/base/asyncsocket.h @@ -34,7 +34,7 @@ namespace talk_base { -// TODO(juberti): Remove Socket and rename AsyncSocket to Socket. +// TODO: Remove Socket and rename AsyncSocket to Socket. // Provides the ability to perform socket I/O asynchronously. class AsyncSocket : public Socket { diff --git a/third_party/libjingle/source/talk/base/asyncudpsocket.cc b/third_party/libjingle/source/talk/base/asyncudpsocket.cc index 3fae8e4..2899606 100644 --- a/third_party/libjingle/source/talk/base/asyncudpsocket.cc +++ b/third_party/libjingle/source/talk/base/asyncudpsocket.cc @@ -59,14 +59,14 @@ void AsyncUDPSocket::OnReadEvent(AsyncSocket* socket) { // An error here typically means we got an ICMP error in response to our // send datagram, indicating the remote address was unreachable. // When doing ICE, this kind of thing will often happen. - // TODO(juberti): Do something better like forwarding the error to the user. + // TODO: Do something better like forwarding the error to the user. SocketAddress local_addr = socket_->GetLocalAddress(); LOG(LS_INFO) << "AsyncUDPSocket[" << local_addr.ToString() << "] " << "receive failed with error " << socket_->GetError(); return; } - // TODO(juberti): Make sure that we got all of the packet. + // TODO: Make sure that we got all of the packet. // If we did not, then we should resize our buffer to be large enough. SignalReadPacket(buf_, (size_t)len, remote_addr, this); } diff --git a/third_party/libjingle/source/talk/base/asyncudpsocket.h b/third_party/libjingle/source/talk/base/asyncudpsocket.h index 7af772e..3a6960c 100644 --- a/third_party/libjingle/source/talk/base/asyncudpsocket.h +++ b/third_party/libjingle/source/talk/base/asyncudpsocket.h @@ -54,7 +54,7 @@ class AsyncUDPSocket : public AsyncPacketSocket { size_t size_; }; -// TODO(juberti): This is now deprecated. Remove it. +// TODO: This is now deprecated. Remove it. inline AsyncUDPSocket* CreateAsyncUDPSocket(SocketFactory* factory) { return AsyncUDPSocket::Create(factory); } diff --git a/third_party/libjingle/source/talk/base/autodetectproxy.cc b/third_party/libjingle/source/talk/base/autodetectproxy.cc index 2b06430..ffcac26 100644 --- a/third_party/libjingle/source/talk/base/autodetectproxy.cc +++ b/third_party/libjingle/source/talk/base/autodetectproxy.cc @@ -46,7 +46,7 @@ AutoDetectProxy::~AutoDetectProxy() { } void AutoDetectProxy::DoWork() { - // TODO(oja): Try connecting to server_url without proxy first here? + // TODO: Try connecting to server_url without proxy first here? if (!server_url_.empty()) { LOG(LS_INFO) << "GetProxySettingsForUrl(" << server_url_ << ") - start"; GetProxySettingsForUrl(agent_.c_str(), server_url_.c_str(), proxy_, true); @@ -66,7 +66,7 @@ void AutoDetectProxy::DoWork() { // Clean up the autodetect socket, from the thread that created it delete socket_; } - // TODO(oja): If we found a proxy, try to use it to verify that it + // TODO: If we found a proxy, try to use it to verify that it // works by sending a request to server_url. This could either be // done here or by the HttpPortAllocator. } diff --git a/third_party/libjingle/source/talk/base/basictypes.h b/third_party/libjingle/source/talk/base/basictypes.h index 71b75c6..781d428 100644 --- a/third_party/libjingle/source/talk/base/basictypes.h +++ b/third_party/libjingle/source/talk/base/basictypes.h @@ -52,14 +52,22 @@ typedef char int8; #ifdef COMPILER_MSVC typedef unsigned __int64 uint64; typedef __int64 int64; +#ifndef INT64_C #define INT64_C(x) x ## I64 +#endif +#ifndef UINT64_C #define UINT64_C(x) x ## UI64 +#endif #define INT64_F "I64" #else typedef unsigned long long uint64; typedef long long int64; +#ifndef INT64_C #define INT64_C(x) x ## LL +#endif +#ifndef UINT64_C #define UINT64_C(x) x ## ULL +#endif #define INT64_F "ll" #endif /* COMPILER_MSVC */ typedef unsigned int uint32; @@ -85,7 +93,7 @@ namespace talk_base { #else // !WIN32 #define alignof(t) __alignof__(t) #endif // !WIN32 -#define IS_ALIGNED(p, t) (0==(reinterpret_cast<uintptr_t>(p) & (alignof(t)-1))) +#define IS_ALIGNED(p, a) (0==(reinterpret_cast<uintptr_t>(p) & ((a)-1))) #define ALIGNP(p, t) \ (reinterpret_cast<uint8*>(((reinterpret_cast<uintptr_t>(p) + \ ((t)-1)) & ~((t)-1)))) diff --git a/third_party/libjingle/source/talk/base/common.h b/third_party/libjingle/source/talk/base/common.h index 1dfd5ba..ba9c5ae 100644 --- a/third_party/libjingle/source/talk/base/common.h +++ b/third_party/libjingle/source/talk/base/common.h @@ -52,7 +52,7 @@ inline void Unused(const void *) { } #define strnicmp(x,y,n) strncasecmp(x,y,n) #define stricmp(x,y) strcasecmp(x,y) -// TODO(sergeyu): Remove this. std::max should be used everywhere in the code. +// TODO: Remove this. std::max should be used everywhere in the code. // NOMINMAX must be defined where we include <windows.h>. #define stdmax(x,y) std::max(x,y) #else diff --git a/third_party/libjingle/source/talk/base/firewallsocketserver.cc b/third_party/libjingle/source/talk/base/firewallsocketserver.cc index 819ec5f..a99c72e 100644 --- a/third_party/libjingle/source/talk/base/firewallsocketserver.cc +++ b/third_party/libjingle/source/talk/base/firewallsocketserver.cc @@ -47,7 +47,7 @@ class FirewallSocket : public AsyncSocketAdapter { LOG(LS_VERBOSE) << "FirewallSocket outbound TCP connection from " << GetLocalAddress().ToString() << " to " << addr.ToString() << " denied"; - // TODO(juberti): Handle this asynchronously. + // TODO: Handle this asynchronously. SetError(EHOSTUNREACH); return SOCKET_ERROR; } diff --git a/third_party/libjingle/source/talk/base/helpers.cc b/third_party/libjingle/source/talk/base/helpers.cc index ff38db0..94ca57e 100644 --- a/third_party/libjingle/source/talk/base/helpers.cc +++ b/third_party/libjingle/source/talk/base/helpers.cc @@ -187,7 +187,7 @@ class TestRandomGenerator : public RandomGenerator { int seed_; }; -// TODO(juberti): Use Base64::Base64Table instead. +// TODO: Use Base64::Base64Table instead. static const char BASE64[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', diff --git a/third_party/libjingle/source/talk/base/host.cc b/third_party/libjingle/source/talk/base/host.cc index 51c37d2..7decc49 100644 --- a/third_party/libjingle/source/talk/base/host.cc +++ b/third_party/libjingle/source/talk/base/host.cc @@ -36,7 +36,7 @@ namespace talk_base { std::string GetHostName() { - // TODO(juberti): fix or get rid of this + // TODO: fix or get rid of this #if 0 struct utsname nm; if (uname(&nm) < 0) diff --git a/third_party/libjingle/source/talk/base/httpbase.cc b/third_party/libjingle/source/talk/base/httpbase.cc index 7015145..f5dc60e 100644 --- a/third_party/libjingle/source/talk/base/httpbase.cc +++ b/third_party/libjingle/source/talk/base/httpbase.cc @@ -27,7 +27,7 @@ // Copyright 2005 Google Inc. All Rights Reserved. // -// Author: <bpm@google.com> (Brian McBarron) + #ifdef WIN32 #include "talk/base/win32.h" diff --git a/third_party/libjingle/source/talk/base/httpbase.h b/third_party/libjingle/source/talk/base/httpbase.h index d457e6b..97527eb 100644 --- a/third_party/libjingle/source/talk/base/httpbase.h +++ b/third_party/libjingle/source/talk/base/httpbase.h @@ -27,7 +27,7 @@ // Copyright 2005 Google Inc. All Rights Reserved. // -// Author: <bpm@google.com> (Brian McBarron) + #ifndef TALK_BASE_HTTPBASE_H__ #define TALK_BASE_HTTPBASE_H__ diff --git a/third_party/libjingle/source/talk/base/httpcommon.cc b/third_party/libjingle/source/talk/base/httpcommon.cc index d83255f..f7553b2 100644 --- a/third_party/libjingle/source/talk/base/httpcommon.cc +++ b/third_party/libjingle/source/talk/base/httpcommon.cc @@ -399,7 +399,7 @@ bool HttpDateToSeconds(const std::string& date, unsigned long* seconds) { gmt = non_gmt + kTimeZoneOffsets[zindex] * 60 * 60; } // TODO: Android should support timezone, see b/2441195 -#if defined(OSX) || defined(ANDROID) +#if defined(OSX) || defined(ANDROID) || defined(BSD) tm *tm_for_timezone = localtime((time_t *)&gmt); *seconds = gmt + tm_for_timezone->tm_gmtoff; #else diff --git a/third_party/libjingle/source/talk/base/httpcommon.h b/third_party/libjingle/source/talk/base/httpcommon.h index f3be3cd..7e0b9cf 100644 --- a/third_party/libjingle/source/talk/base/httpcommon.h +++ b/third_party/libjingle/source/talk/base/httpcommon.h @@ -206,7 +206,7 @@ class Url { public: typedef typename Traits<CTYPE>::string string; - // TODO(bpm): Implement Encode/Decode + // TODO: Implement Encode/Decode static int Encode(const CTYPE* source, CTYPE* destination, size_t len); static int Encode(const string& source, string& destination); static int Decode(const CTYPE* source, CTYPE* destination, size_t len); diff --git a/third_party/libjingle/source/talk/base/linux.cc b/third_party/libjingle/source/talk/base/linux.cc index 6a798cc..2061d73 100644 --- a/third_party/libjingle/source/talk/base/linux.cc +++ b/third_party/libjingle/source/talk/base/linux.cc @@ -1,5 +1,5 @@ // Copyright 2008 Google Inc. All Rights Reserved. -// Author: araju@google.com (Avanish Raju) + // #ifdef LINUX diff --git a/third_party/libjingle/source/talk/base/linux.h b/third_party/libjingle/source/talk/base/linux.h index ef775ed..808dc0e 100644 --- a/third_party/libjingle/source/talk/base/linux.h +++ b/third_party/libjingle/source/talk/base/linux.h @@ -1,5 +1,5 @@ // Copyright 2008 Google Inc. All Rights Reserved. -// Author: araju@google.com (Avanish Raju) + #ifndef TALK_BASE_LINUX_H_ #define TALK_BASE_LINUX_H_ diff --git a/third_party/libjingle/source/talk/base/nethelpers.cc b/third_party/libjingle/source/talk/base/nethelpers.cc index 24c142c..5740dc3 100644 --- a/third_party/libjingle/source/talk/base/nethelpers.cc +++ b/third_party/libjingle/source/talk/base/nethelpers.cc @@ -96,7 +96,7 @@ hostent* SafeGetHostByName(const char* hostname, int* herrno) { p += (num_aliases + 1) * sizeof(char*); for (int i = 0; i < num_aliases; ++i) { result->h_aliases[i] = p; - memcpy(p, result->h_aliases[i], strlen(ent->h_aliases[i]) + 1); + memcpy(p, ent->h_aliases[i], strlen(ent->h_aliases[i]) + 1); p += strlen(ent->h_aliases[i]) + 1; } result->h_aliases[num_aliases] = NULL; diff --git a/third_party/libjingle/source/talk/base/network.cc b/third_party/libjingle/source/talk/base/network.cc index 4091081..8a56d0a 100644 --- a/third_party/libjingle/source/talk/base/network.cc +++ b/third_party/libjingle/source/talk/base/network.cc @@ -208,7 +208,7 @@ void NetworkManager::SetState(const std::string& str) { // Gets the default gateway for the specified interface. uint32 GetDefaultGateway(const std::string& name) { #ifdef OSX - // TODO(juberti): /proc/net/route doesn't exist, + // TODO: /proc/net/route doesn't exist, // Use ioctl to get the routing table return 0xFFFFFFFF; #endif @@ -368,7 +368,7 @@ Network::Network(const std::string& name, const std::string& desc, quality_(kDefaultQuality) { last_data_time_ = Time(); - // TODO(juberti): seed the historical data with one data point based + // TODO: seed the historical data with one data point based // on the link speed metric from XP (4.0 if < 50, 3.0 otherwise). } diff --git a/third_party/libjingle/source/talk/base/openssladapter.cc b/third_party/libjingle/source/talk/base/openssladapter.cc index 5f0bfae..2aacecc 100644 --- a/third_party/libjingle/source/talk/base/openssladapter.cc +++ b/third_party/libjingle/source/talk/base/openssladapter.cc @@ -823,7 +823,7 @@ OpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) { bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) { // Add the root cert to the SSL context - // TODO(sdoyon): this cert appears to be the wrong one. + // TODO: this cert appears to be the wrong one. #if OPENSSL_VERSION_NUMBER >= 0x0090800fL const unsigned char* cert_buffer #else diff --git a/third_party/libjingle/source/talk/base/physicalsocketserver.cc b/third_party/libjingle/source/talk/base/physicalsocketserver.cc index f5724f2..d97cba7 100644 --- a/third_party/libjingle/source/talk/base/physicalsocketserver.cc +++ b/third_party/libjingle/source/talk/base/physicalsocketserver.cc @@ -487,7 +487,7 @@ class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> { *slevel = IPPROTO_IP; *sopt = IP_DONTFRAGMENT; break; -#elif defined(OSX) +#elif defined(OSX) || defined(BSD) LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported."; return -1; #elif defined(POSIX) @@ -1311,7 +1311,7 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { int errcode = 0; // Reap any error code, which can be signaled through reads or writes. - // TODO(juberti): Should we set errcode if getsockopt fails? + // TODO: Should we set errcode if getsockopt fails? if (FD_ISSET(fd, &fdsRead) || FD_ISSET(fd, &fdsWrite)) { socklen_t len = sizeof(errcode); ::getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &len); @@ -1320,7 +1320,7 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { // Check readable descriptors. If we're waiting on an accept, signal // that. Otherwise we're waiting for data, check to see if we're // readable or really closed. - // TODO(juberti): Only peek at TCP descriptors. + // TODO: Only peek at TCP descriptors. if (FD_ISSET(fd, &fdsRead)) { FD_CLR(fd, &fdsRead); if (pdispatcher->GetRequestedEvents() & kfAccept) { @@ -1505,7 +1505,7 @@ bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) { if (dw == WSA_WAIT_FAILED) { // Failed? - // TODO(juberti): need a better strategy than this! + // TODO: need a better strategy than this! int error = WSAGetLastError(); ASSERT(false); return false; diff --git a/third_party/libjingle/source/talk/base/proxydetect.cc b/third_party/libjingle/source/talk/base/proxydetect.cc index 79ec3ac..66213ee 100644 --- a/third_party/libjingle/source/talk/base/proxydetect.cc +++ b/third_party/libjingle/source/talk/base/proxydetect.cc @@ -308,7 +308,7 @@ bool ParseProxy(const std::string& saddress, ProxyInfo* proxy) { if (const char * sep = strchr(address, kAddressSeparator)) { len = (sep - address); address += len + 1; - while (::strchr(kAddressSeparator, *address)) { + while (*address != '\0' && ::strchr(kAddressSeparator, *address)) { address += 1; } } else { @@ -459,7 +459,7 @@ bool GetDefaultFirefoxProfile(Pathname* profile_path) { candidate.clear(); } else if (line.find("IsRelative=") == 0 && line.length() >= 12) { - // TODO(tschmelcher): The initial Linux public launch revealed a fairly + // TODO: The initial Linux public launch revealed a fairly // high number of machines where IsRelative= did not have anything after // it. Perhaps that is legal profiles.ini syntax? relative = (line.at(11) != '0'); @@ -767,7 +767,7 @@ bool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url, // Either the given auto config url was valid or auto // detection found a proxy on this network. if (info.lpszProxy) { - // TODO(oja): Does this bypass list differ from the list + // TODO: Does this bypass list differ from the list // retreived from GetWinHttpProxySettings earlier? if (info.lpszProxyBypass) { proxy->bypass_list = ToUtf8(info.lpszProxyBypass); @@ -946,7 +946,7 @@ bool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) { bool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) { bool success = GetWinHttpProxySettings(url, proxy); if (!success) { - // TODO(oja): Should always call this if no proxy were detected by + // TODO: Should always call this if no proxy were detected by // GetWinHttpProxySettings? // WinHttp failed. Try using the InternetOptionQuery method instead. return GetIeLanProxySettings(url, proxy); @@ -1209,7 +1209,7 @@ bool GetSystemDefaultProxySettings(const char* agent, const char* url, #elif OSX return GetMacProxySettings(proxy); #else - // TODO(oja): Get System settings if browser is not firefox. + // TODO: Get System settings if browser is not firefox. return GetFirefoxProxySettings(url, proxy); #endif } @@ -1241,7 +1241,7 @@ bool GetProxySettingsForUrl(const char* agent, const char* url, break; } - // TODO(oja): Consider using the 'long_operation' parameter to + // TODO: Consider using the 'long_operation' parameter to // decide whether to do the auto detection. if (result && (proxy.autodetect || !proxy.autoconfig_url.empty())) { diff --git a/third_party/libjingle/source/talk/base/socketadapters.cc b/third_party/libjingle/source/talk/base/socketadapters.cc index b82c3fe..427ebdc 100644 --- a/third_party/libjingle/source/talk/base/socketadapters.cc +++ b/third_party/libjingle/source/talk/base/socketadapters.cc @@ -67,7 +67,7 @@ BufferedReadAdapter::~BufferedReadAdapter() { int BufferedReadAdapter::Send(const void *pv, size_t cb) { if (buffering_) { - // TODO(juberti): Spoof error better; Signal Writeable + // TODO: Spoof error better; Signal Writeable socket_->SetError(EWOULDBLOCK); return -1; } @@ -122,7 +122,7 @@ void BufferedReadAdapter::OnReadEvent(AsyncSocket * socket) { int len = socket_->Recv(buffer_ + data_len_, buffer_size_ - data_len_); if (len < 0) { - // TODO(juberti): Do something better like forwarding the error to the user. + // TODO: Do something better like forwarding the error to the user. LOG_ERR(INFO) << "Recv"; return; } @@ -135,7 +135,7 @@ void BufferedReadAdapter::OnReadEvent(AsyncSocket * socket) { /////////////////////////////////////////////////////////////////////////////// // This is a SSL v2 CLIENT_HELLO message. -// TODO(juberti): Should this have a session id? The response doesn't have a +// TODO: Should this have a session id? The response doesn't have a // certificate, so the hello should have a session id. static const uint8 kSslClientHello[] = { 0x80, 0x46, // msg len @@ -187,7 +187,7 @@ int AsyncSSLSocket::Connect(const SocketAddress& addr) { void AsyncSSLSocket::OnConnectEvent(AsyncSocket * socket) { ASSERT(socket == socket_); - // TODO(juberti): we could buffer output too... + // TODO: we could buffer output too... VERIFY(sizeof(kSslClientHello) == DirectSend(kSslClientHello, sizeof(kSslClientHello))); } @@ -198,7 +198,7 @@ void AsyncSSLSocket::ProcessInput(char* data, size_t* len) { if (memcmp(kSslServerHello, data, sizeof(kSslServerHello)) != 0) { Close(); - SignalCloseEvent(this, 0); // TODO(juberti): error code? + SignalCloseEvent(this, 0); // TODO: error code? return; } @@ -271,7 +271,7 @@ int AsyncHttpsProxySocket::Connect(const SocketAddress& addr) { BufferInput(true); } ret = BufferedReadAdapter::Connect(proxy_); - // TODO(juberti): Set state_ appropriately if Connect fails. + // TODO: Set state_ appropriately if Connect fails. return ret; } @@ -358,11 +358,11 @@ void AsyncHttpsProxySocket::ProcessInput(char* data, size_t* len) { // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble if (remainder) - SignalReadEvent(this); // TODO(juberti): signal this?? + SignalReadEvent(this); // TODO: signal this?? } bool AsyncHttpsProxySocket::ShouldIssueConnect() const { - // TODO(juberti): Think about whether a more sophisticated test + // TODO: Think about whether a more sophisticated test // than dest port == 80 is needed. return force_connect_ || (dest_.port() != 80); } @@ -421,7 +421,7 @@ void AsyncHttpsProxySocket::ProcessLine(char * data, size_t len) { MessageBoxA(0, msg.c_str(), "Oops!", MB_OK); #endif #ifdef POSIX - // TODO(juberti): Raise a signal so the UI can be separated. + // TODO: Raise a signal so the UI can be separated. LOG(LS_ERROR) << "Oops!\n\n" << msg; #endif } @@ -499,7 +499,7 @@ void AsyncHttpsProxySocket::EndResponse() { } // No point in waiting for the server to close... let's close now - // TODO(juberti): Refactor out PS_WAIT_CLOSE + // TODO: Refactor out PS_WAIT_CLOSE state_ = PS_WAIT_CLOSE; BufferedReadAdapter::Close(); OnCloseEvent(this, 0); @@ -528,7 +528,7 @@ int AsyncSocksProxySocket::Connect(const SocketAddress& addr) { state_ = SS_INIT; BufferInput(true); ret = BufferedReadAdapter::Connect(proxy_); - // TODO(juberti): Set state_ appropriately if Connect fails. + // TODO: Set state_ appropriately if Connect fails. return ret; } @@ -647,7 +647,7 @@ void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) { // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble if (remainder) - SignalReadEvent(this); // TODO(juberti): signal this?? + SignalReadEvent(this); // TODO: signal this?? } void AsyncSocksProxySocket::SendHello() { @@ -714,7 +714,7 @@ AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(AsyncSocket* socket) } void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) { - // TODO(juberti): See if the whole message has arrived + // TODO: See if the whole message has arrived ASSERT(state_ < SS_CONNECT_PENDING); ByteBuffer response(data, *len); @@ -755,7 +755,7 @@ void AsyncSocksProxyServerSocket::HandleHello(ByteBuffer* request) { return; } - // TODO(juberti): Ask the server which method to use. + // TODO: Ask the server which method to use. SendHelloReply(method); if (method == 0) { state_ = SS_CONNECT; @@ -785,7 +785,7 @@ void AsyncSocksProxyServerSocket::HandleAuth(ByteBuffer* request) { return; } - // TODO(juberti): Allow for checking of credentials. + // TODO: Allow for checking of credentials. SendAuthReply(0); state_ = SS_CONNECT; } diff --git a/third_party/libjingle/source/talk/base/socketadapters.h b/third_party/libjingle/source/talk/base/socketadapters.h index 71f976b..320da6f 100644 --- a/third_party/libjingle/source/talk/base/socketadapters.h +++ b/third_party/libjingle/source/talk/base/socketadapters.h @@ -157,7 +157,7 @@ class AsyncHttpsProxySocket : public BufferedReadAdapter { DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxySocket); }; -/* TODO(juberti): Implement this. +/* TODO: Implement this. class AsyncHttpsProxyServerSocket : public AsyncProxyServerSocket { public: explicit AsyncHttpsProxyServerSocket(AsyncSocket* socket); diff --git a/third_party/libjingle/source/talk/base/stringutils.h b/third_party/libjingle/source/talk/base/stringutils.h index 686a73e..3e1771f 100644 --- a/third_party/libjingle/source/talk/base/stringutils.h +++ b/third_party/libjingle/source/talk/base/stringutils.h @@ -31,13 +31,19 @@ #include <ctype.h> #include <stdarg.h> #include <stdio.h> + #ifdef WIN32 #include <malloc.h> #include <wchar.h> #define alloca _alloca #endif // WIN32 + #ifdef POSIX +#ifdef BSD +#include <stdlib.h> +#else // BSD #include <alloca.h> +#endif // !BSD #endif // POSIX #include <cstring> diff --git a/third_party/libjingle/source/talk/base/taskrunner.cc b/third_party/libjingle/source/talk/base/taskrunner.cc index bf5ed7d..0c0816c 100644 --- a/third_party/libjingle/source/talk/base/taskrunner.cc +++ b/third_party/libjingle/source/talk/base/taskrunner.cc @@ -139,7 +139,7 @@ void TaskRunner::PollTasks() { // see if our "next potentially timed-out task" has indeed timed out. // If it has, wake it up, then queue up the next task in line // Repeat while we have new timed-out tasks. - // TODO(juberti): We need to guard against WakeTasks not updating + // TODO: We need to guard against WakeTasks not updating // next_timeout_task_. Maybe also add documentation in the header file once // we understand this code better. Task* old_timeout_task = NULL; diff --git a/third_party/libjingle/source/talk/base/thread.cc b/third_party/libjingle/source/talk/base/thread.cc index af640a0..28f3e48 100644 --- a/third_party/libjingle/source/talk/base/thread.cc +++ b/third_party/libjingle/source/talk/base/thread.cc @@ -340,7 +340,7 @@ void* Thread::PreRun(void* pv) { #if defined(WIN32) SetThreadName(GetCurrentThreadId(), init->thread->name_.c_str()); #elif defined(POSIX) - // TODO(juberti): See if naming exists for pthreads. + // TODO: See if naming exists for pthreads. #endif #ifdef OSX_USE_COCOA // Make sure the new thread has an autoreleasepool diff --git a/third_party/libjingle/source/talk/base/unixfilesystem.cc b/third_party/libjingle/source/talk/base/unixfilesystem.cc index 842f560..436dc2f 100644 --- a/third_party/libjingle/source/talk/base/unixfilesystem.cc +++ b/third_party/libjingle/source/talk/base/unixfilesystem.cc @@ -507,17 +507,8 @@ bool UnixFilesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) { Pathname UnixFilesystem::GetCurrentDirectory() { Pathname cwd; -#if defined(LINUX) || defined(OSX) - // Both Linux and Mac supported malloc()'ing the string themselves, although - // that is not required by POSIX. - char *path = getcwd(NULL, 0); -#elif defined(ANDROID) - // Android requires the buffer to be allocated before getcwd is called. char buffer[PATH_MAX]; char *path = getcwd(buffer, PATH_MAX); -#else -#error GetCurrentDirectory() not implemented on this platform -#endif if (!path) { LOG_ERR(LS_ERROR) << "getcwd() failed"; @@ -525,9 +516,6 @@ Pathname UnixFilesystem::GetCurrentDirectory() { } cwd.SetFolder(std::string(path)); -#if defined(LINUX) || defined(OSX) - free(path); -#endif return cwd; } diff --git a/third_party/libjingle/source/talk/base/win32filesystem.cc b/third_party/libjingle/source/talk/base/win32filesystem.cc index 41e2e9a..f2a2256 100644 --- a/third_party/libjingle/source/talk/base/win32filesystem.cc +++ b/third_party/libjingle/source/talk/base/win32filesystem.cc @@ -42,7 +42,7 @@ // before calling GetLongPathName. We do this because calling GetLongPathName // when running under protected mode IE (a low integrity process) can result in // a virtualized path being returned, which is wrong if you only plan to read. -// TODO(juberti): Waiting to hear back from IE team on whether this is the +// TODO: Waiting to hear back from IE team on whether this is the // best approach; IEIsProtectedModeProcess is another possible solution. namespace talk_base { diff --git a/third_party/libjingle/source/talk/base/win32socketserver.cc b/third_party/libjingle/source/talk/base/win32socketserver.cc index 6a5307b..490799c 100644 --- a/third_party/libjingle/source/talk/base/win32socketserver.cc +++ b/third_party/libjingle/source/talk/base/win32socketserver.cc @@ -39,7 +39,7 @@ namespace talk_base { // Win32Socket /////////////////////////////////////////////////////////////////////////////// -// TODO(juberti): Move this to a common place where PhysicalSocketServer can +// TODO: Move this to a common place where PhysicalSocketServer can // share it. // Standard MTUs static const uint16 PACKET_MAXIMUMS[] = { @@ -67,7 +67,7 @@ static const uint16 PACKET_MAXIMUMS[] = { static const uint32 IP_HEADER_SIZE = 20; static const uint32 ICMP_HEADER_SIZE = 8; -// TODO(juberti): Enable for production builds also? Use FormatMessage? +// TODO: Enable for production builds also? Use FormatMessage? #ifdef _DEBUG LPCSTR WSAErrorToString(int error, LPCSTR *description_result) { LPCSTR string = "Unspecified"; diff --git a/third_party/libjingle/source/talk/examples/call/call_main.cc b/third_party/libjingle/source/talk/examples/call/call_main.cc index cb42819..dde0784 100644 --- a/third_party/libjingle/source/talk/examples/call/call_main.cc +++ b/third_party/libjingle/source/talk/examples/call/call_main.cc @@ -32,6 +32,8 @@ #include <vector> #include "talk/base/logging.h" #include "talk/base/flags.h" +#include "talk/base/pathutils.h" +#include "talk/base/stream.h" #include "talk/base/ssladapter.h" #include "talk/base/win32socketserver.h" #include "talk/xmpp/xmppclientsettings.h" @@ -40,6 +42,7 @@ #include "talk/examples/login/xmpppump.h" #include "talk/examples/call/callclient.h" #include "talk/examples/call/console.h" +#include "talk/session/phone/filemediaengine.h" class DebugLog : public sigslot::has_slots<> { public: @@ -114,8 +117,8 @@ class DebugLog : public sigslot::has_slots<> { time_string[time_len-1] = 0; // trim off terminating \n } } - LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<<<<<<<<<<") - << " : " << time_string; + LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<") + << " : " << time_string; bool indent; int start = 0, nest = 3; @@ -131,7 +134,8 @@ class DebugLog : public sigslot::has_slots<> { } // Output a tag - LOG(INFO) << std::setw(nest) << " " << std::string(buf + start, i + 1 - start); + LOG(INFO) << std::setw(nest) << " " + << std::string(buf + start, i + 1 - start); if (indent) nest += 2; @@ -150,7 +154,8 @@ class DebugLog : public sigslot::has_slots<> { LOG(INFO) << std::setw(nest) << " " << "## TEXT REMOVED ##"; censor_password_ = false; } else { - LOG(INFO) << std::setw(nest) << " " << std::string(buf + start, i - start); + LOG(INFO) << std::setw(nest) << " " + << std::string(buf + start, i - start); } start = i; } @@ -166,6 +171,39 @@ static DebugLog debug_log_; static const int DEFAULT_PORT = 5222; +cricket::MediaEngine* CreateFileMediaEngine(const char* voice_in, + const char* voice_out, + const char* video_in, + const char* video_out) { + cricket::FileMediaEngine* file_media_engine = new cricket::FileMediaEngine; + // Set the RTP dump file names. + if (voice_in) { + file_media_engine->set_voice_input_filename(voice_in); + } + if (voice_out) { + file_media_engine->set_voice_output_filename(voice_out); + } + if (video_in) { + file_media_engine->set_video_input_filename(video_in); + } + if (video_out) { + file_media_engine->set_video_output_filename(video_out); + } + + // Set voice and video codecs. TODO: The codecs actually depend on + // the the input voice and video streams. + std::vector<cricket::AudioCodec> voice_codecs; + voice_codecs.push_back( + cricket::AudioCodec(9, "G722", 16000, 64000, 1, 0)); + file_media_engine->set_voice_codecs(voice_codecs); + std::vector<cricket::VideoCodec> video_codecs; + video_codecs.push_back( + cricket::VideoCodec(97, "H264", 320, 240, 30, 0)); + file_media_engine->set_video_codecs(video_codecs); + + return file_media_engine; +} + int main(int argc, char **argv) { // This app has three threads. The main thread will run the XMPP client, // which will print to the screen in its own thread. A second thread @@ -176,15 +214,24 @@ int main(int argc, char **argv) { // define options DEFINE_bool(a, false, "Turn on auto accept."); DEFINE_bool(d, false, "Turn on debugging."); - DEFINE_bool(filemedia, false, "Use File media"); DEFINE_bool(testserver, false, "Use test server"); DEFINE_int(portallocator, 0, "Filter out unwanted connection types."); DEFINE_string(filterhost, NULL, "Filter out the host from all candidates."); DEFINE_string(pmuc, "groupchat.google.com", "The persistant muc domain."); DEFINE_string(s, "talk.google.com", "The connection server to use."); + DEFINE_string(voiceinput, NULL, "RTP dump file for voice input."); + DEFINE_string(voiceoutput, NULL, "RTP dump file for voice output."); + DEFINE_string(videoinput, NULL, "RTP dump file for video input."); + DEFINE_string(videooutput, NULL, "RTP dump file for video output."); + DEFINE_bool(help, false, "Prints this message"); // parse options FlagList::SetFlagsFromCommandLine(&argc, argv, true); + if (FLAG_help) { + FlagList::Print(NULL, false); + return 0; + } + bool auto_accept = FLAG_a; bool debug = FLAG_d; bool test_server = FLAG_testserver; @@ -266,6 +313,17 @@ int main(int argc, char **argv) { XmppPump pump; CallClient *client = new CallClient(pump.client()); + if (FLAG_voiceinput || FLAG_voiceoutput || + FLAG_videoinput || FLAG_videooutput) { + // If any dump file is specified, we use FileMediaEngine. + cricket::MediaEngine* engine = CreateFileMediaEngine(FLAG_voiceinput, + FLAG_voiceoutput, + FLAG_videoinput, + FLAG_videooutput); + // The engine will be released by the client later. + client->SetMediaEngine(engine); + } + Console *console = new Console(main_thread, client); client->SetConsole(console); client->SetAutoAccept(auto_accept); diff --git a/third_party/libjingle/source/talk/examples/call/call_main.cc~ b/third_party/libjingle/source/talk/examples/call/call_main.cc~ new file mode 100644 index 0000000..fd7aafd --- /dev/null +++ b/third_party/libjingle/source/talk/examples/call/call_main.cc~ @@ -0,0 +1,348 @@ +/* + * libjingle + * Copyright 2004--2005, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <time.h> +#include <iomanip> +#include <cstdio> +#include <cstring> +#include <vector> +#include "talk/base/logging.h" +#include "talk/base/flags.h" +#include "talk/base/pathutils.h" +#include "talk/base/stream.h" +#include "talk/base/ssladapter.h" +#include "talk/base/win32socketserver.h" +#include "talk/xmpp/xmppclientsettings.h" +#include "talk/examples/login/xmppthread.h" +#include "talk/examples/login/xmppauth.h" +#include "talk/examples/login/xmpppump.h" +#include "talk/examples/call/callclient.h" +#include "talk/examples/call/console.h" +#include "talk/session/phone/filemediaengine.h" + +class DebugLog : public sigslot::has_slots<> { + public: + DebugLog() : + debug_input_buf_(NULL), debug_input_len_(0), debug_input_alloc_(0), + debug_output_buf_(NULL), debug_output_len_(0), debug_output_alloc_(0), + censor_password_(false) + {} + char * debug_input_buf_; + int debug_input_len_; + int debug_input_alloc_; + char * debug_output_buf_; + int debug_output_len_; + int debug_output_alloc_; + bool censor_password_; + + void Input(const char * data, int len) { + if (debug_input_len_ + len > debug_input_alloc_) { + char * old_buf = debug_input_buf_; + debug_input_alloc_ = 4096; + while (debug_input_alloc_ < debug_input_len_ + len) { + debug_input_alloc_ *= 2; + } + debug_input_buf_ = new char[debug_input_alloc_]; + memcpy(debug_input_buf_, old_buf, debug_input_len_); + delete[] old_buf; + } + memcpy(debug_input_buf_ + debug_input_len_, data, len); + debug_input_len_ += len; + DebugPrint(debug_input_buf_, &debug_input_len_, false); + } + + void Output(const char * data, int len) { + if (debug_output_len_ + len > debug_output_alloc_) { + char * old_buf = debug_output_buf_; + debug_output_alloc_ = 4096; + while (debug_output_alloc_ < debug_output_len_ + len) { + debug_output_alloc_ *= 2; + } + debug_output_buf_ = new char[debug_output_alloc_]; + memcpy(debug_output_buf_, old_buf, debug_output_len_); + delete[] old_buf; + } + memcpy(debug_output_buf_ + debug_output_len_, data, len); + debug_output_len_ += len; + DebugPrint(debug_output_buf_, &debug_output_len_, true); + } + + static bool IsAuthTag(const char * str, size_t len) { + if (str[0] == '<' && str[1] == 'a' && + str[2] == 'u' && + str[3] == 't' && + str[4] == 'h' && + str[5] <= ' ') { + std::string tag(str, len); + + if (tag.find("mechanism") != std::string::npos) + return true; + } + return false; + } + + void DebugPrint(char * buf, int * plen, bool output) { + int len = *plen; + if (len > 0) { + time_t tim = time(NULL); + struct tm * now = localtime(&tim); + char *time_string = asctime(now); + if (time_string) { + size_t time_len = strlen(time_string); + if (time_len > 0) { + time_string[time_len-1] = 0; // trim off terminating \n + } + } + LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<") + << " : " << time_string; + + bool indent; + int start = 0, nest = 3; + for (int i = 0; i < len; i += 1) { + if (buf[i] == '>') { + if ((i > 0) && (buf[i-1] == '/')) { + indent = false; + } else if ((start + 1 < len) && (buf[start + 1] == '/')) { + indent = false; + nest -= 2; + } else { + indent = true; + } + + // Output a tag + LOG(INFO) << std::setw(nest) << " " + << std::string(buf + start, i + 1 - start); + + if (indent) + nest += 2; + + // Note if it's a PLAIN auth tag + if (IsAuthTag(buf + start, i + 1 - start)) { + censor_password_ = true; + } + + // incr + start = i + 1; + } + + if (buf[i] == '<' && start < i) { + if (censor_password_) { + LOG(INFO) << std::setw(nest) << " " << "## TEXT REMOVED ##"; + censor_password_ = false; + } else { + LOG(INFO) << std::setw(nest) << " " + << std::string(buf + start, i - start); + } + start = i; + } + } + len = len - start; + memcpy(buf, buf + start, len); + *plen = len; + } + } +}; + +static DebugLog debug_log_; +static const int DEFAULT_PORT = 5222; + + +cricket::MediaEngine* CreateFileMediaEngine(const char* voice_in, + const char* voice_out, + const char* video_in, + const char* video_out) { + cricket::FileMediaEngine* file_media_engine = new cricket::FileMediaEngine; + // Set the RTP dump file names. + if (voice_in) { + file_media_engine->set_voice_input_filename(voice_in); + } + if (voice_out) { + file_media_engine->set_voice_output_filename(voice_out); + } + if (video_in) { + file_media_engine->set_video_input_filename(video_in); + } + if (video_out) { + file_media_engine->set_video_output_filename(video_out); + } + + // Set voice and video codecs. TODO: The codecs actually depend on + // the the input voice and video streams. + std::vector<cricket::AudioCodec> voice_codecs; + voice_codecs.push_back( + cricket::AudioCodec(9, "G722", 16000, 0, 1, 0)); + file_media_engine->set_voice_codecs(voice_codecs); + std::vector<cricket::VideoCodec> video_codecs; + video_codecs.push_back( + cricket::VideoCodec(97, "H264", 320, 240, 30, 0)); + file_media_engine->set_video_codecs(video_codecs); + + return file_media_engine; +} + +int main(int argc, char **argv) { + // This app has three threads. The main thread will run the XMPP client, + // which will print to the screen in its own thread. A second thread + // will get input from the console, parse it, and pass the appropriate + // message back to the XMPP client's thread. A third thread is used + // by MediaSessionClient as its worker thread. + + // define options + DEFINE_bool(a, false, "Turn on auto accept."); + DEFINE_bool(d, false, "Turn on debugging."); + DEFINE_bool(testserver, false, "Use test server"); + DEFINE_int(portallocator, 0, "Filter out unwanted connection types."); + DEFINE_string(filterhost, NULL, "Filter out the host from all candidates."); + DEFINE_string(pmuc, "groupchat.google.com", "The persistant muc domain."); + DEFINE_string(s, "talk.google.com", "The connection server to use."); + DEFINE_string(voiceinput, NULL, "RTP dump file for voice input."); + DEFINE_string(voiceoutput, NULL, "RTP dump file for voice output."); + DEFINE_string(videoinput, NULL, "RTP dump file for video input."); + DEFINE_string(videooutput, NULL, "RTP dump file for video output."); + DEFINE_bool(help, false, "Prints this message"); + + // parse options + FlagList::SetFlagsFromCommandLine(&argc, argv, true); + if (FLAG_help) { + FlagList::Print(NULL, false); + return 0; + } + + bool auto_accept = FLAG_a; + bool debug = FLAG_d; + bool test_server = FLAG_testserver; + int32 portallocator_flags = FLAG_portallocator; + std::string pmuc_domain = FLAG_pmuc; + std::string server = FLAG_s; + + // parse username and password, if present + buzz::Jid jid; + std::string username; + talk_base::InsecureCryptStringImpl pass; + if (argc > 1) { + username = argv[1]; + if (argc > 2) { + pass.password() = argv[2]; + } + } + + if (debug) + talk_base::LogMessage::LogToDebug(talk_base::LS_VERBOSE); + + if (username.empty()) { + std::cout << "JID: "; + std::cin >> username; + } + if (username.find('@') == std::string::npos) { + username.append("@localhost"); + } + jid = buzz::Jid(username); + if (!jid.IsValid() || jid.node() == "") { + printf("Invalid JID. JIDs should be in the form user@domain\n"); + return 1; + } + if (pass.password().empty() && !test_server) { + Console::SetEcho(false); + std::cout << "Password: "; + std::cin >> pass.password(); + Console::SetEcho(true); + std::cout << std::endl; + } + + buzz::XmppClientSettings xcs; + xcs.set_user(jid.node()); + xcs.set_resource("call"); + xcs.set_host(jid.domain()); + xcs.set_use_tls(!test_server); + + if (test_server) { + pass.password() = jid.node(); + xcs.set_allow_plain(true); + } + xcs.set_pass(talk_base::CryptString(pass)); + + std::string host; + int port; + + int colon = server.find(':'); + if (colon == -1) { + host = server; + port = DEFAULT_PORT; + } else { + host = server.substr(0, colon); + port = atoi(server.substr(colon + 1).c_str()); + } + + xcs.set_server(talk_base::SocketAddress(host, port)); + printf("Logging in to %s as %s\n", server.c_str(), jid.Str().c_str()); + + talk_base::InitializeSSL(); + + +#if WIN32 + // Need to pump messages on our main thread on Windows. + talk_base::Win32Thread w32_thread; + talk_base::ThreadManager::SetCurrent(&w32_thread); +#endif + talk_base::Thread* main_thread = talk_base::Thread::Current(); + + XmppPump pump; + CallClient *client = new CallClient(pump.client()); + + if (FLAG_voiceinput || FLAG_voiceoutput || + FLAG_videoinput || FLAG_videooutput) { + // If any dump file is specified, we use FileMediaEngine. + cricket::MediaEngine* engine = CreateFileMediaEngine(FLAG_voiceinput, + FLAG_voiceoutput, + FLAG_videoinput, + FLAG_videooutput); + // The engine will be released by the client later. + client->SetMediaEngine(engine); + } + + Console *console = new Console(main_thread, client); + client->SetConsole(console); + client->SetAutoAccept(auto_accept); + client->SetPmucDomain(pmuc_domain); + client->SetPortAllocatorFlags(portallocator_flags); + console->Start(); + + if (debug) { + pump.client()->SignalLogInput.connect(&debug_log_, &DebugLog::Input); + pump.client()->SignalLogOutput.connect(&debug_log_, &DebugLog::Output); + } + + pump.DoLogin(xcs, new XmppSocket(true), NULL); + main_thread->Run(); + pump.DoDisconnect(); + + console->Stop(); + delete console; + delete client; + + return 0; +} diff --git a/third_party/libjingle/source/talk/examples/call/callclient.cc b/third_party/libjingle/source/talk/examples/call/callclient.cc index 73ede99..03edf95 100644 --- a/third_party/libjingle/source/talk/examples/call/callclient.cc +++ b/third_party/libjingle/source/talk/examples/call/callclient.cc @@ -154,7 +154,7 @@ void CallClient::ParseLine(const std::string& line) { } } else if (call_) { if ((words.size() == 1) && (words[0] == "hangup")) { - // TODO(juberti): do more shutdown here, move to Terminate() + // TODO: do more shutdown here, move to Terminate() call_->Terminate(); call_ = NULL; session_ = NULL; @@ -163,6 +163,9 @@ void CallClient::ParseLine(const std::string& line) { call_->Mute(true); } else if ((words.size() == 1) && (words[0] == "unmute")) { call_->Mute(false); + } else if ((words.size() == 2) && (words[0] == "dtmf")) { + int ev = std::string("0123456789*#").find(words[1][0]); + call_->PressDTMF(ev); } else { console_->Print(CALL_COMMANDS); } @@ -292,7 +295,7 @@ void CallClient::InitPhone() { network_manager_ = new talk_base::NetworkManager(); - // TODO(juberti): Decide if the relay address should be specified here. + // TODO: Decide if the relay address should be specified here. talk_base::SocketAddress stun_addr("stun.l.google.com", 19302); port_allocator_ = new cricket::BasicPortAllocator(network_manager_, stun_addr, @@ -480,6 +483,10 @@ void CallClient::MakeCallTo(const std::string& name, bool video) { found_jid = mucs_.begin()->first; found = true; is_muc = true; + } else if (name[0] == '+') { + // if the first character is a +, assume it's a phone number + found_jid = callto_jid; + found = true; } else if (callto_jid.resource() == "voicemail") { // if the resource is /voicemail, allow that found_jid = callto_jid; @@ -535,7 +542,7 @@ void CallClient::PlaceCall(const buzz::Jid& jid, bool is_muc, bool video) { media_client_->SetFocus(call_); if (call_->video()) { call_->SetLocalRenderer(local_renderer_); - // TODO(tschmelcher): Call this once for every different remote SSRC + // TODO: Call this once for every different remote SSRC // once we get to testing multiway video. call_->SetVideoRenderer(session_, 0, remote_renderer_); } diff --git a/third_party/libjingle/source/talk/libjingle.scons b/third_party/libjingle/source/talk/libjingle.scons index ea5ed1a..09a3bc1 100644 --- a/third_party/libjingle/source/talk/libjingle.scons +++ b/third_party/libjingle/source/talk/libjingle.scons @@ -2,10 +2,7 @@ import talk Import("env") talk.Library(env, name = "expat", - CPPPATH = [ - "third_party/expat-2.0.1/", - ], - CPPDEFINES = [ + cppdefines = [ "XML_STATIC", ], srcs = [ @@ -13,6 +10,9 @@ talk.Library(env, name = "expat", "third_party/expat-2.0.1/lib/xmlrole.c", "third_party/expat-2.0.1/lib/xmltok.c", ], + includedirs = [ + "third_party/expat-2.0.1/", + ], win_cppdefines = [ "COMPILED_FROM_DSP", ], @@ -45,14 +45,14 @@ talk.Library(env, name = "libsrtp", "third_party/srtp/srtp/ekt.c", "third_party/srtp/srtp/srtp.c", ], + includedirs = [ + "third_party/srtp/include", + "third_party/srtp/crypto/include", + ], win_ccflags = [ "/wd4701", "/wd4702", ], - CPPPATH = [ - "third_party/srtp/include", - "third_party/srtp/crypto/include", - ], ) talk.Library(env, name = "libjingle", lin_srcs = [ @@ -71,7 +71,7 @@ talk.Library(env, name = "libjingle", "base/sslidentity.cc", "base/sslstreamadapter.cc", ], - CPPDEFINES = [ + cppdefines = [ "FEATURE_ENABLE_VOICEMAIL", "EXPAT_RELATIVE_PATH", "SRTP_RELATIVE_PATH", @@ -164,9 +164,11 @@ talk.Library(env, name = "libjingle", "session/phone/channelmanager.cc", "session/phone/codec.cc", "session/phone/devicemanager.cc", + "session/phone/filemediaengine.cc", "session/phone/mediaengine.cc", "session/phone/mediamonitor.cc", "session/phone/mediasessionclient.cc", + "session/phone/rtpdump.cc", "session/phone/soundclip.cc", "session/phone/srtpfilter.cc", "xmllite/qname.cc", @@ -187,6 +189,11 @@ talk.Library(env, name = "libjingle", "xmpp/xmppstanzaparser.cc", "xmpp/xmpptask.cc", ], + includedirs = [ + "third_party/expat-2.0.1/", + "third_party/srtp/include", + "third_party/srtp/crypto/include", + ], win_srcs = [ "base/schanneladapter.cc", "base/win32.cc", @@ -198,11 +205,6 @@ talk.Library(env, name = "libjingle", "base/winfirewall.cc", "base/winping.cc", ], - CPPPATH = [ - "third_party/expat-2.0.1/", - "third_party/srtp/include", - "third_party/srtp/crypto/include", - ], ) talk.App(env, name = "login", libs = [ @@ -234,7 +236,7 @@ talk.Library(env, name = "libxmpphelp", ], ) talk.App(env, name = "call", - mac_FRAMEWORKS = [ + mac_frameworks = [ "AudioToolbox", "AudioUnit", "Cocoa", @@ -255,7 +257,7 @@ talk.App(env, name = "call", "crypto", "ssl", ], - CPPDEFINES = [ + cppdefines = [ "FEATURE_ENABLE_VOICEMAIL", ], lin_libs = [ diff --git a/third_party/libjingle/source/talk/main.scons b/third_party/libjingle/source/talk/main.scons index 34895c6..d4163df 100644 --- a/third_party/libjingle/source/talk/main.scons +++ b/third_party/libjingle/source/talk/main.scons @@ -1,5 +1,4 @@ # -*- Python -*- -# This is the main file of the hammer/scons build for magicflute. # # All the helper functions are defined in: # - site_scons/talk.py @@ -15,8 +14,6 @@ # in the build. # # -# For more documentation and information check: -# https://sites.google.com/a/google.com/wavelet/Home/Magic-Flute--RTC-Engine- # import talk import os @@ -25,7 +22,7 @@ import os # The build files/directories to 'build'. # If the name is the name of a directory then that directory shall contain a # .scons file with the same name as the directory itself: -# Ex: The directory magicflute contains a file called magicflute.scons +# Ex: The directory session/phone contains a file called phone.scons # components = talk.Components("libjingle.scons") @@ -48,8 +45,7 @@ root_env = Environment( DESTINATION_ROOT = '$MAIN_DIR/build', CPPPATH = [ '$OBJ_ROOT', # generated headers are relative to here - '$MAIN_DIR/..', # TODO(dape): how can we use GOOGLECLIENT instead? - '$GOOGLE3', # google3 headers are relative to here + '$MAIN_DIR/..', # TODO: how can we use GOOGLECLIENT instead? ], CPPDEFINES = [ # Temp flag while porting to hammer. @@ -60,8 +56,6 @@ root_env = Environment( 'FEATURE_ENABLE_SSL', 'FEATURE_ENABLE_VOICEMAIL', 'FEATURE_ENABLE_PSTN', - 'HAVE_GIPS', - 'HAVE_LMI', 'HAVE_SRTP', ] ) @@ -72,7 +66,7 @@ root_env = Environment( win_env = root_env.Clone( tools = [ 'atlmfc_vc80', - 'code_signing', + #'code_signing', 'component_targets_msvs', 'directx_9_0_c', #'grid_builder', @@ -116,7 +110,7 @@ win_env.Append( ], CPPDEFINES = [ '_ATL_CSTRING_EXPLICIT_CONSTRUCTORS', - # TODO(dape): encapsulate all string operations that are not based + # TODO: encapsulate all string operations that are not based # on std::string/std::wstring and make sure we use the safest versions # available on all platforms. '_CRT_SECURE_NO_WARNINGS', @@ -126,7 +120,7 @@ win_env.Append( 'UNICODE', '_HAS_EXCEPTIONS=0', 'WIN32', - # TODO(dape): remove this from logging.cc and enable here instead. + # TODO: remove this from logging.cc and enable here instead. #'WIN32_LEAN_AND_MEAN', 'WINVER=0x0500', @@ -145,7 +139,7 @@ win_env.Append( '$PLATFORM_SDK_VISTA_6_0_DIR/Lib' ], LINKFLAGS = [ - '-manifest' # TODO(thaloun): Why do we need this? + '-manifest' # TODO: Why do we need this? ], MIDLFLAGS = [ '/win32', @@ -153,7 +147,7 @@ win_env.Append( ] ) -# TODO(dape): Figure out what this does; found it in +# TODO: Figure out what this does; found it in # omaha/main.scons. This fixes the problem with redefinition # of OS_WINDOWS symbol. win_env.FilterOut(CPPDEFINES = ['OS_WINDOWS=OS_WINDOWS']) @@ -260,7 +254,7 @@ mac_env.Append( # This flag makes all members of a static library be included in the # final exe - that increases the size of the exe, but without it # Obj-C categories aren't properly included in the exe. - # TODO(thaloun): consider only defining for libs that actually have objc. + # TODO: consider only defining for libs that actually have objc. '-ObjC', '-arch', 'i386', ], @@ -298,7 +292,7 @@ mac_opt_env = mac_env.Clone( ) mac_opt_env.Append( CCFLAGS = [ - # TODO(thaloun): Figure out how mk can compile without + # TODO: Figure out how mk can compile without # this flag, then remove. Confirmed asserts are preprocessed # out. Maybe it's a different version of gcc? '-Wno-unused-variable', @@ -321,7 +315,7 @@ linux_env.Append( # Also consider other linux flags: 64bit, no-strict-aliasing, wrap, etc ], LINKFLAGS = [ - # TODO(tschmelcher) consider enabling gc-sections. Perhaps only in opt. + # TODO consider enabling gc-sections. Perhaps only in opt. #'-Wl,--gc-sections', '-Wl,--start-group', ], @@ -344,75 +338,6 @@ linux_opt_env = linux_env.Clone( ) envs.append(linux_opt_env) -#------------------------------------------------------------------------------- -# L I N U X -- C H R O M E -- O S -# -linux_chromeos_env = linux_env.Clone( - AR = os.environ.get("AR"), - AS = os.environ.get("AS"), - LD = os.environ.get("LD"), - NM = os.environ.get("NM"), - RANLIB = os.environ.get("RANLIB"), - CC = str(os.environ.get("CC")) + - ' --sysroot=' + str(os.environ.get("SYSROOT")), - CXX = str(os.environ.get("CXX")) + - ' --sysroot=' + str(os.environ.get("SYSROOT")), -) - -linux_chromeos_env.Append( - CPPDEFINES = [ - 'CHROMEOS', - '__MMX__', - '__SSE__', - '__SSE2__', - 'USE_TALK_SOUND', - ], - - CPPPATH = [ - os.environ.get("CPPPATH"), - ], - - LIBPATH = [ - os.environ.get("LIBPATH"), - ], - - CCFLAGS = [ - os.environ.get("CCFLAGS"), - # ChromeOS devices for sure has MMX, SSE, and SSE2. - # So turning on -mmmx, -msse, and -msse2 without CPU detection should be - # safe. - '-mmmx', - '-msse', - '-msse2', - ], - - CXXFLAGS = [ - os.environ.get("CXXFLAGS"), - ], - - RPATH = [ - os.environ.get("RPATH"), - ], -) - -DeclareBit('linux_chromeos', 'Chrome OS ebuild') -linux_chromeos_env.SetBits('linux_chromeos') - -linux_chromeos_dbg_env = linux_chromeos_env.Clone( - BUILD_TYPE = 'chromeos-dbg', - BUILD_TYPE_DESCRIPTION = 'Chrome OS debug build', - BUILD_GROUPS = ['chromeos'], - tools = ['target_debug'] -) -envs.append(linux_chromeos_dbg_env) - -linux_chromeos_opt_env = linux_chromeos_env.Clone( - BUILD_TYPE = 'chromeos-opt', - BUILD_TYPE_DESCRIPTION = 'Chrome OS optimized build', - BUILD_GROUPS = ['chromeos'], - tools = ['target_optimized'] -) -envs.append(linux_chromeos_opt_env) # TODO(): Clone linux envs for 64bit. See 'variant' documentation. @@ -451,7 +376,8 @@ if win_env.Bit('vsproj'): # Source project p = vs_env.ComponentVSDirProject( 'flute_source', - ['$MAIN_DIR', '$GOOGLE3', '$THIRD_PARTY'], + ['$MAIN_DIR', + '$THIRD_PARTY'], COMPONENT_VS_SOURCE_FOLDERS = [ # Files are assigned to first matching folder. Folder names of None # are filters. @@ -468,7 +394,6 @@ if win_env.Bit('vsproj'): # Solution and target projects s = vs_env.ComponentVSSolution( - '../../flute', ['all_libraries', 'all_programs', 'all_test_programs'], projects = [p], ) @@ -479,4 +404,3 @@ if win_env.Bit('vsproj'): print '***($SolutionDir)/build/<foo>/staging/<bar>.exe' Default(None) Default([s]) - diff --git a/third_party/libjingle/source/talk/p2p/base/constants.cc b/third_party/libjingle/source/talk/p2p/base/constants.cc index 44ac86f..9e45457 100644 --- a/third_party/libjingle/source/talk/p2p/base/constants.cc +++ b/third_party/libjingle/source/talk/p2p/base/constants.cc @@ -29,17 +29,23 @@ namespace cricket { - const std::string NS_EMPTY(""); const std::string NS_JINGLE("urn:xmpp:jingle:1"); const std::string NS_GINGLE("http://www.google.com/session"); // actions (aka <session> or <jingle>) -const buzz::QName QN_INITIATOR(true, NS_EMPTY, "initiator"); const buzz::QName QN_ACTION(true, NS_EMPTY, "action"); +const std::string LN_INITIATOR("initiator"); +const buzz::QName QN_INITIATOR(true, NS_EMPTY, LN_INITIATOR); +const buzz::QName QN_CREATOR(true, NS_EMPTY, "creator"); -const buzz::QName QN_JINGLE_JINGLE(true, NS_JINGLE, "jingle"); +const buzz::QName QN_JINGLE(true, NS_JINGLE, "jingle"); const buzz::QName QN_JINGLE_CONTENT(true, NS_JINGLE, "content"); +const buzz::QName QN_JINGLE_CONTENT_NAME(true, NS_EMPTY, "name"); +const buzz::QName QN_JINGLE_CONTENT_MEDIA(true, NS_EMPTY, "media"); +const buzz::QName QN_JINGLE_REASON(true, NS_JINGLE, "reason"); +const std::string JINGLE_CONTENT_MEDIA_AUDIO("audio"); +const std::string JINGLE_CONTENT_MEDIA_VIDEO("video"); const std::string JINGLE_ACTION_SESSION_INITIATE("session-initiate"); const std::string JINGLE_ACTION_SESSION_INFO("session-info"); const std::string JINGLE_ACTION_SESSION_ACCEPT("session-accept"); @@ -67,7 +73,6 @@ const buzz::QName QN_CHANNELS(true, NS_EMPTY, "channels"); const buzz::QName QN_WIDTH(true, NS_EMPTY, "width"); const buzz::QName QN_HEIGHT(true, NS_EMPTY, "height"); const buzz::QName QN_FRAMERATE(true, NS_EMPTY, "framerate"); -const buzz::QName QN_PARAMETER(true, NS_EMPTY, "parameter"); const std::string LN_NAME("name"); const std::string LN_VALUE("value"); const buzz::QName QN_PAYLOADTYPE_PARAMETER_NAME(true, NS_EMPTY, LN_NAME); @@ -81,16 +86,12 @@ const std::string CN_AUDIO("audio"); const std::string CN_VIDEO("video"); const std::string CN_OTHER("main"); -const std::string NS_JINGLE_AUDIO("urn:xmpp:jingle:apps:rtp:audio"); -const buzz::QName QN_JINGLE_AUDIO_CONTENT( - true, NS_JINGLE_AUDIO, LN_DESCRIPTION); -const buzz::QName QN_JINGLE_AUDIO_PAYLOADTYPE( - true, NS_JINGLE_AUDIO, LN_PAYLOADTYPE); -const std::string NS_JINGLE_VIDEO("urn:xmpp:jingle:apps:rtp:video"); -const buzz::QName QN_JINGLE_VIDEO_CONTENT( - true, NS_JINGLE_VIDEO, LN_DESCRIPTION); -const buzz::QName QN_JINGLE_VIDEO_PAYLOADTYPE( - true, NS_JINGLE_VIDEO, LN_PAYLOADTYPE); +const std::string NS_JINGLE_RTP("urn:xmpp:jingle:apps:rtp:1"); +const buzz::QName QN_JINGLE_RTP_CONTENT( + true, NS_JINGLE_RTP, LN_DESCRIPTION); +const buzz::QName QN_JINGLE_RTP_PAYLOADTYPE( + true, NS_JINGLE_RTP, LN_PAYLOADTYPE); +const buzz::QName QN_PARAMETER(true, NS_JINGLE_RTP, "parameter"); const std::string NS_GINGLE_AUDIO("http://www.google.com/session/phone"); const buzz::QName QN_GINGLE_AUDIO_CONTENT( @@ -107,11 +108,8 @@ const buzz::QName QN_GINGLE_VIDEO_SRCID(true, NS_GINGLE_VIDEO, "src-id"); const buzz::QName QN_GINGLE_VIDEO_BANDWIDTH(true, NS_GINGLE_VIDEO, "bandwidth"); // transports and candidates -const std::string NS_JINGLE_P2P("urn:xmpp:jingle:transports:ice-udp:1"); const std::string LN_TRANSPORT("transport"); const std::string LN_CANDIDATE("candidate"); -const buzz::QName QN_JINGLE_P2P_TRANSPORT(true, NS_JINGLE_P2P, LN_TRANSPORT); -const buzz::QName QN_JINGLE_P2P_CANDIDATE(true, NS_JINGLE_P2P, LN_CANDIDATE); const buzz::QName QN_UFRAG(true, cricket::NS_EMPTY, "ufrag"); const buzz::QName QN_PWD(true, cricket::NS_EMPTY, "pwd"); const buzz::QName QN_COMPONENT(true, cricket::NS_EMPTY, "component"); @@ -126,13 +124,15 @@ const std::string JINGLE_CANDIDATE_TYPE_SERVER_STUN("srflx"); const std::string JINGLE_CANDIDATE_NAME_RTP("1"); const std::string JINGLE_CANDIDATE_NAME_RTCP("2"); +// TODO Once we are full ICE-UDP compliant, use this namespace. +// For now, just use the same as NS_GINGLE_P2P. +// const std::string NS_JINGLE_ICE_UDP("urn:xmpp:jingle:transports:ice-udp:1"); const std::string NS_GINGLE_P2P("http://www.google.com/transport/p2p"); const buzz::QName QN_GINGLE_P2P_TRANSPORT(true, NS_GINGLE_P2P, LN_TRANSPORT); -const buzz::QName QN_GINGLE2_P2P_CANDIDATE(true, NS_GINGLE_P2P, LN_CANDIDATE); -const buzz::QName QN_GINGLE_P2P_CANDIDATE(true, NS_GINGLE, LN_CANDIDATE); -const buzz::QName QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME(true, - NS_GINGLE_P2P, "unknown-channel-name"); -const buzz::QName QN_GINGLE_CANDIDATE(true, cricket::NS_GINGLE, "candidate"); +const buzz::QName QN_GINGLE_P2P_CANDIDATE(true, NS_GINGLE_P2P, LN_CANDIDATE); +const buzz::QName QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME( + true, NS_GINGLE_P2P, "unknown-channel-name"); +const buzz::QName QN_GINGLE_CANDIDATE(true, NS_GINGLE, LN_CANDIDATE); const buzz::QName QN_ADDRESS(true, cricket::NS_EMPTY, "address"); const buzz::QName QN_USERNAME(true, cricket::NS_EMPTY, "username"); const buzz::QName QN_PASSWORD(true, cricket::NS_EMPTY, "password"); @@ -143,10 +143,28 @@ const std::string GINGLE_CANDIDATE_NAME_RTCP("rtcp"); const std::string GINGLE_CANDIDATE_NAME_VIDEO_RTP("video_rtp"); const std::string GINGLE_CANDIDATE_NAME_VIDEO_RTCP("video_rtcp"); -const std::string NS_GINGLE_RAW("http://www.google.com/transport/raw-udp"); -const buzz::QName QN_GINGLE_RAW_TRANSPORT(true, NS_GINGLE_RAW, "transport"); -const buzz::QName QN_GINGLE_RAW_CHANNEL(true, NS_GINGLE_RAW, "channel"); - +// terminate reasons and errors +const std::string JINGLE_ERROR_BAD_REQUEST("bad-request"); +const std::string JINGLE_ERROR_OUT_OF_ORDER("out-of-order"); +const std::string JINGLE_ERROR_UNKNOWN_SESSION("unknown-session"); + +// Call terminate reasons from XEP-166 +const std::string STR_TERMINATE_DECLINE("decline"); +const std::string STR_TERMINATE_SUCCESS("success"); +const std::string STR_TERMINATE_ERROR("general-error"); +const std::string STR_TERMINATE_INCOMPATIBLE_PARAMETERS( + "incompatible-parameters"); + +// Old terminate reasons used by cricket +const std::string STR_TERMINATE_CALL_ENDED("call-ended"); +const std::string STR_TERMINATE_RECIPIENT_UNAVAILABLE("recipient-unavailable"); +const std::string STR_TERMINATE_RECIPIENT_BUSY("recipient-busy"); +const std::string STR_TERMINATE_INSUFFICIENT_FUNDS("insufficient-funds"); +const std::string STR_TERMINATE_NUMBER_MALFORMED("number-malformed"); +const std::string STR_TERMINATE_NUMBER_DISALLOWED("number-disallowed"); +const std::string STR_TERMINATE_PROTOCOL_ERROR("protocol-error"); +const std::string STR_TERMINATE_INTERNAL_SERVER_ERROR("internal-server-error"); +const std::string STR_TERMINATE_UNKNOWN_ERROR("unknown-error"); // old stuff #ifdef FEATURE_ENABLE_VOICEMAIL @@ -154,11 +172,4 @@ const std::string NS_VOICEMAIL("http://www.google.com/session/voicemail"); const buzz::QName QN_VOICEMAIL_REGARDING(true, NS_VOICEMAIL, "regarding"); #endif -/* Disabling redirect until we can implement it the "Jingle way". -const std::string GINGLE_ACTION_REDIRECT("redirect"); -const buzz::QName QN_REDIRECT_TARGET(true, NS_GINGLE_SESSION, "target"); -const buzz::QName QN_REDIRECT_COOKIE(true, NS_GINGLE_SESSION, "cookie"); -const buzz::QName QN_REDIRECT_REGARDING(true, NS_GINGLE_SESSION, "regarding"); -*/ - } // namespace cricket diff --git a/third_party/libjingle/source/talk/p2p/base/constants.h b/third_party/libjingle/source/talk/p2p/base/constants.h index edf200e..7e33c5b 100644 --- a/third_party/libjingle/source/talk/p2p/base/constants.h +++ b/third_party/libjingle/source/talk/p2p/base/constants.h @@ -53,21 +53,25 @@ extern const std::string NS_EMPTY; extern const std::string NS_JINGLE; extern const std::string NS_GINGLE; -// TODO(pthatcher): remove GINGLE2 when we -// move to purely Jingle and Gingle protocols. enum SignalingProtocol { PROTOCOL_JINGLE, PROTOCOL_GINGLE, - PROTOCOL_GINGLE2, PROTOCOL_HYBRID, }; // actions (aka Gingle <session> or Jingle <jingle>) -extern const buzz::QName QN_INITIATOR; extern const buzz::QName QN_ACTION; +extern const std::string LN_INITIATOR; +extern const buzz::QName QN_INITIATOR; +extern const buzz::QName QN_CREATOR; -extern const buzz::QName QN_JINGLE_JINGLE; +extern const buzz::QName QN_JINGLE; extern const buzz::QName QN_JINGLE_CONTENT; +extern const buzz::QName QN_JINGLE_CONTENT_NAME; +extern const buzz::QName QN_JINGLE_CONTENT_MEDIA; +extern const buzz::QName QN_JINGLE_REASON; +extern const std::string JINGLE_CONTENT_MEDIA_AUDIO; +extern const std::string JINGLE_CONTENT_MEDIA_VIDEO; extern const std::string JINGLE_ACTION_SESSION_INITIATE; extern const std::string JINGLE_ACTION_SESSION_INFO; extern const std::string JINGLE_ACTION_SESSION_ACCEPT; @@ -115,12 +119,9 @@ extern const std::string CN_AUDIO; extern const std::string CN_VIDEO; extern const std::string CN_OTHER; -extern const std::string NS_JINGLE_AUDIO; -extern const buzz::QName QN_JINGLE_AUDIO_CONTENT; -extern const buzz::QName QN_JINGLE_AUDIO_PAYLOADTYPE; -extern const std::string NS_JINGLE_VIDEO; -extern const buzz::QName QN_JINGLE_VIDEO_CONTENT; -extern const buzz::QName QN_JINGLE_VIDEO_PAYLOADTYPE; +extern const std::string NS_JINGLE_RTP; +extern const buzz::QName QN_JINGLE_RTP_CONTENT; +extern const buzz::QName QN_JINGLE_RTP_PAYLOADTYPE; extern const std::string NS_GINGLE_AUDIO; extern const buzz::QName QN_GINGLE_AUDIO_CONTENT; @@ -133,7 +134,6 @@ extern const buzz::QName QN_GINGLE_VIDEO_SRCID; extern const buzz::QName QN_GINGLE_VIDEO_BANDWIDTH; // transports and candidates -extern const std::string NS_JINGLE_P2P; extern const std::string LN_TRANSPORT; extern const std::string LN_CANDIDATE; extern const buzz::QName QN_JINGLE_P2P_TRANSPORT; @@ -154,7 +154,6 @@ extern const std::string JINGLE_CANDIDATE_NAME_RTCP; extern const std::string NS_GINGLE_P2P; extern const buzz::QName QN_GINGLE_P2P_TRANSPORT; -extern const buzz::QName QN_GINGLE2_P2P_CANDIDATE; extern const buzz::QName QN_GINGLE_P2P_CANDIDATE; extern const buzz::QName QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME; extern const buzz::QName QN_GINGLE_CANDIDATE; @@ -171,8 +170,29 @@ extern const std::string GINGLE_CANDIDATE_NAME_VIDEO_RTCP; extern const std::string NS_GINGLE_RAW; extern const buzz::QName QN_GINGLE_RAW_TRANSPORT; extern const buzz::QName QN_GINGLE_RAW_CHANNEL; -extern const buzz::QName QN_GINGLE_RAW_BEHIND_SYM_NAT; -extern const buzz::QName QN_GINGLE_RAW_CAN_RECEIVE_FROM_SYM_NAT; + +// terminate reasons and errors: see http://xmpp.org/extensions/xep-0166.html +extern const std::string JINGLE_ERROR_BAD_REQUEST; // like parse error +// got transport-info before session-initiate, for example +extern const std::string JINGLE_ERROR_OUT_OF_ORDER; +extern const std::string JINGLE_ERROR_UNKNOWN_SESSION; + +// Call terminate reasons from XEP-166 +extern const std::string STR_TERMINATE_DECLINE; // polite reject +extern const std::string STR_TERMINATE_SUCCESS; // polite hangup +extern const std::string STR_TERMINATE_ERROR; // something bad happened +extern const std::string STR_TERMINATE_INCOMPATIBLE_PARAMETERS; // no codecs? + +// Old terminate reasons used by cricket +extern const std::string STR_TERMINATE_CALL_ENDED; +extern const std::string STR_TERMINATE_RECIPIENT_UNAVAILABLE; +extern const std::string STR_TERMINATE_RECIPIENT_BUSY; +extern const std::string STR_TERMINATE_INSUFFICIENT_FUNDS; +extern const std::string STR_TERMINATE_NUMBER_MALFORMED; +extern const std::string STR_TERMINATE_NUMBER_DISALLOWED; +extern const std::string STR_TERMINATE_PROTOCOL_ERROR; +extern const std::string STR_TERMINATE_INTERNAL_SERVER_ERROR; +extern const std::string STR_TERMINATE_UNKNOWN_ERROR; // old stuff #ifdef FEATURE_ENABLE_VOICEMAIL diff --git a/third_party/libjingle/source/talk/p2p/base/p2ptransport.cc b/third_party/libjingle/source/talk/p2p/base/p2ptransport.cc index b360246..dd170ff 100644 --- a/third_party/libjingle/source/talk/p2p/base/p2ptransport.cc +++ b/third_party/libjingle/source/talk/p2p/base/p2ptransport.cc @@ -29,9 +29,11 @@ #include <string> #include <vector> + #include "talk/base/base64.h" #include "talk/base/common.h" -#include "talk/p2p/base/candidate.h" +#include "talk/base/stringencode.h" +#include "talk/base/stringutils.h" #include "talk/p2p/base/constants.h" #include "talk/p2p/base/p2ptransportchannel.h" #include "talk/p2p/base/parsing.h" @@ -50,9 +52,11 @@ const size_t kMaxUsernameSize = 16; namespace cricket { -P2PTransport::P2PTransport(talk_base::Thread* worker_thread, +P2PTransport::P2PTransport(talk_base::Thread* signaling_thread, + talk_base::Thread* worker_thread, PortAllocator* allocator) - : Transport(worker_thread, NS_GINGLE_P2P, allocator) { + : Transport(signaling_thread, worker_thread, + NS_GINGLE_P2P, allocator) { } P2PTransport::~P2PTransport() { @@ -61,7 +65,7 @@ P2PTransport::~P2PTransport() { void P2PTransport::OnTransportError(const buzz::XmlElement* error) { // Need to know if it was <unknown-channel name="xxx">. - ASSERT(error->Name().Namespace() == name()); + ASSERT(error->Name().Namespace() == type()); if ((error->Name() == QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME) && error->HasAttr(buzz::QN_NAME)) { std::string channel_name = error->Attr(buzz::QN_NAME); @@ -71,9 +75,13 @@ void P2PTransport::OnTransportError(const buzz::XmlElement* error) { } } -bool P2PTransport::ParseCandidates(const buzz::XmlElement* elem, - Candidates* candidates, - ParseError* error) { + +bool P2PTransportParser::ParseCandidates(SignalingProtocol protocol, + const buzz::XmlElement* elem, + Candidates* candidates, + ParseError* error) { + // TODO: Once we implement standard ICE-UDP, parse the + // candidates according to XEP-176. for (const buzz::XmlElement* candidate_elem = elem->FirstElement(); candidate_elem != NULL; candidate_elem = candidate_elem->NextElement()) { @@ -89,9 +97,9 @@ bool P2PTransport::ParseCandidates(const buzz::XmlElement* elem, return true; } -bool P2PTransport::ParseCandidate(const buzz::XmlElement* elem, - Candidate* candidate, - ParseError* error) { +bool P2PTransportParser::ParseCandidate(const buzz::XmlElement* elem, + Candidate* candidate, + ParseError* error) { if (!elem->HasAttr(buzz::QN_NAME) || !elem->HasAttr(QN_ADDRESS) || !elem->HasAttr(QN_PORT) || @@ -122,19 +130,11 @@ bool P2PTransport::ParseCandidate(const buzz::XmlElement* elem, if (!VerifyUsernameFormat(candidate->username(), error)) return false; - if (!HasChannel(candidate->name())) { - buzz::XmlElement* extra_info = - new buzz::XmlElement(QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME); - extra_info->AddAttr(buzz::QN_NAME, candidate->name()); - error->extra = extra_info; - return BadParse("channel named in candidate does not exist", error); - } - return true; } -bool P2PTransport::VerifyUsernameFormat(const std::string& username, - ParseError* error) { +bool P2PTransportParser::VerifyUsernameFormat(const std::string& username, + ParseError* error) { if (username.size() > kMaxUsernameSize) return BadParse("candidate username is too long", error); if (!talk_base::Base64::IsBase64Encoded(username)) @@ -144,21 +144,23 @@ bool P2PTransport::VerifyUsernameFormat(const std::string& username, } const buzz::QName& GetCandidateQName(SignalingProtocol protocol) { - if (protocol == PROTOCOL_GINGLE2) { - return QN_GINGLE2_P2P_CANDIDATE; + if (protocol == PROTOCOL_GINGLE) { + return QN_GINGLE_CANDIDATE; } else { + // TODO: Once we implement standard ICE-UDP, use the + // XEP-176 namespace. return QN_GINGLE_P2P_CANDIDATE; } } -bool P2PTransport::WriteCandidates(const Candidates& candidates, - SignalingProtocol protocol, - XmlElements* candidate_elems, - WriteError* error) { - for (std::vector<Candidate>::const_iterator - iter = candidates.begin(); - iter != candidates.end(); - ++iter) { +bool P2PTransportParser::WriteCandidates(SignalingProtocol protocol, + const Candidates& candidates, + XmlElements* candidate_elems, + WriteError* error) { + // TODO: Once we implement standard ICE-UDP, parse the + // candidates according to XEP-176. + for (std::vector<Candidate>::const_iterator iter = candidates.begin(); + iter != candidates.end(); ++iter) { buzz::XmlElement* cand_elem = new buzz::XmlElement(GetCandidateQName(protocol)); if (!WriteCandidate(*iter, cand_elem, error)) @@ -168,9 +170,9 @@ bool P2PTransport::WriteCandidates(const Candidates& candidates, return true; } -bool P2PTransport::WriteCandidate(const Candidate& candidate, - buzz::XmlElement* elem, - WriteError* error) { +bool P2PTransportParser::WriteCandidate(const Candidate& candidate, + buzz::XmlElement* elem, + WriteError* error) { elem->SetAttr(buzz::QN_NAME, candidate.name()); elem->SetAttr(QN_ADDRESS, candidate.address().IPAsString()); elem->SetAttr(QN_PORT, candidate.address().PortAsString()); diff --git a/third_party/libjingle/source/talk/p2p/base/p2ptransport.h b/third_party/libjingle/source/talk/p2p/base/p2ptransport.h index aaf154d..084f487 100644 --- a/third_party/libjingle/source/talk/p2p/base/p2ptransport.h +++ b/third_party/libjingle/source/talk/p2p/base/p2ptransport.h @@ -36,17 +36,11 @@ namespace cricket { class P2PTransport: public Transport { public: - P2PTransport(talk_base::Thread* worker_thread, PortAllocator* allocator); + P2PTransport(talk_base::Thread* signaling_thread, + talk_base::Thread* worker_thread, + PortAllocator* allocator); virtual ~P2PTransport(); - virtual bool ParseCandidates(const buzz::XmlElement* elem, - Candidates* candidates, - ParseError* error); - virtual bool WriteCandidates(const Candidates& candidates, - SignalingProtocol protocol, - XmlElements* candidate_elems, - WriteError* error); - virtual void OnTransportError(const buzz::XmlElement* error); protected: @@ -55,6 +49,22 @@ class P2PTransport: public Transport { const std::string& name, const std::string& content_type); virtual void DestroyTransportChannel(TransportChannelImpl* channel); + friend class P2PTransportChannel; + + DISALLOW_EVIL_CONSTRUCTORS(P2PTransport); +}; + +class P2PTransportParser : public TransportParser { + public: + P2PTransportParser() {} + virtual bool ParseCandidates(SignalingProtocol protocol, + const buzz::XmlElement* elem, + Candidates* candidates, + ParseError* error); + virtual bool WriteCandidates(SignalingProtocol protocol, + const Candidates& candidates, + XmlElements* candidate_elems, + WriteError* error); private: bool ParseCandidate(const buzz::XmlElement* elem, Candidate* candidate, @@ -65,9 +75,7 @@ class P2PTransport: public Transport { bool VerifyUsernameFormat(const std::string& username, ParseError* error); - friend class P2PTransportChannel; - - DISALLOW_EVIL_CONSTRUCTORS(P2PTransport); + DISALLOW_EVIL_CONSTRUCTORS(P2PTransportParser); }; } // namespace cricket diff --git a/third_party/libjingle/source/talk/p2p/base/parsing.h b/third_party/libjingle/source/talk/p2p/base/parsing.h index a932d9d..0ae7403 100644 --- a/third_party/libjingle/source/talk/p2p/base/parsing.h +++ b/third_party/libjingle/source/talk/p2p/base/parsing.h @@ -61,6 +61,10 @@ struct ParseError { // The error type for writing. struct WriteError { std::string text; + + void SetText(const std::string& text) { + this->text = text; + } }; // Convenience method for returning a message when parsing fails. diff --git a/third_party/libjingle/source/talk/p2p/base/port.h b/third_party/libjingle/source/talk/p2p/base/port.h index ffa8c89..88b15c6 100644 --- a/third_party/libjingle/source/talk/p2p/base/port.h +++ b/third_party/libjingle/source/talk/p2p/base/port.h @@ -79,7 +79,7 @@ class RateTracker { size_t total_bytes_; size_t bytes_second_; uint32 last_bytes_second_time_; - size_t last_bytes_second_calc_; + size_t last_bytes_second_calc_; }; // Represents a local communication mechanism that can be used to create @@ -106,8 +106,17 @@ class Port : public talk_base::MessageHandler, public sigslot::has_slots<> { // In order to establish a connection to this Port (so that real data can be // sent through), the other side must send us a STUN binding request that is // authenticated with this username and password. + // Fills in the username fragment and password. These will be initially set + // in the constructor to random values. Subclasses or tests can override. + // TODO: Change this to "username" rather than "username_fragment". const std::string& username_fragment() const { return username_frag_; } + void set_username_fragment(const std::string& username) { + username_frag_ = username; + } + const std::string& password() const { return password_; } + void set_password(const std::string& password) { password_ = password; } + // A value in [0,1] that indicates the preference for this port versus other // ports on this client. (Larger indicates more preference.) @@ -231,13 +240,6 @@ class Port : public talk_base::MessageHandler, public sigslot::has_slots<> { enum Lifetime { LT_PRESTART, LT_PRETIMEOUT, LT_POSTTIMEOUT } lifetime_; bool enable_port_packets_; - // Fills in the username fragment and password. These will be initially set - // in the constructor to random values. Subclasses can override, though. - void set_username_fragment(const std::string& username_fragment) { - username_frag_ = username_fragment; - } - void set_password(const std::string& password) { password_ = password; } - // Fills in the local address of the port. void AddAddress(const talk_base::SocketAddress& address, const std::string& protocol, bool final); diff --git a/third_party/libjingle/source/talk/p2p/base/rawtransport.cc b/third_party/libjingle/source/talk/p2p/base/rawtransport.cc index 0bcdd6a..b07d69c 100644 --- a/third_party/libjingle/source/talk/p2p/base/rawtransport.cc +++ b/third_party/libjingle/source/talk/p2p/base/rawtransport.cc @@ -40,16 +40,19 @@ #if defined(FEATURE_ENABLE_PSTN) namespace cricket { -RawTransport::RawTransport(talk_base::Thread* worker_thread, +RawTransport::RawTransport(talk_base::Thread* signaling_thread, + talk_base::Thread* worker_thread, PortAllocator* allocator) - : Transport(worker_thread, NS_GINGLE_RAW, allocator) { + : Transport(signaling_thread, worker_thread, + NS_GINGLE_RAW, allocator) { } RawTransport::~RawTransport() { DestroyAllChannels(); } -bool RawTransport::ParseCandidates(const buzz::XmlElement* elem, +bool RawTransport::ParseCandidates(SignalingProtocol protocol, + const buzz::XmlElement* elem, Candidates* candidates, ParseError* error) { ASSERT(elem->FirstChild() == NULL); @@ -70,8 +73,8 @@ bool RawTransport::ParseCandidates(const buzz::XmlElement* elem, return true; } -bool RawTransport::WriteCandidates(const Candidates& candidates, - SignalingProtocol protocol, +bool RawTransport::WriteCandidates(SignalingProtocol protocol, + const Candidates& candidates, XmlElements* candidate_elems, WriteError* error) { for (std::vector<Candidate>::const_iterator @@ -82,7 +85,7 @@ bool RawTransport::WriteCandidates(const Candidates& candidates, talk_base::SocketAddress addr = cand->address(); buzz::XmlElement* elem = new buzz::XmlElement(QN_GINGLE_RAW_CHANNEL); - elem->SetAttr(buzz::QN_NAME, name()); + elem->SetAttr(buzz::QN_NAME, type()); elem->SetAttr(QN_ADDRESS, addr.IPAsString()); elem->SetAttr(QN_PORT, addr.PortAsString()); candidate_elems->push_back(elem); diff --git a/third_party/libjingle/source/talk/p2p/base/rawtransport.h b/third_party/libjingle/source/talk/p2p/base/rawtransport.h index 09f715f..6734130 100644 --- a/third_party/libjingle/source/talk/p2p/base/rawtransport.h +++ b/third_party/libjingle/source/talk/p2p/base/rawtransport.h @@ -37,16 +37,19 @@ namespace cricket { // Implements a transport that only sends raw packets, no STUN. As a result, // it cannot do pings to determine connectivity, so it only uses a single port // that it thinks will work. -class RawTransport: public Transport { +class RawTransport: public Transport, public TransportParser { public: - RawTransport(talk_base::Thread* worker_thread, PortAllocator* allocator); + RawTransport(talk_base::Thread* signaling_thread, + talk_base::Thread* worker_thread, + PortAllocator* allocator); virtual ~RawTransport(); - virtual bool ParseCandidates(const buzz::XmlElement* elem, + virtual bool ParseCandidates(SignalingProtocol protocol, + const buzz::XmlElement* elem, Candidates* candidates, ParseError* error); - virtual bool WriteCandidates(const Candidates& candidates, - SignalingProtocol protocol, + virtual bool WriteCandidates(SignalingProtocol protocol, + const Candidates& candidates, XmlElements* candidate_elems, WriteError* error); diff --git a/third_party/libjingle/source/talk/p2p/base/relayport.cc b/third_party/libjingle/source/talk/p2p/base/relayport.cc index eaa5f73..ff6d55a 100644 --- a/third_party/libjingle/source/talk/p2p/base/relayport.cc +++ b/third_party/libjingle/source/talk/p2p/base/relayport.cc @@ -616,7 +616,7 @@ void RelayEntry::OnMessage(talk_base::Message *pmsg) { // the next address, otherwise give this connection more time and // await the real timeout. // - // TODO(oja): Connect to servers in pararel to speed up connect time + // TODO: Connect to servers in pararel to speed up connect time // and to avoid giving up to early. port_->SignalSoftTimeout(ra); HandleConnectFailure(current_connection_->socket()); diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver.cc b/third_party/libjingle/source/talk/p2p/base/relayserver.cc index 6ff0861..525da34 100644 --- a/third_party/libjingle/source/talk/p2p/base/relayserver.cc +++ b/third_party/libjingle/source/talk/p2p/base/relayserver.cc @@ -215,7 +215,7 @@ void RelayServer::OnInternalPacket( RelayServerConnection* ext_conn = int_conn->binding()->GetExternalConnection( int_conn->default_destination()); if (ext_conn && ext_conn->locked()) { - // TODO(juberti): Check the HMAC. + // TODO: Check the HMAC. ext_conn->Send(bytes, size); } else { // This happens very often and is not an error. @@ -234,7 +234,7 @@ void RelayServer::OnExternalPacket( // If this connection already exists, then forward the traffic. ConnectionMap::iterator piter = connections_.find(ap); if (piter != connections_.end()) { - // TODO(juberti): Check the HMAC. + // TODO: Check the HMAC. RelayServerConnection* ext_conn = piter->second; RelayServerConnection* int_conn = ext_conn->binding()->GetInternalConnection( @@ -265,7 +265,7 @@ void RelayServer::OnExternalPacket( uint32 length = talk_base::_min(static_cast<uint32>(username_attr->length()), USERNAME_LENGTH); std::string username(username_attr->bytes(), length); - // TODO(juberti): Check the HMAC. + // TODO: Check the HMAC. // The binding should already be present. BindingMap::iterator biter = bindings_.find(username); @@ -315,7 +315,7 @@ bool RelayServer::HandleStun( if (username) username->append(username_attr->bytes(), username_attr->length()); - // TODO(juberti): Check for unknown attributes (<= 0x7fff) + // TODO: Check for unknown attributes (<= 0x7fff) return true; } @@ -341,7 +341,7 @@ void RelayServer::HandleStunAllocate( return; } - // TODO(juberti): Check the HMAC. + // TODO: Check the HMAC. // Find or create the binding for this username. @@ -397,7 +397,7 @@ void RelayServer::HandleStun( return; } - // TODO(juberti): Check the HMAC. + // TODO: Check the HMAC. // Send this request to the appropriate handler. if (request.type() == STUN_SEND_REQUEST) @@ -440,9 +440,9 @@ void RelayServer::HandleStunAllocate( res_lifetime_attr->SetValue(int_conn->binding()->lifetime() / 1000); response.AddAttribute(res_lifetime_attr); - // TODO(juberti): Support transport-prefs (preallocate RTCP port). - // TODO(juberti): Support bandwidth restrictions. - // TODO(juberti): Add message integrity check. + // TODO: Support transport-prefs (preallocate RTCP port). + // TODO: Support bandwidth restrictions. + // TODO: Add message integrity check. // Send a response to the caller. int_conn->SendStun(response); diff --git a/third_party/libjingle/source/talk/p2p/base/session.cc b/third_party/libjingle/source/talk/p2p/base/session.cc index 6dc5a4b..806c025 100644 --- a/third_party/libjingle/source/talk/p2p/base/session.cc +++ b/third_party/libjingle/source/talk/p2p/base/session.cc @@ -29,6 +29,7 @@ #include "talk/base/common.h" #include "talk/base/logging.h" #include "talk/base/helpers.h" +#include "talk/base/scoped_ptr.h" #include "talk/xmpp/constants.h" #include "talk/xmpp/jid.h" #include "talk/p2p/base/sessionclient.h" @@ -51,12 +52,109 @@ namespace cricket { bool BadMessage(const buzz::QName type, const std::string& text, - SessionError* err) { + MessageError* err) { err->SetType(type); err->SetText(text); return false; } +TransportProxy::~TransportProxy() { + for (ChannelMap::iterator iter = channels_.begin(); + iter != channels_.end(); ++iter) { + iter->second->SignalDestroyed(iter->second); + delete iter->second; + } + delete transport_; +} + +std::string TransportProxy::type() const { + return transport_->type(); +} + +TransportChannel* TransportProxy::GetChannel(const std::string& name) { + return GetProxy(name); +} + +TransportChannel* TransportProxy::CreateChannel( + const std::string& name, const std::string& content_type) { + ASSERT(GetChannel(name) == NULL); + ASSERT(!transport_->HasChannel(name)); + + // We always create a proxy in case we need to change out the transport later. + TransportChannelProxy* channel = + new TransportChannelProxy(name, content_type); + channels_[name] = channel; + + if (state_ == STATE_NEGOTIATED) { + SetProxyImpl(name, channel); + } else if (state_ == STATE_CONNECTING) { + GetOrCreateImpl(name, content_type); + } + return channel; +} + +void TransportProxy::DestroyChannel(const std::string& name) { + TransportChannel* channel = GetChannel(name); + if (channel) { + channels_.erase(name); + channel->SignalDestroyed(channel); + delete channel; + } +} + +void TransportProxy::SpeculativelyConnectChannels() { + ASSERT(state_ == STATE_INIT || state_ == STATE_CONNECTING); + state_ = STATE_CONNECTING; + for (ChannelMap::iterator iter = channels_.begin(); + iter != channels_.end(); ++iter) { + GetOrCreateImpl(iter->first, iter->second->content_type()); + } + transport_->ConnectChannels(); +} + +void TransportProxy::CompleteNegotiation() { + if (state_ != STATE_NEGOTIATED) { + state_ = STATE_NEGOTIATED; + for (ChannelMap::iterator iter = channels_.begin(); + iter != channels_.end(); ++iter) { + SetProxyImpl(iter->first, iter->second); + } + transport_->ConnectChannels(); + } +} + +void TransportProxy::AddSentCandidates(const Candidates& candidates) { + for (Candidates::const_iterator cand = candidates.begin(); + cand != candidates.end(); ++cand) { + sent_candidates_.push_back(*cand); + } +} + + +TransportChannelProxy* TransportProxy::GetProxy(const std::string& name) { + ChannelMap::iterator iter = channels_.find(name); + return (iter != channels_.end()) ? iter->second : NULL; +} + +TransportChannelImpl* TransportProxy::GetOrCreateImpl( + const std::string& name, const std::string& content_type) { + TransportChannelImpl* impl = transport_->GetChannel(name); + if (impl == NULL) { + impl = transport_->CreateChannel(name, content_type); + } + return impl; +} + +void TransportProxy::SetProxyImpl( + const std::string& name, TransportChannelProxy* proxy) { + TransportChannelImpl* impl = GetOrCreateImpl(name, proxy->content_type()); + ASSERT(impl != NULL); + proxy->SetImplementation(impl); +} + + + + BaseSession::BaseSession(talk_base::Thread *signaling_thread) : state_(STATE_INIT), error_(ERROR_NONE), local_description_(NULL), remote_description_(NULL), @@ -95,8 +193,7 @@ void BaseSession::OnMessage(talk_base::Message *pmsg) { break; case MSG_ERROR: - // Any of the defined errors is most likely fatal. - Terminate(); + TerminateWithReason(STR_TERMINATE_ERROR); break; case MSG_STATE: @@ -108,6 +205,7 @@ void BaseSession::OnMessage(talk_base::Message *pmsg) { case STATE_SENTREJECT: case STATE_RECEIVEDREJECT: + // Assume clean termination. Terminate(); break; @@ -120,24 +218,28 @@ void BaseSession::OnMessage(talk_base::Message *pmsg) { } -Session::Session(SessionManager *session_manager, const std::string& name, - const SessionID& id, const std::string& content_type, +Session::Session(SessionManager *session_manager, + const std::string& local_name, + const std::string& initiator_name, + const std::string& sid, const std::string& content_type, SessionClient* client) : BaseSession(session_manager->signaling_thread()) { ASSERT(session_manager->signaling_thread()->IsCurrent()); ASSERT(client != NULL); session_manager_ = session_manager; - name_ = name; - id_ = id; + local_name_ = local_name; + sid_ = sid; + initiator_name_ = initiator_name; content_type_ = content_type; + // TODO: Once we support different transport types, + // don't hard code this here. + transport_type_ = NS_GINGLE_P2P; + transport_parser_ = new P2PTransportParser(); client_ = client; error_ = ERROR_NONE; state_ = STATE_INIT; initiator_ = false; - SetTransport(new P2PTransport(session_manager_->worker_thread(), - session_manager_->port_allocator())); - transport_negotiated_ = false; - current_protocol_ = PROTOCOL_GINGLE2; + current_protocol_ = PROTOCOL_HYBRID; } Session::~Session() { @@ -147,19 +249,33 @@ Session::~Session() { state_ = STATE_DEINIT; SignalState(this, state_); - for (ChannelMap::iterator iter = channels_.begin(); - iter != channels_.end(); - ++iter) { - iter->second->SignalDestroyed(iter->second); + for (TransportMap::iterator iter = transports_.begin(); + iter != transports_.end(); ++iter) { delete iter->second; } - delete transport_; + delete transport_parser_; +} + +Transport* Session::GetTransport(const std::string& content_name) { + TransportProxy* transproxy = GetTransportProxy(content_name); + if (transproxy == NULL) + return NULL; + return transproxy->impl(); +} + +void Session::set_allow_local_ips(bool allow) { + allow_local_ips_ = allow; + for (TransportMap::iterator iter = transports_.begin(); + iter != transports_.end(); ++iter) { + iter->second->impl()->set_allow_local_ips(allow); + } } bool Session::Initiate(const std::string &to, const SessionDescription* sdesc) { ASSERT(signaling_thread_->IsCurrent()); + SessionError error; // Only from STATE_INIT if (state_ != STATE_INIT) @@ -169,12 +285,20 @@ bool Session::Initiate(const std::string &to, remote_name_ = to; initiator_ = true; set_local_description(sdesc); + if (!CreateTransportProxies(GetEmptyTransportInfos(sdesc->contents()), + &error)) { + LOG(LS_ERROR) << "Could not create transports: " << error.text; + return false; + } + + if (!SendInitiateMessage(sdesc, &error)) { + LOG(LS_ERROR) << "Could not send initiate message: " << error.text; + return false; + } - SendInitiateMessage(sdesc); SetState(Session::STATE_SENTINITIATE); - // We speculatively start attempting connection of the P2P transports. - ConnectDefaultTransportChannels(transport_); + SpeculativelyConnectAllTransportChannels(); return true; } @@ -189,16 +313,17 @@ bool Session::Accept(const SessionDescription* sdesc) { initiator_ = false; set_local_description(sdesc); - // Wait for ChooseTransport to complete - if (!transport_negotiated_) - return true; + SessionError error; + if (!SendAcceptMessage(sdesc, &error)) { + LOG(LS_ERROR) << "Could not send accept message: " << error.text; + return false; + } - SendAcceptMessage(sdesc); SetState(Session::STATE_SENTACCEPT); return true; } -bool Session::Reject() { +bool Session::Reject(const std::string& reason) { ASSERT(signaling_thread_->IsCurrent()); // Reject is sent in response to an initiate or modify, to reject the @@ -209,13 +334,17 @@ bool Session::Reject() { // Setup for signaling. initiator_ = false; - SendRejectMessage(); - SetState(STATE_SENTREJECT); + SessionError error; + if (!SendRejectMessage(reason, &error)) { + LOG(LS_ERROR) << "Could not send reject message: " << error.text; + return false; + } + SetState(STATE_SENTREJECT); return true; } -bool Session::Terminate() { +bool Session::TerminateWithReason(const std::string& reason) { ASSERT(signaling_thread_->IsCurrent()); // Either side can terminate, at any time. @@ -231,7 +360,11 @@ bool Session::Terminate() { break; default: - SendTerminateMessage(); + SessionError error; + if (!SendTerminateMessage(reason, &error)) { + LOG(LS_ERROR) << "Could not send terminate message: " << error.text; + return false; + } break; } @@ -239,14 +372,61 @@ bool Session::Terminate() { return true; } -// only used by app/win32/fileshare.cc -void Session::SendInfoMessage(const XmlElements& elems) { +bool Session::SendInfoMessage(const XmlElements& elems) { ASSERT(signaling_thread_->IsCurrent()); - SendMessage(ACTION_SESSION_INFO, elems); + SessionError error; + if (!SendMessage(ACTION_SESSION_INFO, elems, &error)) { + LOG(LS_ERROR) << "Could not send info message " << error.text; + return false; + } + return true; +} + + +TransportProxy* Session::GetTransportProxy(const Transport* transport) { + for (TransportMap::iterator iter = transports_.begin(); + iter != transports_.end(); ++iter) { + TransportProxy* transproxy = iter->second; + if (transproxy->impl() == transport) { + return transproxy; + } + } + return NULL; } -void Session::SetTransport(Transport* transport) { - transport_ = transport; +TransportProxy* Session::GetTransportProxy(const std::string& content_name) { + TransportMap::iterator iter = transports_.find(content_name); + return (iter != transports_.end()) ? iter->second : NULL; +} + +TransportProxy* Session::GetFirstTransportProxy() { + if (transports_.empty()) + return NULL; + return transports_.begin()->second; +} + +TransportInfos Session::GetEmptyTransportInfos( + const ContentInfos& contents) const { + TransportInfos tinfos; + for (ContentInfos::const_iterator content = contents.begin(); + content != contents.end(); ++content) { + tinfos.push_back( + TransportInfo(content->name, transport_type_, Candidates())); + } + return tinfos; +} + +TransportProxy* Session::GetOrCreateTransportProxy( + const std::string& content_name) { + TransportProxy* transproxy = GetTransportProxy(content_name); + if (transproxy) + return transproxy; + + Transport* transport = + new P2PTransport(signaling_thread_, + session_manager_->worker_thread(), + session_manager_->port_allocator()); + transport->set_allow_local_ips(allow_local_ips_); transport->SignalConnecting.connect( this, &Session::OnTransportConnecting); transport->SignalWritableState.connect( @@ -259,41 +439,47 @@ void Session::SetTransport(Transport* transport) { this, &Session::OnTransportSendError); transport->SignalChannelGone.connect( this, &Session::OnTransportChannelGone); + + transproxy = new TransportProxy(content_name, transport); + transports_[content_name] = transproxy; + + return transproxy; } -void Session::ConnectDefaultTransportChannels(Transport* transport) { - for (ChannelMap::iterator iter = channels_.begin(); - iter != channels_.end(); - ++iter) { - ASSERT(!transport->HasChannel(iter->first)); - transport->CreateChannel(iter->first, content_type()); +bool Session::CreateTransportProxies(const TransportInfos& tinfos, + SessionError* error) { + for (TransportInfos::const_iterator tinfo = tinfos.begin(); + tinfo != tinfos.end(); ++tinfo) { + if (tinfo->transport_type != transport_type_) { + error->SetText("No supported transport in offer."); + return false; + } + + GetOrCreateTransportProxy(tinfo->content_name); } - transport->ConnectChannels(); + return true; } -void Session::ConnectTransportChannels(Transport* transport) { - ASSERT(signaling_thread_->IsCurrent()); - - // Create implementations for all of the channels if they don't exist. - for (ChannelMap::iterator iter = channels_.begin(); - iter != channels_.end(); - ++iter) { - TransportChannelProxy* channel = iter->second; - TransportChannelImpl* impl = transport->GetChannel(channel->name()); - if (impl == NULL) - impl = transport->CreateChannel(channel->name(), content_type()); - ASSERT(impl != NULL); - channel->SetImplementation(impl); +void Session::SpeculativelyConnectAllTransportChannels() { + for (TransportMap::iterator iter = transports_.begin(); + iter != transports_.end(); ++iter) { + iter->second->SpeculativelyConnectChannels(); } +} - // Have this transport start connecting if it is not already. - // (We speculatively connect the most common transport right away.) - transport->ConnectChannels(); +void Session::CompleteTransportNegotiations(const TransportInfos& transports) { + for (TransportInfos::const_iterator transport = transports.begin(); + transport != transports.end(); ++transport) { + TransportProxy* transproxy = GetTransportProxy(transport->content_name); + if (transproxy) { + transproxy->CompleteNegotiation(); + } + } } TransportParserMap Session::GetTransportParsers() { TransportParserMap parsers; - parsers[transport_->name()] = transport_; + parsers[transport_type_] = transport_parser_; return parsers; } @@ -303,45 +489,37 @@ ContentParserMap Session::GetContentParsers() { return parsers; } -TransportChannel* Session::CreateChannel(const std::string& name) { - ASSERT(channels_.find(name) == channels_.end()); - ASSERT(!transport_->HasChannel(name)); - - // We always create a proxy in case we need to change out the transport later. - TransportChannelProxy* channel = - new TransportChannelProxy(name, content_type_); - channels_[name] = channel; - - // If we've already decided on a transport, create the transport channel and - // tell the proxy to use it. - if (transport_negotiated_) { - channel->SetImplementation(transport_->CreateChannel(name, content_type_)); - // If we're in the process of initiating the session, the transport will - // be trying to connect its channels, so just add a new transport channel. - // When we decide on a transport, we'll hook it up to the new proxy. - } else if (state_ == STATE_SENTINITIATE) { - transport_->CreateChannel(name, content_type()); - } - return channel; +TransportChannel* Session::CreateChannel(const std::string& content_name, + const std::string& channel_name) { + // We create the proxy "on demand" here because we need to support + // creating channels at any time, even before we send or receive + // initiate messages, which is before we create the transports. + TransportProxy* transproxy = GetOrCreateTransportProxy(content_name); + return transproxy->CreateChannel(channel_name, content_type_); } -TransportChannel* Session::GetChannel(const std::string& name) { - ChannelMap::iterator iter = channels_.find(name); - return (iter != channels_.end()) ? iter->second : NULL; +TransportChannel* Session::GetChannel(const std::string& content_name, + const std::string& channel_name) { + TransportProxy* transproxy = GetTransportProxy(content_name); + if (transproxy == NULL) + return NULL; + else + return transproxy->GetChannel(channel_name); } -void Session::DestroyChannel(TransportChannel* channel) { - ChannelMap::iterator iter = channels_.find(channel->name()); - ASSERT(iter != channels_.end()); - ASSERT(channel == iter->second); - channels_.erase(iter); - channel->SignalDestroyed(channel); - delete channel; +void Session::DestroyChannel(const std::string& content_name, + const std::string& channel_name) { + TransportProxy* transproxy = GetTransportProxy(content_name); + ASSERT(transproxy != NULL); + transproxy->DestroyChannel(channel_name); } void Session::OnSignalingReady() { ASSERT(signaling_thread_->IsCurrent()); - transport_->OnSignalingReady(); + for (TransportMap::iterator iter = transports_.begin(); + iter != transports_.end(); ++iter) { + iter->second->impl()->OnSignalingReady(); + } } void Session::OnTransportConnecting(Transport* transport) { @@ -352,14 +530,12 @@ void Session::OnTransportConnecting(Transport* transport) { void Session::OnTransportWritable(Transport* transport) { ASSERT(signaling_thread_->IsCurrent()); - ASSERT(transport == transport_); // If the transport is not writable, start a timer to make sure that it // becomes writable within a reasonable amount of time. If it does not, we // terminate since we can't actually send data. If the transport is writable, // cancel the timer. Note that writability transitions may occur repeatedly // during the lifetime of the session. - signaling_thread_->Clear(this, MSG_TIMEOUT); if (transport->HasChannels() && !transport->writable()) { signaling_thread_->PostDelayed( @@ -375,14 +551,21 @@ void Session::OnTransportRequestSignaling(Transport* transport) { void Session::OnTransportCandidatesReady(Transport* transport, const Candidates& candidates) { ASSERT(signaling_thread_->IsCurrent()); - if (!transport_negotiated_) { - for (Candidates::const_iterator iter = candidates.begin(); - iter != candidates.end(); - ++iter) { - sent_candidates_.push_back(*iter); + TransportProxy* transproxy = GetTransportProxy(transport); + if (transproxy != NULL) { + if (!transproxy->negotiated()) { + transproxy->AddSentCandidates(candidates); + } + SessionError error; + if (!SendTransportInfoMessage( + TransportInfo(transproxy->content_name(), transproxy->type(), + candidates), + &error)) { + LOG(LS_ERROR) << "Could not send transport info message: " + << error.text; + return; } } - SendTransportInfoMessage(candidates); } void Session::OnTransportSendError(Transport* transport, @@ -405,26 +588,16 @@ void Session::OnIncomingMessage(const SessionMessage& msg) { ASSERT(signaling_thread_->IsCurrent()); ASSERT(state_ == STATE_INIT || msg.from == remote_name_); - // PROTOCOL_GINGLE is effectively the old compatibility_mode_ which - // meant "talking to old client". We can flip to - // compatibility_mode_, but not back. - if (msg.protocol == PROTOCOL_GINGLE) { - current_protocol_ = PROTOCOL_GINGLE; - } - - if (msg.type == ACTION_TRANSPORT_INFO && - current_protocol_ == PROTOCOL_GINGLE && - !transport_negotiated_) { - // We have sent some already (using transport-info), and we need - // to re-send them using the candidates message. - if (sent_candidates_.size() > 0) { - SendTransportInfoMessage(sent_candidates_); + if (current_protocol_== PROTOCOL_HYBRID) { + if (msg.protocol == PROTOCOL_GINGLE) { + current_protocol_ = PROTOCOL_GINGLE; + } else { + current_protocol_ = PROTOCOL_JINGLE; } - sent_candidates_.clear(); } bool valid = false; - SessionError error; + MessageError error; switch (msg.type) { case ACTION_SESSION_INITIATE: valid = OnInitiateMessage(msg, &error); @@ -468,8 +641,8 @@ void Session::OnFailedSend(const buzz::XmlElement* orig_stanza, SessionMessage msg; ParseError parse_error; if (!ParseSessionMessage(orig_stanza, &msg, &parse_error)) { - LOG(LERROR) << "Error parsing failed send: " << parse_error.text - << ":" << orig_stanza; + LOG(LS_ERROR) << "Error parsing failed send: " << parse_error.text + << ":" << orig_stanza; return; } @@ -481,8 +654,8 @@ void Session::OnFailedSend(const buzz::XmlElement* orig_stanza, ASSERT(error->HasAttr(buzz::QN_TYPE)); error_type = error->Attr(buzz::QN_TYPE); - LOG(LERROR) << "Session error:\n" << error->Str() << "\n" - << "in response to:\n" << orig_stanza->Str(); + LOG(LS_ERROR) << "Session error:\n" << error->Str() << "\n" + << "in response to:\n" << orig_stanza->Str(); } if (msg.type == ACTION_TRANSPORT_INFO) { @@ -491,10 +664,15 @@ void Session::OnFailedSend(const buzz::XmlElement* orig_stanza, // errors, because if we do not establish writability again, we will // terminate anyway. The exceptions are transport-specific error tags, // which we pass on to the respective transport. + + // TODO: This is only used for unknown channel name. + // For Jingle, find a stanard-compliant way of doing this. For + // Gingle, guess the content name based on the channel name. for (const buzz::XmlElement* elem = error->FirstElement(); NULL != elem; elem = elem->NextElement()) { - if (transport_->name() == elem->Name().Namespace()) { - transport_->OnTransportError(elem); + TransportProxy* transproxy = GetFirstTransportProxy(); + if (transproxy && transproxy->type() == error->Name().Namespace()) { + transproxy->impl()->OnTransportError(elem); } } } else if ((error_type != "continue") && (error_type != "wait")) { @@ -505,59 +683,60 @@ void Session::OnFailedSend(const buzz::XmlElement* orig_stanza, } bool Session::OnInitiateMessage(const SessionMessage& msg, - SessionError* error) { + MessageError* error) { if (!CheckState(STATE_INIT, error)) return false; SessionInitiate init; - if (!ParseSessionInitiate(msg.action_elem, GetContentParsers(), &init, error)) + if (!ParseSessionInitiate(msg.protocol, msg.action_elem, + GetContentParsers(), GetTransportParsers(), + &init, error)) return false; - if (transport_->name() != init.transport_name) + SessionError session_error; + if (!CreateTransportProxies(init.transports, &session_error)) { return BadMessage(buzz::QN_STANZA_NOT_ACCEPTABLE, - "no supported transport in offer", - error); + session_error.text, error); + } initiator_ = false; remote_name_ = msg.from; - set_remote_description(new SessionDescription(init.AdoptContents())); + set_remote_description(new SessionDescription(init.ClearContents())); SetState(STATE_RECEIVEDINITIATE); // Users of Session may listen to state change and call Reject(). - if (state_ != STATE_SENTREJECT && !transport_negotiated_) { - transport_negotiated_ = true; - ConnectTransportChannels(transport_); - - // If the user wants to accept, allow that now - if (local_description_) { - Accept(local_description_); - } + if (state_ != STATE_SENTREJECT) { + // TODO: Jingle spec allows candidates to be in the + // initiate. We should support receiving them. + CompleteTransportNegotiations(init.transports); } return true; } -bool Session::OnAcceptMessage(const SessionMessage& msg, SessionError* error) { +bool Session::OnAcceptMessage(const SessionMessage& msg, MessageError* error) { if (!CheckState(STATE_SENTINITIATE, error)) return false; SessionAccept accept; - if (!ParseSessionAccept(msg.action_elem, GetContentParsers(), &accept, error)) + if (!ParseSessionAccept(msg.protocol, msg.action_elem, + GetContentParsers(), GetTransportParsers(), + &accept, error)) return false; - set_remote_description(new SessionDescription(accept.AdoptContents())); + set_remote_description(new SessionDescription(accept.ClearContents())); SetState(STATE_RECEIVEDACCEPT); - // Users of Session may listen to state change and call Reject(). - if (state_ != STATE_SENTREJECT && !transport_negotiated_) { - transport_negotiated_ = true; - ConnectTransportChannels(transport_); + if (state_ != STATE_SENTREJECT) { + // TODO: Jingle spec allows candidates to be in the + // accept. We should support receiving them. + CompleteTransportNegotiations(accept.transports); } return true; } -bool Session::OnRejectMessage(const SessionMessage& msg, SessionError* error) { +bool Session::OnRejectMessage(const SessionMessage& msg, MessageError* error) { if (!CheckState(STATE_SENTINITIATE, error)) return false; @@ -572,9 +751,9 @@ bool Session::OnInfoMessage(const SessionMessage& msg) { } bool Session::OnTerminateMessage(const SessionMessage& msg, - SessionError* error) { + MessageError* error) { SessionTerminate term; - if (!ParseSessionTerminate(msg.action_elem, &term, error)) + if (!ParseSessionTerminate(msg.protocol, msg.action_elem, &term, error)) return false; SignalReceivedTerminateReason(this, term.reason); @@ -587,29 +766,50 @@ bool Session::OnTerminateMessage(const SessionMessage& msg, } bool Session::OnTransportInfoMessage(const SessionMessage& msg, - SessionError* error) { - TransportInfo info; - if (!ParseTransportInfo(msg.action_elem, GetTransportParsers(), &info, error)) + MessageError* error) { + TransportInfos tinfos; + if (!ParseTransportInfos(msg.protocol, msg.action_elem, + initiator_description()->contents(), + GetTransportParsers(), &tinfos, error)) return false; - if (transport_->name() == info.transport_name) { - transport_->OnRemoteCandidates(info.candidates); - if (!transport_negotiated_) { - transport_negotiated_ = true; - ConnectTransportChannels(transport_); + for (TransportInfos::iterator tinfo = tinfos.begin(); + tinfo != tinfos.end(); ++tinfo) { + TransportProxy* transproxy = GetTransportProxy(tinfo->content_name); + if (transproxy == NULL) + return BadParse("Unknown content name: " + tinfo->content_name, error); + + for (Candidates::const_iterator cand = tinfo->candidates.begin(); + cand != tinfo->candidates.end(); ++cand) { + if (!transproxy->impl()->VerifyCandidate(*cand, error)) + return false; + + if (!transproxy->impl()->HasChannel(cand->name())) { + buzz::XmlElement* extra_info = + new buzz::XmlElement(QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME); + extra_info->AddAttr(buzz::QN_NAME, cand->name()); + error->extra = extra_info; + return BadParse("channel named in candidate does not exist: " + + cand->name() + " for content: "+ tinfo->content_name, + error); + } } + + transproxy->impl()->OnRemoteCandidates(tinfo->candidates); + transproxy->CompleteNegotiation(); } + return true; } bool Session::OnTransportAcceptMessage(const SessionMessage& msg, - SessionError* error) { - // TODO(pthatcher): Currently here only for compatibility with + MessageError* error) { + // TODO: Currently here only for compatibility with // Gingle 1.1 clients (notably, Google Voice). return true; } -bool Session::CheckState(State state, SessionError* error) { +bool Session::CheckState(State state, MessageError* error) { ASSERT(state_ == state); if (state_ != state) { return BadMessage(buzz::QN_STANZA_NOT_ALLOWED, @@ -641,57 +841,128 @@ void Session::OnMessage(talk_base::Message *pmsg) { } } -void Session::SendInitiateMessage(const SessionDescription* sdesc) { - SessionInitiate init(transport_->name(), sdesc->contents()); - XmlElements elems; - // TODO(pthatcher): Handle write errors. - WriteError error; - WriteSessionInitiate(init, GetContentParsers(), current_protocol_, - &elems, &error); - SendMessage(ACTION_SESSION_INITIATE, elems); +bool Session::SendInitiateMessage(const SessionDescription* sdesc, + SessionError* error) { + SessionInitiate init; + init.contents = sdesc->contents(); + init.transports = GetEmptyTransportInfos(init.contents); + return SendMessage(ACTION_SESSION_INITIATE, init, error); } -void Session::SendAcceptMessage(const SessionDescription* sdesc) { - // TODO(pthatcher): When we support the Jingle standard, we need to - // include at least an empty <transport> in the accept. - std::string transport_name = ""; - SessionAccept accept(transport_name, sdesc->contents()); +bool Session::WriteSessionAction( + SignalingProtocol protocol, const SessionInitiate& init, + XmlElements* elems, WriteError* error) { + ContentParserMap content_parsers = GetContentParsers(); + TransportParserMap trans_parsers = GetTransportParsers(); - XmlElements elems; - // TODO(pthatcher): Handle write errors. - WriteError error; - WriteSessionAccept(accept, GetContentParsers(), &elems, &error); - SendMessage(ACTION_SESSION_ACCEPT, elems); + return WriteSessionInitiate(protocol, init.contents, init.transports, + content_parsers, trans_parsers, + elems, error); } -void Session::SendRejectMessage() { +bool Session::SendAcceptMessage(const SessionDescription* sdesc, + SessionError* error) { XmlElements elems; - SendMessage(ACTION_SESSION_REJECT, elems); + if (!WriteSessionAccept(current_protocol_, + sdesc->contents(), + GetEmptyTransportInfos(sdesc->contents()), + GetContentParsers(), GetTransportParsers(), + &elems, error)) { + return false; + } + return SendMessage(ACTION_SESSION_ACCEPT, elems, error); } -void Session::SendTerminateMessage() { +bool Session::SendRejectMessage(const std::string& reason, + SessionError* error) { XmlElements elems; - SendMessage(ACTION_SESSION_TERMINATE, elems); + return SendMessage(ACTION_SESSION_REJECT, elems, error); } -void Session::SendTransportInfoMessage(const Candidates& candidates) { - TransportInfo info(transport_->name(), candidates); - XmlElements elems; - // TODO(pthatcher): Handle write errors. - WriteError error; - WriteTransportInfo(info, GetTransportParsers(), current_protocol_, - &elems, &error); - SendMessage(ACTION_TRANSPORT_INFO, elems); + +bool Session::SendTerminateMessage(const std::string& reason, + SessionError* error) { + SessionTerminate term(reason); + return SendMessage(ACTION_SESSION_TERMINATE, term, error); } -void Session::SendMessage(ActionType type, const XmlElements& action_elems) { - SessionMessage msg(current_protocol_, type, id_.id_str(), id_.initiator()); - msg.to = remote_name_; +bool Session::WriteSessionAction(SignalingProtocol protocol, + const SessionTerminate& term, + XmlElements* elems, WriteError* error) { + WriteSessionTerminate(protocol, term, elems); + return true; +} + +bool Session::SendTransportInfoMessage(const TransportInfo& tinfo, + SessionError* error) { + return SendMessage(ACTION_TRANSPORT_INFO, tinfo, error); +} + +bool Session::WriteSessionAction(SignalingProtocol protocol, + const TransportInfo& tinfo, + XmlElements* elems, WriteError* error) { + TransportInfos tinfos; + tinfos.push_back(tinfo); + TransportParserMap parsers = GetTransportParsers(); + return WriteTransportInfos(protocol, tinfos, parsers, + elems, error); +} + +bool Session::SendMessage(ActionType type, const XmlElements& action_elems, + SessionError* error) { talk_base::scoped_ptr<buzz::XmlElement> stanza( new buzz::XmlElement(buzz::QN_IQ)); + + SessionMessage msg(current_protocol_, type, sid_, initiator_name_); + msg.to = remote_name_; WriteSessionMessage(msg, action_elems, stanza.get()); + SignalOutgoingMessage(this, stanza.get()); + return true; +} + +template <typename Action> +bool Session::SendMessage(ActionType type, const Action& action, + SessionError* error) { + talk_base::scoped_ptr<buzz::XmlElement> stanza( + new buzz::XmlElement(buzz::QN_IQ)); + if (!WriteActionMessage(type, action, stanza.get(), error)) + return false; + + SignalOutgoingMessage(this, stanza.get()); + return true; +} + +template <typename Action> +bool Session::WriteActionMessage(ActionType type, const Action& action, + buzz::XmlElement* stanza, + WriteError* error) { + if (current_protocol_ == PROTOCOL_HYBRID) { + if (!WriteActionMessage(PROTOCOL_JINGLE, type, action, stanza, error)) + return false; + if (!WriteActionMessage(PROTOCOL_GINGLE, type, action, stanza, error)) + return false; + } else { + if (!WriteActionMessage(current_protocol_, type, action, stanza, error)) + return false; + } + return true; +} + +template <typename Action> +bool Session::WriteActionMessage(SignalingProtocol protocol, + ActionType type, const Action& action, + buzz::XmlElement* stanza, WriteError* error) { + XmlElements action_elems; + if (!WriteSessionAction(protocol, action, &action_elems, error)) + return false; + + SessionMessage msg(protocol, type, sid_, initiator_name_); + msg.to = remote_name_; + + WriteSessionMessage(msg, action_elems, stanza); + return true; } void Session::SendAcknowledgementMessage(const buzz::XmlElement* stanza) { diff --git a/third_party/libjingle/source/talk/p2p/base/session.h b/third_party/libjingle/source/talk/p2p/base/session.h index 181b63b..64bb83a 100644 --- a/third_party/libjingle/source/talk/p2p/base/session.h +++ b/third_party/libjingle/source/talk/p2p/base/session.h @@ -37,7 +37,6 @@ #include "talk/p2p/base/sessionmanager.h" #include "talk/base/socketaddress.h" #include "talk/p2p/base/sessionclient.h" -#include "talk/p2p/base/sessionid.h" #include "talk/p2p/base/parsing.h" #include "talk/p2p/base/port.h" #include "talk/xmllite/xmlelement.h" @@ -53,20 +52,80 @@ class TransportChannel; class TransportChannelProxy; class TransportChannelImpl; -// We add "type" to the errors because it's need for +// Used for errors that will send back a specific error message to the +// remote peer. We add "type" to the errors because it's needed for // SignalErrorMessage. -struct SessionError : ParseError { +struct MessageError : ParseError { buzz::QName type; // if unset, assume type is a parse error - SessionError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {} + MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {} void SetType(const buzz::QName type) { this->type = type; } }; -// TODO(juberti): Consider simplifying the dependency from Voice/VideoChannel +// Used for errors that may be returned by public session methods that +// can fail. +// TODO: Use this error in Session::Initiate and +// Session::Accept. +struct SessionError : WriteError { +}; + +// Bundles a Transport and ChannelMap together. ChannelMap is used to +// create transport channels before receiving or sending a session +// initiate, and for speculatively connecting channels. Previously, a +// session had one ChannelMap and transport. Now, with multiple +// transports per session, we need multiple ChannelMaps as well. +class TransportProxy { + public: + TransportProxy(const std::string& content_name, Transport* transport) + : content_name_(content_name), + transport_(transport), + state_(STATE_INIT), + sent_candidates_(false) {} + ~TransportProxy(); + + std::string content_name() const { return content_name_; } + Transport* impl() const { return transport_; } + std::string type() const; + bool negotiated() const { return state_ == STATE_NEGOTIATED; } + const Candidates& sent_candidates() const { return sent_candidates_; } + + TransportChannel* GetChannel(const std::string& name); + TransportChannel* CreateChannel(const std::string& name, + const std::string& content_type); + void DestroyChannel(const std::string& name); + void AddSentCandidates(const Candidates& candidates); + void ClearSentCandidates() { sent_candidates_.clear(); } + void SpeculativelyConnectChannels(); + void CompleteNegotiation(); + + private: + enum TransportState { + STATE_INIT, + STATE_CONNECTING, + STATE_NEGOTIATED + }; + + typedef std::map<std::string, TransportChannelProxy*> ChannelMap; + + TransportChannelProxy* GetProxy(const std::string& name); + TransportChannelImpl* GetOrCreateImpl(const std::string& name, + const std::string& content_type); + void SetProxyImpl(const std::string& name, TransportChannelProxy* proxy); + + std::string content_name_; + Transport* transport_; + TransportState state_; + ChannelMap channels_; + Candidates sent_candidates_; +}; + +typedef std::map<std::string, TransportProxy*> TransportMap; + +// TODO: Consider simplifying the dependency from Voice/VideoChannel // on Session. Right now the Channel class requires a BaseSession, but it only // uses CreateChannel/DestroyChannel. Perhaps something like a // TransportChannelFactory could be hoisted up out of BaseSession, or maybe @@ -128,16 +187,25 @@ class BaseSession : public sigslot::has_slots<>, Error error() const { return error_; } sigslot::signal2<BaseSession *, Error> SignalError; - // Creates a new channel with the given name. This method may be called + // Creates a new channel with the given names. This method may be called // immediately after creating the session. However, the actual // implementation may not be fixed until transport negotiation completes. - virtual TransportChannel* CreateChannel(const std::string& name) = 0; - - // Returns the channel with the given name. - virtual TransportChannel* GetChannel(const std::string& name) = 0; - - // Destroys the given channel. - virtual void DestroyChannel(TransportChannel* channel) = 0; + // This will usually be called from the worker thread, but that + // shouldn't be an issue since the main thread will be blocked in + // Send when doing so. + virtual TransportChannel* CreateChannel(const std::string& content_name, + const std::string& channel_name) = 0; + + // Returns the channel with the given names. + virtual TransportChannel* GetChannel(const std::string& content_name, + const std::string& channel_name) = 0; + + // Destroys the channel with the given names. + // This will usually be called from the worker thread, but that + // shouldn't be an issue since the main thread will be blocked in + // Send when doing so. + virtual void DestroyChannel(const std::string& content_name, + const std::string& channel_name) = 0; // Invoked when we notice that there is no matching channel on our peer. sigslot::signal2<Session*, const std::string&> SignalChannelGone; @@ -174,19 +242,20 @@ class BaseSession : public sigslot::has_slots<>, // RECEIVEDINITIATE state and respond by accepting or rejecting. // Takes ownership of session description. virtual bool Accept(const SessionDescription* sdesc) = 0; - virtual bool Reject() = 0; - - // At any time, we may terminate an outstanding session. - virtual bool Terminate() = 0; + virtual bool Reject(const std::string& reason) = 0; + bool Terminate() { + return TerminateWithReason(STR_TERMINATE_SUCCESS); + } + virtual bool TerminateWithReason(const std::string& reason) = 0; // The worker thread used by the session manager virtual talk_base::Thread *worker_thread() = 0; // Returns the JID of this client. - const std::string &name() const { return name_; } + const std::string& local_name() const { return local_name_; } // Returns the JID of the other peer in this session. - const std::string &remote_name() const { return remote_name_; } + const std::string& remote_name() const { return remote_name_; } // Set the JID of the other peer in this session. // Typically the remote_name_ is set when the session is initiated. @@ -195,20 +264,18 @@ class BaseSession : public sigslot::has_slots<>, // explicitly. void set_remote_name(const std::string& name) { remote_name_ = name; } - // Holds the ID of this session, which should be unique across the world. - const SessionID& id() const { return id_; } + const std::string& id() const { return sid_; } protected: State state_; Error error_; const SessionDescription* local_description_; const SessionDescription* remote_description_; - SessionID id_; + std::string sid_; // We don't use buzz::Jid because changing to buzz:Jid here has a // cascading effect that requires an enormous number places to // change to buzz::Jid as well. - std::string name_; - + std::string local_name_; std::string remote_name_; talk_base::Thread *signaling_thread_; }; @@ -230,89 +297,98 @@ class Session : public BaseSession { // Returns the client that is handling the application data of this session. SessionClient* client() const { return client_; } + SignalingProtocol current_protocol() const { return current_protocol_; } + + void set_current_protocol(SignalingProtocol protocol) { + current_protocol_ = protocol; + } + // Indicates whether we initiated this session. bool initiator() const { return initiator_; } + const SessionDescription* initiator_description() const { + if (initiator_) { + return local_description_; + } else { + return remote_description_; + } + } + // Fired whenever we receive a terminate message along with a reason sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason; - // Returns the transport that has been negotiated or NULL if negotiation is - // still in progress. - Transport* transport() const { return transport_; } + void set_allow_local_ips(bool allow); + + // Returns the transport that has been negotiated or NULL if + // negotiation is still in progress. + Transport* GetTransport(const std::string& content_name); // Takes ownership of session description. + // TODO: Add an error argument to pass back to the caller. bool Initiate(const std::string& to, const SessionDescription* sdesc); // When we receive an initiate, we create a session in the // RECEIVEDINITIATE state and respond by accepting or rejecting. // Takes ownership of session description. + // TODO: Add an error argument to pass back to the caller. virtual bool Accept(const SessionDescription* sdesc); - virtual bool Reject(); - - // At any time, we may terminate an outstanding session. - virtual bool Terminate(); + virtual bool Reject(const std::string& reason); + virtual bool TerminateWithReason(const std::string& reason); // The two clients in the session may also send one another arbitrary XML // messages, which are called "info" messages. Both of these functions take // ownership of the XmlElements and delete them when done. - void SendInfoMessage(const XmlElements& elems); + bool SendInfoMessage(const XmlElements& elems); sigslot::signal2<Session*, const XmlElements&> SignalInfoMessage; // Maps passed to serialization functions. TransportParserMap GetTransportParsers(); ContentParserMap GetContentParsers(); - // Creates a new channel with the given name. This method may be called + // Creates a new channel with the given names. This method may be called // immediately after creating the session. However, the actual // implementation may not be fixed until transport negotiation completes. - virtual TransportChannel* CreateChannel(const std::string& name); + virtual TransportChannel* CreateChannel(const std::string& content_name, + const std::string& channel_name); - // Returns the channel with the given name. - virtual TransportChannel* GetChannel(const std::string& name); + // Returns the channel with the given names. + virtual TransportChannel* GetChannel(const std::string& content_name, + const std::string& channel_name); - // Destroys the given channel. - virtual void DestroyChannel(TransportChannel* channel); + // Destroys the channel with the given names. + virtual void DestroyChannel(const std::string& content_name, + const std::string& channel_name); // Handles messages posted to us. virtual void OnMessage(talk_base::Message *pmsg); private: - typedef std::map<std::string, TransportChannelProxy*> ChannelMap; - - SessionManager *session_manager_; - bool initiator_; - std::string content_type_; - SessionClient* client_; - // TODO(pthatcher): reenable redirect the Jingle way - // std::string redirect_target_; - - Transport* transport_; - bool transport_negotiated_; - // in order to resend candidates, we need to know what we sent. - Candidates sent_candidates_; - ChannelMap channels_; - // Keeps track of what protocol we are speaking. This was - // previously done using "compatibility_mode_". Now - // "compatibility_mode_" is when the protocol is PROTOCOL_GINGLE. - // But, it's no longer a binary value, since we can have - // PROTOCOL_JINGLE and PROTOCOL_HYBRID. - SignalingProtocol current_protocol_; - // Creates or destroys a session. (These are called only SessionManager.) Session(SessionManager *session_manager, - const std::string& name, - const SessionID& id, - const std::string& content_type, + const std::string& local_name, const std::string& initiator_name, + const std::string& sid, const std::string& content_type, SessionClient* client); ~Session(); - // To improve connection time, this creates the channels on the most common - // transport type and initiates connection. - void ConnectDefaultTransportChannels(Transport* transport); - void ConnectTransportChannels(Transport* transport); + // Get a TransportProxy by content_name or transport. NULL if not found. + TransportProxy* GetTransportProxy(const std::string& content_name); + TransportProxy* GetTransportProxy(const Transport* transport); + TransportProxy* GetFirstTransportProxy(); + // TransportProxy is owned by session. Return proxy just for convenience. + TransportProxy* GetOrCreateTransportProxy(const std::string& content_name); + // For each transport info, create a transport proxy. Can fail for + // incompatible transport types. + bool CreateTransportProxies(const TransportInfos& tinfos, + SessionError* error); + void SpeculativelyConnectAllTransportChannels(); + // For each transport proxy with a matching content name, complete + // the transport negotiation. + void CompleteTransportNegotiations(const TransportInfos& tinfos); + // Returns a TransportInfo without candidates for each content name. + // Uses the transport_type_ of the session. + TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const; - void SetTransport(Transport* transport); // Called when the first channel of a transport begins connecting. We use // this to start a timer, to make sure that the connection completes in a @@ -354,14 +430,50 @@ class Session : public BaseSession { void OnSignalingReady(); // Send various kinds of session messages. - void SendInitiateMessage(const SessionDescription* sdesc); - void SendAcceptMessage(const SessionDescription* sdesc); - void SendRejectMessage(); - void SendTerminateMessage(); - void SendTransportInfoMessage(const Candidates& candidates); - - // Sends a message of the given type to the other client. - void SendMessage(ActionType type, const XmlElements& action_elems); + bool SendInitiateMessage(const SessionDescription* sdesc, + SessionError* error); + bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error); + bool SendRejectMessage(const std::string& reason, SessionError* error); + bool SendTerminateMessage(const std::string& reason, SessionError* error); + bool SendTransportInfoMessage(const TransportInfo& tinfo, + SessionError* error); + + // Both versions of SendMessage send a message of the given type to + // the other client. Can pass either a set of elements or an + // "action", which must have a WriteSessionAction method to go along + // with it. Sending with an action supports sending a "hybrid" + // message. Sending with elements must be sent as Jingle or Gingle. + + // When passing elems, must be either Jingle or Gingle protocol. + // Takes ownership of action_elems. + bool SendMessage(ActionType type, const XmlElements& action_elems, + SessionError* error); + // When passing an action, may be Hybrid protocol. + template <typename Action> + bool SendMessage(ActionType type, const Action& action, + SessionError* error); + + // Helper methods to write the session message stanza. + template <typename Action> + bool WriteActionMessage(ActionType type, const Action& action, + buzz::XmlElement* stanza, WriteError* error); + template <typename Action> + bool WriteActionMessage(SignalingProtocol protocol, + ActionType type, const Action& action, + buzz::XmlElement* stanza, WriteError* error); + + // Sending messages in hybrid form requires being able to write them + // on a per-protocol basis with a common method signature, which all + // of these have. + bool WriteSessionAction(SignalingProtocol protocol, + const SessionInitiate& init, + XmlElements* elems, WriteError* error); + bool WriteSessionAction(SignalingProtocol protocol, + const TransportInfo& tinfo, + XmlElements* elems, WriteError* error); + bool WriteSessionAction(SignalingProtocol protocol, + const SessionTerminate& term, + XmlElements* elems, WriteError* error); // Sends a message back to the other client indicating that we have received // and accepted their message. @@ -388,16 +500,30 @@ class Session : public BaseSession { // Handlers for the various types of messages. These functions may take // pointers to the whole stanza or to just the session element. - bool OnInitiateMessage(const SessionMessage& msg, SessionError* error); - bool OnAcceptMessage(const SessionMessage& msg, SessionError* error); - bool OnRejectMessage(const SessionMessage& msg, SessionError* error); + bool OnInitiateMessage(const SessionMessage& msg, MessageError* error); + bool OnAcceptMessage(const SessionMessage& msg, MessageError* error); + bool OnRejectMessage(const SessionMessage& msg, MessageError* error); bool OnInfoMessage(const SessionMessage& msg); - bool OnTerminateMessage(const SessionMessage& msg, SessionError* error); - bool OnTransportInfoMessage(const SessionMessage& msg, SessionError* error); - bool OnTransportAcceptMessage(const SessionMessage& msg, SessionError* error); + bool OnTerminateMessage(const SessionMessage& msg, MessageError* error); + bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error); + bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error); // Verifies that we are in the appropriate state to receive this message. - bool CheckState(State state, SessionError* error); + bool CheckState(State state, MessageError* error); + + SessionManager *session_manager_; + bool initiator_; + std::string initiator_name_; + std::string content_type_; + SessionClient* client_; + std::string transport_type_; + TransportParser* transport_parser_; + // This is transport-specific but required so much by unit tests + // that it's much easier to put it here. + bool allow_local_ips_; + TransportMap transports_; + // Keeps track of what protocol we are speaking. + SignalingProtocol current_protocol_; friend class SessionManager; // For access to constructor, destructor, // and signaling related methods. diff --git a/third_party/libjingle/source/talk/p2p/base/sessionclient.h b/third_party/libjingle/source/talk/p2p/base/sessionclient.h index 38e1693..d6604a9 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessionclient.h +++ b/third_party/libjingle/source/talk/p2p/base/sessionclient.h @@ -40,10 +40,12 @@ class SessionDescription; class ContentParser { public: - virtual bool ParseContent(const buzz::XmlElement* elem, + virtual bool ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* elem, const ContentDescription** content, ParseError* error) = 0; - virtual bool WriteContent(const ContentDescription* content, + virtual bool WriteContent(SignalingProtocol protocol, + const ContentDescription* content, buzz::XmlElement** elem, WriteError* error) = 0; virtual ~ContentParser() {} @@ -65,13 +67,14 @@ class SessionClient : public ContentParser { virtual void OnSessionCreate(Session* session, bool received_initiate) = 0; virtual void OnSessionDestroy(Session* session) = 0; - virtual bool ParseContent(const buzz::XmlElement* elem, + virtual bool ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* elem, const ContentDescription** content, ParseError* error) = 0; - virtual bool WriteContent(const ContentDescription* content, + virtual bool WriteContent(SignalingProtocol protocol, + const ContentDescription* content, buzz::XmlElement** elem, WriteError* error) = 0; - protected: // The SessionClient interface explicitly does not include destructor virtual ~SessionClient() { } diff --git a/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc b/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc index 5fef38b..872358e 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc +++ b/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc @@ -31,10 +31,10 @@ namespace cricket { -const ContentInfo* SessionDescription::GetContentByName( - const std::string& name) const { - for (std::vector<ContentInfo>::const_iterator content = contents_.begin(); - content != contents_.end(); content++) { +const ContentInfo* FindContentInfoByName( + const ContentInfos& contents, const std::string& name) { + for (ContentInfos::const_iterator content = contents.begin(); + content != contents.end(); content++) { if (content->name == name) { return &(*content); } @@ -42,10 +42,10 @@ const ContentInfo* SessionDescription::GetContentByName( return NULL; } -const ContentInfo* SessionDescription::FirstContentByType( - const std::string& type) const { - for (std::vector<ContentInfo>::const_iterator content = contents_.begin(); - content != contents_.end(); content++) { +const ContentInfo* FindContentInfoByType( + const ContentInfos& contents, const std::string& type) { + for (ContentInfos::const_iterator content = contents.begin(); + content != contents.end(); content++) { if (content->type == type) { return &(*content); } @@ -53,6 +53,16 @@ const ContentInfo* SessionDescription::FirstContentByType( return NULL; } +const ContentInfo* SessionDescription::GetContentByName( + const std::string& name) const { + return FindContentInfoByName(contents_, name); +} + +const ContentInfo* SessionDescription::FirstContentByType( + const std::string& type) const { + return FindContentInfoByType(contents_, type); +} + void SessionDescription::AddContent(const std::string& name, const std::string& type, const ContentDescription* description) { diff --git a/third_party/libjingle/source/talk/p2p/base/sessiondescription.h b/third_party/libjingle/source/talk/p2p/base/sessiondescription.h index 5fe8ed1..fe575fa 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessiondescription.h +++ b/third_party/libjingle/source/talk/p2p/base/sessiondescription.h @@ -55,13 +55,19 @@ struct ContentInfo { const ContentDescription* description; }; +typedef std::vector<ContentInfo> ContentInfos; +const ContentInfo* FindContentInfoByName( + const ContentInfos& contents, const std::string& name); +const ContentInfo* FindContentInfoByType( + const ContentInfos& contents, const std::string& type); + // Describes a collection of contents, each with its own name and // type. Analgous to a <jingle> or <session> stanza. Assumes that // contents are unique be name, but doesn't enforce that. class SessionDescription { public: SessionDescription() {} - explicit SessionDescription(const std::vector<ContentInfo>& contents) : + explicit SessionDescription(const ContentInfos& contents) : contents_(contents) {} const ContentInfo* GetContentByName(const std::string& name) const; const ContentInfo* FirstContentByType(const std::string& type) const; @@ -69,20 +75,20 @@ class SessionDescription { void AddContent(const std::string& name, const std::string& type, const ContentDescription* description); - // TODO(pthatcher): Implement RemoveContent when it's needed for + // TODO: Implement RemoveContent when it's needed for // content-remove Jingle messages. // void RemoveContent(const std::string& name); - const std::vector<ContentInfo>& contents() const { return contents_; } + const ContentInfos& contents() const { return contents_; } ~SessionDescription() { - for (std::vector<ContentInfo>::iterator content = contents_.begin(); + for (ContentInfos::iterator content = contents_.begin(); content != contents_.end(); content++) { delete content->description; } } private: - std::vector<ContentInfo> contents_; + ContentInfos contents_; }; // Indicates whether a ContentDescription was an offer or an answer, as diff --git a/third_party/libjingle/source/talk/p2p/base/sessionid.h b/third_party/libjingle/source/talk/p2p/base/sessionid.h index 7efa235..6942942 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessionid.h +++ b/third_party/libjingle/source/talk/p2p/base/sessionid.h @@ -28,70 +28,10 @@ #ifndef TALK_P2P_BASE_SESSIONID_H_ #define TALK_P2P_BASE_SESSIONID_H_ -#include <string> -#include <sstream> -#include "talk/base/basictypes.h" +// TODO: Remove this file. namespace cricket { -// Each session is identified by a pair (from,id), where id is only -// assumed to be unique to the machine identified by from. -class SessionID { - public: - SessionID() : id_str_("0") { - } - SessionID(const std::string& initiator, uint32 id) - : initiator_(initiator) { - set_id(id); - } - SessionID(const std::string& initiator, const std::string& id_str) - : id_str_(id_str), initiator_(initiator) { - } - SessionID(const SessionID& sid) - : id_str_(sid.id_str_), initiator_(sid.initiator_) { - } - - void set_id(uint32 id) { - std::stringstream st; - st << id; - st >> id_str_; - } - const std::string id_str() const { - return id_str_; - } - void set_id_str(const std::string &id_str) { - id_str_ = id_str; - } - - const std::string &initiator() const { - return initiator_; - } - void set_initiator(const std::string &initiator) { - initiator_ = initiator; - } - - bool operator <(const SessionID& sid) const { - int r = initiator_.compare(sid.initiator_); - if (r == 0) - r = id_str_.compare(sid.id_str_); - return r < 0; - } - - bool operator ==(const SessionID& sid) const { - return (id_str_ == sid.id_str_) && (initiator_ == sid.initiator_); - } - - SessionID& operator =(const SessionID& sid) { - id_str_ = sid.id_str_; - initiator_ = sid.initiator_; - return *this; - } - - private: - std::string id_str_; - std::string initiator_; -}; - } // namespace cricket #endif // TALK_P2P_BASE_SESSIONID_H_ diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmanager.cc b/third_party/libjingle/source/talk/p2p/base/sessionmanager.cc index 49aacc3..61a4c4a 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessionmanager.cc +++ b/third_party/libjingle/source/talk/p2p/base/sessionmanager.cc @@ -27,12 +27,12 @@ #include "talk/p2p/base/sessionmanager.h" -#include <vector> -#include "talk/p2p/base/session.h" -#include "talk/p2p/base/sessionmessages.h" #include "talk/base/common.h" #include "talk/base/helpers.h" +#include "talk/base/stringencode.h" #include "talk/p2p/base/constants.h" +#include "talk/p2p/base/session.h" +#include "talk/p2p/base/sessionmessages.h" #include "talk/xmpp/constants.h" #include "talk/xmpp/jid.h" @@ -74,19 +74,22 @@ SessionClient* SessionManager::GetClient(const std::string& content_type) { return (iter != client_map_.end()) ? iter->second : NULL; } -Session *SessionManager::CreateSession(const std::string& name, +Session* SessionManager::CreateSession(const std::string& local_name, const std::string& content_type) { - return CreateSession(name, SessionID(name, talk_base::CreateRandomId()), + return CreateSession(local_name, local_name, + talk_base::ToString(talk_base::CreateRandomId()), content_type, false); } -Session *SessionManager::CreateSession( - const std::string &name, const SessionID& id, - const std::string& content_type, bool received_initiate) { +Session* SessionManager::CreateSession( + const std::string& local_name, const std::string& initiator_name, + const std::string& sid, const std::string& content_type, + bool received_initiate) { SessionClient* client = GetClient(content_type); ASSERT(client != NULL); - Session *session = new Session(this, name, id, content_type, client); + Session* session = new Session(this, local_name, initiator_name, + sid, content_type, client); session_map_[session->id()] = session; session->SignalRequestSignaling.connect( this, &SessionManager::OnRequestSignaling); @@ -98,7 +101,7 @@ Session *SessionManager::CreateSession( return session; } -void SessionManager::DestroySession(Session *session) { +void SessionManager::DestroySession(Session* session) { if (session != NULL) { SessionMap::iterator it = session_map_.find(session->id()); if (it != session_map_.end()) { @@ -110,8 +113,8 @@ void SessionManager::DestroySession(Session *session) { } } -Session *SessionManager::GetSession(const SessionID& id) { - SessionMap::iterator it = session_map_.find(id); +Session* SessionManager::GetSession(const std::string& sid) { + SessionMap::iterator it = session_map_.find(sid); if (it != session_map_.end()) return it->second; return NULL; @@ -119,7 +122,7 @@ Session *SessionManager::GetSession(const SessionID& id) { void SessionManager::TerminateAll() { while (session_map_.begin() != session_map_.end()) { - Session *session = session_map_.begin()->second; + Session* session = session_map_.begin()->second; session->Terminate(); } } @@ -129,9 +132,8 @@ bool SessionManager::IsSessionMessage(const buzz::XmlElement* stanza) { } Session* SessionManager::FindSession(const std::string& sid, - const std::string& initiator, const std::string& remote_name) { - SessionMap::iterator iter = session_map_.find(SessionID(initiator, sid)); + SessionMap::iterator iter = session_map_.find(sid); if (iter == session_map_.end()) return NULL; @@ -152,12 +154,11 @@ void SessionManager::OnIncomingMessage(const buzz::XmlElement* stanza) { return; } - Session* session = FindSession(msg.sid, msg.initiator, msg.from); + Session* session = FindSession(msg.sid, msg.from); if (session) { session->OnIncomingMessage(msg); return; } - if (msg.type != ACTION_SESSION_INITIATE) { SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify", "unknown session", NULL); @@ -165,7 +166,8 @@ void SessionManager::OnIncomingMessage(const buzz::XmlElement* stanza) { } std::string content_type; - if (!ParseFirstContentType(msg.action_elem, &content_type, &error)) { + if (!ParseContentType(msg.protocol, msg.action_elem, + &content_type, &error)) { SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify", error.text, NULL); return; @@ -173,12 +175,11 @@ void SessionManager::OnIncomingMessage(const buzz::XmlElement* stanza) { if (!GetClient(content_type)) { SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify", - "unknown session description type", NULL); + "unknown content type: " + content_type, NULL); return; } - session = CreateSession(msg.to, - SessionID(msg.initiator, msg.sid), + session = CreateSession(msg.to, msg.initiator, msg.sid, content_type, true); session->OnIncomingMessage(msg); } @@ -195,10 +196,10 @@ void SessionManager::OnFailedSend(const buzz::XmlElement* orig_stanza, SessionMessage msg; ParseError error; if (!ParseSessionMessage(orig_stanza, &msg, &error)) { - return; // TODO(pthatcher): log somewhere? + return; // TODO: log somewhere? } - Session* session = FindSession(msg.sid, msg.initiator, msg.to); + Session* session = FindSession(msg.sid, msg.to); if (session) { talk_base::scoped_ptr<buzz::XmlElement> synthetic_error; if (!error_stanza) { @@ -235,11 +236,7 @@ buzz::XmlElement* SessionManager::CreateErrorMessage( iq->SetAttr(buzz::QN_ID, stanza->Attr(buzz::QN_ID)); iq->SetAttr(buzz::QN_TYPE, "error"); - for (const buzz::XmlElement* elem = stanza->FirstElement(); - elem != NULL; - elem = elem->NextElement()) { - iq->AddElement(new buzz::XmlElement(*elem)); - } + CopyXmlChildren(stanza, iq); buzz::XmlElement* error = new buzz::XmlElement(buzz::QN_ERROR); error->SetAttr(buzz::QN_TYPE, type); diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmanager.h b/third_party/libjingle/source/talk/p2p/base/sessionmanager.h index 9eebc4d..9bc1019 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessionmanager.h +++ b/third_party/libjingle/source/talk/p2p/base/sessionmanager.h @@ -32,10 +32,10 @@ #include <string> #include <utility> #include <vector> + +#include "talk/base/sigslot.h" #include "talk/base/thread.h" #include "talk/p2p/base/portallocator.h" -#include "talk/p2p/base/sessionid.h" -#include "talk/base/sigslot.h" namespace buzz { class QName; @@ -73,14 +73,14 @@ class SessionManager : public sigslot::has_slots<> { // Creates a new session. The given name is the JID of the client on whose // behalf we initiate the session. - Session *CreateSession(const std::string& name, + Session *CreateSession(const std::string& local_name, const std::string& content_type); // Destroys the given session. void DestroySession(Session *session); // Returns the session with the given ID or NULL if none exists. - Session *GetSession(const SessionID& id); + Session *GetSession(const std::string& sid); // Terminates all of the sessions created by this manager. void TerminateAll(); @@ -94,7 +94,6 @@ class SessionManager : public sigslot::has_slots<> { // Given a sid, initiator, and remote_name, this finds the matching Session Session* FindSession(const std::string& sid, - const std::string& initiator, const std::string& remote_name); // Called when we receive a stanza for which IsSessionMessage is true. @@ -126,7 +125,7 @@ class SessionManager : public sigslot::has_slots<> { void OnSignalingReady(); private: - typedef std::map<SessionID, Session*> SessionMap; + typedef std::map<std::string, Session*> SessionMap; typedef std::map<std::string, SessionClient*> ClientMap; PortAllocator *allocator_; @@ -138,8 +137,9 @@ class SessionManager : public sigslot::has_slots<> { // Helper function for CreateSession. This is also invoked when we receive // a message attempting to initiate a session with this client. - Session *CreateSession(const std::string& name, - const SessionID& id, + Session *CreateSession(const std::string& local_name, + const std::string& initiator, + const std::string& sid, const std::string& content_type, bool received_initiate); diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmessages.cc b/third_party/libjingle/source/talk/p2p/base/sessionmessages.cc index c340629..f7c424e 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessionmessages.cc +++ b/third_party/libjingle/source/talk/p2p/base/sessionmessages.cc @@ -28,11 +28,13 @@ #include "talk/p2p/base/sessionmessages.h" #include "talk/base/logging.h" +#include "talk/base/scoped_ptr.h" #include "talk/xmpp/constants.h" #include "talk/p2p/base/constants.h" #include "talk/p2p/base/p2ptransport.h" #include "talk/p2p/base/parsing.h" #include "talk/p2p/base/sessionclient.h" +#include "talk/p2p/base/sessiondescription.h" #include "talk/p2p/base/transport.h" namespace cricket { @@ -50,6 +52,18 @@ ActionType ToActionType(const std::string& type) { return ACTION_SESSION_TERMINATE; if (type == GINGLE_ACTION_CANDIDATES) return ACTION_TRANSPORT_INFO; + if (type == JINGLE_ACTION_SESSION_INITIATE) + return ACTION_SESSION_INITIATE; + if (type == JINGLE_ACTION_TRANSPORT_INFO) + return ACTION_TRANSPORT_INFO; + if (type == JINGLE_ACTION_TRANSPORT_ACCEPT) + return ACTION_TRANSPORT_ACCEPT; + if (type == JINGLE_ACTION_SESSION_INFO) + return ACTION_SESSION_INFO; + if (type == JINGLE_ACTION_SESSION_ACCEPT) + return ACTION_SESSION_ACCEPT; + if (type == JINGLE_ACTION_SESSION_TERMINATE) + return ACTION_SESSION_TERMINATE; if (type == JINGLE_ACTION_TRANSPORT_INFO) return ACTION_TRANSPORT_INFO; if (type == JINGLE_ACTION_TRANSPORT_ACCEPT) @@ -58,7 +72,29 @@ ActionType ToActionType(const std::string& type) { return ACTION_UNKNOWN; } -std::string ToString(ActionType type, SignalingProtocol protocol) { +std::string ToJingleString(ActionType type) { + switch (type) { + case ACTION_SESSION_INITIATE: + return JINGLE_ACTION_SESSION_INITIATE; + case ACTION_SESSION_INFO: + return JINGLE_ACTION_SESSION_INFO; + case ACTION_SESSION_ACCEPT: + return JINGLE_ACTION_SESSION_ACCEPT; + // Notice that reject and terminate both go to + // "session-terminate", but there is no "session-reject". + case ACTION_SESSION_REJECT: + case ACTION_SESSION_TERMINATE: + return JINGLE_ACTION_SESSION_TERMINATE; + case ACTION_TRANSPORT_INFO: + return JINGLE_ACTION_TRANSPORT_INFO; + case ACTION_TRANSPORT_ACCEPT: + return JINGLE_ACTION_TRANSPORT_ACCEPT; + default: + return ""; + } +} + +std::string ToGingleString(ActionType type) { switch (type) { case ACTION_SESSION_INITIATE: return GINGLE_ACTION_INITIATE; @@ -71,61 +107,122 @@ std::string ToString(ActionType type, SignalingProtocol protocol) { case ACTION_SESSION_TERMINATE: return GINGLE_ACTION_TERMINATE; case ACTION_TRANSPORT_INFO: - if (protocol == PROTOCOL_GINGLE2) - return JINGLE_ACTION_TRANSPORT_INFO; - else - return GINGLE_ACTION_CANDIDATES; + return GINGLE_ACTION_CANDIDATES; default: return ""; } } -bool IsSessionMessage(const buzz::XmlElement* stanza) { - if (stanza->Name() != buzz::QN_IQ || - stanza->Attr(buzz::QN_TYPE) != buzz::STR_SET) - return false; - const buzz::XmlElement* action = stanza->FirstNamed(QN_GINGLE_SESSION); - if (action == NULL) +bool IsJingleMessage(const buzz::XmlElement* stanza) { + const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE); + if (jingle == NULL) return false; - return (action->HasAttr(buzz::QN_TYPE) && - action->HasAttr(buzz::QN_ID) && - action->HasAttr(QN_INITIATOR)); + return (jingle->HasAttr(buzz::QN_ACTION) && + jingle->HasAttr(buzz::QN_ID)); } -bool ParseSessionMessage(const buzz::XmlElement* stanza, - SessionMessage* msg, - ParseError* error) { - const buzz::XmlElement* action; - if (!RequireXmlChild(stanza, QN_GINGLE_SESSION.LocalPart(), &action, error)) +bool IsGingleMessage(const buzz::XmlElement* stanza) { + const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION); + if (session == NULL) return false; - std::string type_string; - if (!RequireXmlAttr(action, buzz::QN_TYPE, &type_string, error)) + return (session->HasAttr(buzz::QN_TYPE) && + session->HasAttr(buzz::QN_ID) && + session->HasAttr(QN_INITIATOR)); +} + +bool IsSessionMessage(const buzz::XmlElement* stanza) { + return (stanza->Name() == buzz::QN_IQ && + stanza->Attr(buzz::QN_TYPE) == buzz::STR_SET && + (IsJingleMessage(stanza) || + IsGingleMessage(stanza))); +} + +bool ParseGingleSessionMessage(const buzz::XmlElement* session, + SessionMessage* msg, + ParseError* error) { + msg->protocol = PROTOCOL_GINGLE; + std::string type_string = session->Attr(buzz::QN_TYPE); + msg->type = ToActionType(type_string); + msg->sid = session->Attr(buzz::QN_ID); + msg->initiator = session->Attr(QN_INITIATOR); + msg->action_elem = session; + + if (msg->type == ACTION_UNKNOWN) + return BadParse("unknown action: " + type_string, error); + + return true; +} + +bool ParseJingleSessionMessage(const buzz::XmlElement* jingle, + SessionMessage* msg, + ParseError* error) { + msg->protocol = PROTOCOL_JINGLE; + std::string type_string = jingle->Attr(buzz::QN_ACTION); + msg->type = ToActionType(type_string); + msg->sid = jingle->Attr(buzz::QN_ID); + msg->initiator = GetXmlAttr(jingle, QN_INITIATOR, ""); + msg->action_elem = jingle; + + if (msg->type == ACTION_UNKNOWN) + return BadParse("unknown action: " + type_string, error); + + return true; +} + +bool ParseHybridSessionMessage(const buzz::XmlElement* jingle, + SessionMessage* msg, + ParseError* error) { + if (!ParseJingleSessionMessage(jingle, msg, error)) return false; + msg->protocol = PROTOCOL_HYBRID; + + return true; +} +bool ParseSessionMessage(const buzz::XmlElement* stanza, + SessionMessage* msg, + ParseError* error) { msg->id = stanza->Attr(buzz::QN_ID); msg->from = stanza->Attr(buzz::QN_FROM); msg->to = stanza->Attr(buzz::QN_TO); msg->stanza = stanza; - msg->sid = action->Attr(buzz::QN_ID); - msg->initiator = action->Attr(QN_INITIATOR); - msg->type = ToActionType(type_string); - if (msg->type == ACTION_UNKNOWN) - return BadParse("unknown action: " + type_string, error); - msg->action_elem = action; + const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE); + const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION); + if (jingle && session) + return ParseHybridSessionMessage(jingle, msg, error); + if (jingle != NULL) + return ParseJingleSessionMessage(jingle, msg, error); + if (session != NULL) + return ParseGingleSessionMessage(session, msg, error); + return false; +} - if (type_string == GINGLE_ACTION_CANDIDATES || - (msg->type == ACTION_SESSION_INITIATE && - action->FirstNamed(QN_GINGLE_P2P_TRANSPORT) == NULL)) { - msg->protocol = PROTOCOL_GINGLE; - } else { - msg->protocol = PROTOCOL_GINGLE2; - } +buzz::XmlElement* WriteGingleAction(const SessionMessage& msg, + const XmlElements& action_elems) { + buzz::XmlElement* session = new buzz::XmlElement(QN_GINGLE_SESSION, true); + session->AddAttr(buzz::QN_TYPE, ToGingleString(msg.type)); + session->AddAttr(buzz::QN_ID, msg.sid); + session->AddAttr(QN_INITIATOR, msg.initiator); + AddXmlChildren(session, action_elems); + return session; +} - return true; +buzz::XmlElement* WriteJingleAction(const SessionMessage& msg, + const XmlElements& action_elems) { + buzz::XmlElement* jingle = new buzz::XmlElement(QN_JINGLE, true); + jingle->AddAttr(buzz::QN_ACTION, ToJingleString(msg.type)); + jingle->AddAttr(buzz::QN_ID, msg.sid); + // TODO: Right now, the XMPP server rejects a jingle-only + // (non hybrid) message with "feature-not-implemented" if there is + // no initiator. Fix the server, and then only set the initiator on + // session-initiate messages here. + jingle->AddAttr(QN_INITIATOR, msg.initiator); + AddXmlChildren(jingle, action_elems); + return jingle; } void WriteSessionMessage(const SessionMessage& msg, @@ -134,15 +231,11 @@ void WriteSessionMessage(const SessionMessage& msg, stanza->SetAttr(buzz::QN_TO, msg.to); stanza->SetAttr(buzz::QN_TYPE, buzz::STR_SET); - buzz::XmlElement* action = new buzz::XmlElement(QN_GINGLE_SESSION, true); - action->AddAttr(buzz::QN_TYPE, - ToString(msg.type, msg.protocol)); - action->AddAttr(buzz::QN_ID, msg.sid); - action->AddAttr(QN_INITIATOR, msg.initiator); - - AddXmlChildren(action, action_elems); - - stanza->AddElement(action); + if (msg.protocol == PROTOCOL_GINGLE) { + stanza->AddElement(WriteGingleAction(msg, action_elems)); + } else { + stanza->AddElement(WriteJingleAction(msg, action_elems)); + } } @@ -156,89 +249,191 @@ TransportParser* GetTransportParser(const TransportParserMap& trans_parsers, } } -bool ParseCandidates(const buzz::XmlElement* candidates_elem, +bool ParseCandidates(SignalingProtocol protocol, + const buzz::XmlElement* candidates_elem, const TransportParserMap& trans_parsers, - const std::string& trans_name, + const std::string& transport_type, Candidates* candidates, ParseError* error) { - TransportParser* trans_parser = GetTransportParser(trans_parsers, trans_name); + TransportParser* trans_parser = + GetTransportParser(trans_parsers, transport_type); if (trans_parser == NULL) - return BadParse("unknown transport type: " + trans_name, error); + return BadParse("unknown transport type: " + transport_type, error); - return trans_parser->ParseCandidates(candidates_elem, candidates, error); + return trans_parser->ParseCandidates(protocol, candidates_elem, + candidates, error); } -// Pass in NULL candidates if you don't want them parsed. -bool ParseGingleTransport(const buzz::XmlElement* action_elem, - const TransportParserMap& trans_parsers, - std::string* name, - Candidates* candidates, - ParseError* error) { - const buzz::XmlElement* candidates_elem; - const buzz::XmlElement* trans_elem = GetXmlChild(action_elem, LN_TRANSPORT); - if (trans_elem == NULL) { // PROTCOL_GINGLE - *name = NS_GINGLE_P2P; - candidates_elem = action_elem; - } else { // PROTOCOL_GINGLE2 - *name = trans_elem->Name().Namespace(); - candidates_elem = trans_elem; +bool ParseGingleTransportInfos(const buzz::XmlElement* action_elem, + const ContentInfos& contents, + const TransportParserMap& trans_parsers, + TransportInfos* tinfos, + ParseError* error) { + TransportInfo tinfo(CN_OTHER, NS_GINGLE_P2P, Candidates()); + if (!ParseCandidates(PROTOCOL_GINGLE, action_elem, + trans_parsers, NS_GINGLE_P2P, + &tinfo.candidates, error)) + return false; + + bool has_audio = FindContentInfoByName(contents, CN_AUDIO) != NULL; + bool has_video = FindContentInfoByName(contents, CN_VIDEO) != NULL; + + // If we don't have media, no need to separate the candidates. + if (!has_audio && !has_audio) { + tinfos->push_back(tinfo); + return true; } - if (candidates != NULL) { - return ParseCandidates(candidates_elem, trans_parsers, *name, - candidates, error); + // If we have media, separate the candidates. Create the + // TransportInfo here to avoid copying the candidates. + TransportInfo audio_tinfo(CN_AUDIO, NS_GINGLE_P2P, Candidates()); + TransportInfo video_tinfo(CN_VIDEO, NS_GINGLE_P2P, Candidates()); + for (Candidates::iterator cand = tinfo.candidates.begin(); + cand != tinfo.candidates.end(); cand++) { + if (cand->name() == GINGLE_CANDIDATE_NAME_RTP || + cand->name() == GINGLE_CANDIDATE_NAME_RTCP) { + audio_tinfo.candidates.push_back(*cand); + } else if (cand->name() == GINGLE_CANDIDATE_NAME_VIDEO_RTP || + cand->name() == GINGLE_CANDIDATE_NAME_VIDEO_RTCP) { + video_tinfo.candidates.push_back(*cand); + } + } + + if (has_audio) { + tinfos->push_back(audio_tinfo); } + + if (has_video) { + tinfos->push_back(video_tinfo); + } + return true; } -bool ParseGingleTransportName(const buzz::XmlElement* action_elem, - std::string* name, +bool ParseJingleTransportInfo(const buzz::XmlElement* trans_elem, + const ContentInfo& content, + const TransportParserMap& trans_parsers, + TransportInfos* tinfos, ParseError* error) { - return ParseGingleTransport(action_elem, TransportParserMap(), - name, NULL, error); + std::string transport_type = trans_elem->Name().Namespace(); + TransportInfo tinfo(content.name, transport_type, Candidates()); + if (!ParseCandidates(PROTOCOL_JINGLE, trans_elem, + trans_parsers, transport_type, + &tinfo.candidates, error)) + return false; + + tinfos->push_back(tinfo); + return true; +} + +bool ParseJingleTransportInfos(const buzz::XmlElement* jingle, + const ContentInfos& contents, + const TransportParserMap trans_parsers, + TransportInfos* tinfos, + ParseError* error) { + for (const buzz::XmlElement* pair_elem + = jingle->FirstNamed(QN_JINGLE_CONTENT); + pair_elem != NULL; + pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) { + std::string content_name; + if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME, + &content_name, error)) + return false; + + const ContentInfo* content = FindContentInfoByName(contents, content_name); + if (!content) + return BadParse("Unknown content name: " + content_name, error); + + const buzz::XmlElement* trans_elem; + if (!RequireXmlChild(pair_elem, LN_TRANSPORT, &trans_elem, error)) + return false; + + if (!ParseJingleTransportInfo(trans_elem, *content, trans_parsers, + tinfos, error)) + return false; + } + + return true; } buzz::XmlElement* NewTransportElement(const std::string& name) { return new buzz::XmlElement(buzz::QName(true, name, LN_TRANSPORT), true); } -bool WriteGingleTransport(const std::string& trans_name, - const Candidates& candidates, - const TransportParserMap& trans_parsers, - SignalingProtocol protocol, - XmlElements* elems, - WriteError* error) { - TransportParser* trans_parser = GetTransportParser(trans_parsers, trans_name); +bool WriteCandidates(SignalingProtocol protocol, + const std::string& trans_type, + const Candidates& candidates, + const TransportParserMap& trans_parsers, + XmlElements* elems, + WriteError* error) { + TransportParser* trans_parser = GetTransportParser(trans_parsers, trans_type); if (trans_parser == NULL) - return BadWrite("unknown transport type: " + trans_name, error); + return BadWrite("unknown transport type: " + trans_type, error); - if (protocol == PROTOCOL_GINGLE2) { - buzz::XmlElement* trans_elem = NewTransportElement(trans_name); - XmlElements cand_elems; - if (!trans_parser->WriteCandidates(candidates, protocol, - &cand_elems, error)) - return false; - AddXmlChildren(trans_elem, cand_elems); - elems->push_back(trans_elem); - } else { - if (!trans_parser->WriteCandidates(candidates, protocol, elems, error)) + return trans_parser->WriteCandidates(protocol, candidates, elems, error); +} + +bool WriteGingleTransportInfos(const TransportInfos& tinfos, + const TransportParserMap& trans_parsers, + XmlElements* elems, + WriteError* error) { + for (TransportInfos::const_iterator tinfo = tinfos.begin(); + tinfo != tinfos.end(); ++tinfo) { + if (!WriteCandidates(PROTOCOL_GINGLE, + tinfo->transport_type, tinfo->candidates, + trans_parsers, elems, error)) return false; } + return true; } -bool WriteGingleTransportWithoutCandidates(const std::string& trans_name, - SignalingProtocol protocol, - XmlElements* elems, - WriteError* error) { - if (protocol == PROTOCOL_GINGLE2) { - elems->push_back(NewTransportElement(trans_name)); +bool WriteJingleTransportInfo(const TransportInfo& tinfo, + const TransportParserMap& trans_parsers, + XmlElements* elems, + WriteError* error) { + XmlElements candidate_elems; + if (!WriteCandidates(PROTOCOL_JINGLE, + tinfo.transport_type, tinfo.candidates, trans_parsers, + &candidate_elems, error)) + return false; + + buzz::XmlElement* trans_elem = NewTransportElement(tinfo.transport_type); + AddXmlChildren(trans_elem, candidate_elems); + elems->push_back(trans_elem); + return true; +} + +void WriteJingleContentPair(const std::string name, + const XmlElements& pair_elems, + XmlElements* elems) { + buzz::XmlElement* pair_elem = new buzz::XmlElement(QN_JINGLE_CONTENT); + pair_elem->SetAttr(QN_JINGLE_CONTENT_NAME, name); + pair_elem->SetAttr(QN_CREATOR, LN_INITIATOR); + AddXmlChildren(pair_elem, pair_elems); + + elems->push_back(pair_elem); +} + +bool WriteJingleTransportInfos(const TransportInfos& tinfos, + const TransportParserMap& trans_parsers, + XmlElements* elems, + WriteError* error) { + for (TransportInfos::const_iterator tinfo = tinfos.begin(); + tinfo != tinfos.end(); ++tinfo) { + XmlElements pair_elems; + if (!WriteJingleTransportInfo(*tinfo, trans_parsers, + &pair_elems, error)) + return false; + + WriteJingleContentPair(tinfo->content_name, pair_elems, elems); } + return true; } -ContentParser* FindContentParser(const ContentParserMap& content_parsers, - const std::string& type) { +ContentParser* GetContentParser(const ContentParserMap& content_parsers, + const std::string& type) { ContentParserMap::const_iterator map = content_parsers.find(type); if (map == content_parsers.end()) { return NULL; @@ -247,91 +442,106 @@ ContentParser* FindContentParser(const ContentParserMap& content_parsers, } } -// Like FindContentParser, but does trickery for NS_GINGLE_AUDIO and -// NS_GINGLE_VIDEO. Because clients still assume only one content -// type, but we split up the types, we need to be able to let either -// content type work as the other. -ContentParser* GetContentParser(const ContentParserMap& content_parsers, - const std::string& type) { - ContentParser* parser = FindContentParser(content_parsers, type); - if (parser == NULL) { - if (type == NS_GINGLE_AUDIO) { - return FindContentParser(content_parsers, NS_GINGLE_VIDEO); - } else if (type == NS_GINGLE_VIDEO) { - return FindContentParser(content_parsers, NS_GINGLE_AUDIO); - } - } - - return parser; -} - -bool ParseContent(const std::string& name, - const std::string& type, - const buzz::XmlElement* elem, - const ContentParserMap& parsers, - std::vector<ContentInfo>* contents, - ParseError* error) { +bool ParseContentInfo(SignalingProtocol protocol, + const std::string& name, + const std::string& type, + const buzz::XmlElement* elem, + const ContentParserMap& parsers, + ContentInfos* contents, + ParseError* error) { ContentParser* parser = GetContentParser(parsers, type); if (parser == NULL) return BadParse("unknown application content: " + type, error); const ContentDescription* desc; - if (!parser->ParseContent(elem, &desc, error)) + if (!parser->ParseContent(protocol, elem, &desc, error)) return false; contents->push_back(ContentInfo(name, type, desc)); return true; } -bool ParseGingleContentType(const buzz::XmlElement* action_elem, - std::string* content_type, - const buzz::XmlElement** content_elem, - ParseError* error) { - if (!RequireXmlChild(action_elem, LN_DESCRIPTION, content_elem, error)) +bool ParseContentType(const buzz::XmlElement* parent_elem, + std::string* content_type, + const buzz::XmlElement** content_elem, + ParseError* error) { + if (!RequireXmlChild(parent_elem, LN_DESCRIPTION, content_elem, error)) return false; *content_type = (*content_elem)->Name().Namespace(); return true; } -bool ParseGingleContents(const buzz::XmlElement* action_elem, - const ContentParserMap& content_parsers, - std::vector<ContentInfo>* contents, - ParseError* error) { +bool ParseGingleContentInfos(const buzz::XmlElement* session, + const ContentParserMap& content_parsers, + ContentInfos* contents, + ParseError* error) { std::string content_type; const buzz::XmlElement* content_elem; - if (!ParseGingleContentType(action_elem, &content_type, &content_elem, error)) + if (!ParseContentType(session, &content_type, &content_elem, error)) return false; if (content_type == NS_GINGLE_VIDEO) { // A parser parsing audio or video content should look at the // namespace and only parse the codecs relevant to that namespace. - // We use this to control which codecs get parsed: first video, - // then audio. - if (!ParseContent(CN_VIDEO, NS_GINGLE_VIDEO, - content_elem, content_parsers, - contents, error)) - return false; - + // We use this to control which codecs get parsed: first audio, + // then video. talk_base::scoped_ptr<buzz::XmlElement> audio_elem( new buzz::XmlElement(QN_GINGLE_AUDIO_CONTENT)); CopyXmlChildren(content_elem, audio_elem.get()); - if (!ParseContent(CN_AUDIO, NS_GINGLE_AUDIO, - audio_elem.get(), content_parsers, - contents, error)) + if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP, + audio_elem.get(), content_parsers, + contents, error)) + return false; + + if (!ParseContentInfo(PROTOCOL_GINGLE, CN_VIDEO, NS_JINGLE_RTP, + content_elem, content_parsers, + contents, error)) + return false; + } else if (content_type == NS_GINGLE_AUDIO) { + if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP, + content_elem, content_parsers, + contents, error)) return false; } else { - if (!ParseContent(CN_OTHER, content_type, - content_elem, content_parsers, - contents, error)) + if (!ParseContentInfo(PROTOCOL_GINGLE, CN_OTHER, content_type, + content_elem, content_parsers, + contents, error)) return false; } return true; } -buzz::XmlElement* WriteContent(const ContentInfo& content, - const ContentParserMap& parsers, - WriteError* error) { +bool ParseJingleContentInfos(const buzz::XmlElement* jingle, + const ContentParserMap& content_parsers, + ContentInfos* contents, + ParseError* error) { + for (const buzz::XmlElement* pair_elem + = jingle->FirstNamed(QN_JINGLE_CONTENT); + pair_elem != NULL; + pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) { + std::string content_name; + if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME, + &content_name, error)) + return false; + + std::string content_type; + const buzz::XmlElement* content_elem; + if (!ParseContentType(pair_elem, &content_type, &content_elem, error)) + return false; + + if (!ParseContentInfo(PROTOCOL_JINGLE, content_name, content_type, + content_elem, content_parsers, + contents, error)) + return false; + } + return true; +} + +buzz::XmlElement* WriteContentInfo(SignalingProtocol protocol, + const ContentInfo& content, + const ContentParserMap& parsers, + WriteError* error) { ContentParser* parser = GetContentParser(parsers, content.type); if (parser == NULL) { BadWrite("unknown content type: " + content.type, error); @@ -339,32 +549,35 @@ buzz::XmlElement* WriteContent(const ContentInfo& content, } buzz::XmlElement* elem = NULL; - if (!parser->WriteContent(content.description, &elem, error)) + if (!parser->WriteContent(protocol, content.description, &elem, error)) return NULL; return elem; } -bool WriteGingleContents(const std::vector<ContentInfo>& contents, - const ContentParserMap& parsers, - XmlElements* elems, - WriteError* error) { +bool WriteGingleContentInfos(const ContentInfos& contents, + const ContentParserMap& parsers, + XmlElements* elems, + WriteError* error) { if (contents.size() == 1) { - buzz::XmlElement* elem = WriteContent(contents.front(), parsers, error); + buzz::XmlElement* elem = WriteContentInfo( + PROTOCOL_GINGLE, contents.front(), parsers, error); if (!elem) return false; elems->push_back(elem); } else if (contents.size() == 2 && - contents.at(0).type == NS_GINGLE_AUDIO && - contents.at(1).type == NS_GINGLE_VIDEO) { + contents.at(0).type == NS_JINGLE_RTP && + contents.at(1).type == NS_JINGLE_RTP) { // Special-case audio + video contents so that they are "merged" // into one "video" content. - buzz::XmlElement* audio = WriteContent(contents.at(0), parsers, error); + buzz::XmlElement* audio = WriteContentInfo( + PROTOCOL_GINGLE, contents.at(0), parsers, error); if (!audio) return false; - buzz::XmlElement* video = WriteContent(contents.at(1), parsers, error); + buzz::XmlElement* video = WriteContentInfo( + PROTOCOL_GINGLE, contents.at(1), parsers, error); if (!video) { delete audio; return false; @@ -380,100 +593,229 @@ bool WriteGingleContents(const std::vector<ContentInfo>& contents, return true; } -bool ParseFirstContentType(const buzz::XmlElement* action_elem, - std::string* content_type, - ParseError* error) { +const TransportInfo* GetTransportInfoByContentName( + const TransportInfos& tinfos, const std::string& content_name) { + for (TransportInfos::const_iterator tinfo = tinfos.begin(); + tinfo != tinfos.end(); ++tinfo) { + if (content_name == tinfo->content_name) { + return &*tinfo; + } + } + return NULL; +} + +bool WriteJingleContentPairs(const ContentInfos& contents, + const ContentParserMap& content_parsers, + const TransportInfos& tinfos, + const TransportParserMap& trans_parsers, + XmlElements* elems, + WriteError* error) { + for (ContentInfos::const_iterator content = contents.begin(); + content != contents.end(); ++content) { + const TransportInfo* tinfo = + GetTransportInfoByContentName(tinfos, content->name); + if (!tinfo) + return BadWrite("No transport for content: " + content->name, error); + + XmlElements pair_elems; + buzz::XmlElement* elem = WriteContentInfo( + PROTOCOL_JINGLE, *content, content_parsers, error); + if (!elem) + return false; + pair_elems.push_back(elem); + + if (!WriteJingleTransportInfo(*tinfo, trans_parsers, + &pair_elems, error)) + return false; + + WriteJingleContentPair(content->name, pair_elems, elems); + } + return true; +} + +bool ParseContentType(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, + std::string* content_type, + ParseError* error) { const buzz::XmlElement* content_elem; - return ParseGingleContentType( - action_elem, content_type, &content_elem, error); + if (protocol == PROTOCOL_GINGLE) { + if (!ParseContentType(action_elem, content_type, &content_elem, error)) + return false; + + // Internally, we only use NS_JINGLE_RTP. + if (*content_type == NS_GINGLE_AUDIO || + *content_type == NS_GINGLE_VIDEO) + *content_type = NS_JINGLE_RTP; + } else { + const buzz::XmlElement* pair_elem + = action_elem->FirstNamed(QN_JINGLE_CONTENT); + if (pair_elem == NULL) + return BadParse("No contents found", error); + + if (!ParseContentType(pair_elem, content_type, &content_elem, error)) + return false; + + // If there is more than one content type, return an error. + for (; pair_elem != NULL; + pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) { + std::string content_type2; + if (!ParseContentType(pair_elem, &content_type2, &content_elem, error)) + return false; + + if (content_type2 != *content_type) + return BadParse("More than one content type found", error); + } + } + + return true; } -bool ParseSessionInitiate(const buzz::XmlElement* action_elem, +bool ParseSessionInitiate(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, const ContentParserMap& content_parsers, - SessionInitiate* init, ParseError* error) { - if (!ParseGingleContents(action_elem, content_parsers, - &init->contents, error)) - return false; + const TransportParserMap& trans_parsers, + SessionInitiate* init, + ParseError* error) { + init->owns_contents = true; + if (protocol == PROTOCOL_GINGLE) { + if (!ParseGingleContentInfos(action_elem, content_parsers, + &init->contents, error)) + return false; - if (!ParseGingleTransportName(action_elem, &(init->transport_name), error)) - return false; + if (!ParseGingleTransportInfos(action_elem, init->contents, trans_parsers, + &init->transports, error)) + return false; + } else { + if (!ParseJingleContentInfos(action_elem, content_parsers, + &init->contents, error)) + return false; + + if (!ParseJingleTransportInfos(action_elem, init->contents, trans_parsers, + &init->transports, error)) + return false; + } return true; } -bool WriteSessionInitiate(const SessionInitiate& init, + +bool WriteSessionInitiate(SignalingProtocol protocol, + const ContentInfos& contents, + const TransportInfos& tinfos, const ContentParserMap& content_parsers, - SignalingProtocol protocol, + const TransportParserMap& transport_parsers, XmlElements* elems, WriteError* error) { - if (!WriteGingleContents(init.contents, content_parsers, elems, error)) - return false; + if (protocol == PROTOCOL_GINGLE) { + if (!WriteGingleContentInfos(contents, content_parsers, elems, error)) + return false; - // We don't have any candidates yet, so only send the transport - // name. Send candidates asynchronously later with transport-info - // or candidates messages. - if (!WriteGingleTransportWithoutCandidates( - init.transport_name, protocol, elems, error)) - return false; + if (!WriteGingleTransportInfos(tinfos, transport_parsers, + elems, error)) + return false; + } else { + if (!WriteJingleContentPairs(contents, content_parsers, + tinfos, transport_parsers, + elems, error)) + return false; + } return true; } -bool ParseSessionAccept(const buzz::XmlElement* action_elem, +bool ParseSessionAccept(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, const ContentParserMap& content_parsers, - SessionAccept* accept, ParseError* error) { - if (!ParseGingleContents(action_elem, content_parsers, - &accept->contents, error)) - return false; - - return true; + const TransportParserMap& transport_parsers, + SessionAccept* accept, + ParseError* error) { + return ParseSessionInitiate(protocol, action_elem, + content_parsers, transport_parsers, + accept, error); } -bool WriteSessionAccept(const SessionAccept& accept, +bool WriteSessionAccept(SignalingProtocol protocol, + const ContentInfos& contents, + const TransportInfos& tinfos, const ContentParserMap& content_parsers, + const TransportParserMap& transport_parsers, XmlElements* elems, WriteError* error) { - return WriteGingleContents(accept.contents, content_parsers, elems, error); + return WriteSessionInitiate(protocol, contents, tinfos, + content_parsers, transport_parsers, + elems, error); } -bool ParseSessionTerminate(const buzz::XmlElement* action_elem, - SessionTerminate* term, ParseError* error) { - const buzz::XmlElement* reason_elem = action_elem->FirstElement(); - if (reason_elem != NULL) { - term->reason = reason_elem->Name().LocalPart(); - const buzz::XmlElement *debug_elem = reason_elem->FirstElement(); - if (debug_elem != NULL) { - term->debug_reason = debug_elem->Name().LocalPart(); +bool ParseSessionTerminate(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, + SessionTerminate* term, + ParseError* error) { + if (protocol == PROTOCOL_GINGLE) { + const buzz::XmlElement* reason_elem = action_elem->FirstElement(); + if (reason_elem != NULL) { + term->reason = reason_elem->Name().LocalPart(); + const buzz::XmlElement *debug_elem = reason_elem->FirstElement(); + if (debug_elem != NULL) { + term->debug_reason = debug_elem->Name().LocalPart(); + } + } + return true; + } else { + const buzz::XmlElement* reason_elem = + action_elem->FirstNamed(QN_JINGLE_REASON); + if (reason_elem) { + reason_elem = reason_elem->FirstElement(); + if (reason_elem) { + term->reason = reason_elem->Name().LocalPart(); + } } + return true; } - return true; } -bool WriteSessionTerminate(const SessionTerminate& term, - XmlElements* elems, - WriteError* error) { - elems->push_back(new buzz::XmlElement( - buzz::QName(true, NS_EMPTY, term.reason))); - return true; +void WriteSessionTerminate(SignalingProtocol protocol, + const SessionTerminate& term, + XmlElements* elems) { + if (protocol == PROTOCOL_GINGLE) { + elems->push_back(new buzz::XmlElement( + buzz::QName(true, NS_GINGLE, term.reason))); + } else { + if (!term.reason.empty()) { + buzz::XmlElement* reason_elem = new buzz::XmlElement(QN_JINGLE_REASON); + reason_elem->AddElement(new buzz::XmlElement( + buzz::QName(true, NS_JINGLE, term.reason))); + elems->push_back(reason_elem); + } + } } -bool ParseTransportInfo(const buzz::XmlElement* action_elem, - const TransportParserMap& trans_parsers, - TransportInfo* info, ParseError* error) { - return ParseGingleTransport(action_elem, trans_parsers, - &(info->transport_name), &(info->candidates), - error); +bool ParseTransportInfos(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, + const ContentInfos& contents, + const TransportParserMap& trans_parsers, + TransportInfos* tinfos, + ParseError* error) { + if (protocol == PROTOCOL_GINGLE) { + return ParseGingleTransportInfos( + action_elem, contents, trans_parsers, tinfos, error); + } else { + return ParseJingleTransportInfos( + action_elem, contents, trans_parsers, tinfos, error); + } } -bool WriteTransportInfo(const TransportInfo& info, - const TransportParserMap& trans_parsers, - SignalingProtocol protocol, - XmlElements* elems, - WriteError* error) { - return WriteGingleTransport(info.transport_name, info.candidates, - trans_parsers, protocol, - elems, error); +bool WriteTransportInfos(SignalingProtocol protocol, + const TransportInfos& tinfos, + const TransportParserMap& trans_parsers, + XmlElements* elems, + WriteError* error) { + if (protocol == PROTOCOL_GINGLE) { + return WriteGingleTransportInfos(tinfos, trans_parsers, + elems, error); + } else { + return WriteJingleTransportInfos(tinfos, trans_parsers, + elems, error); + } } - } // namespace cricket diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmessages.h b/third_party/libjingle/source/talk/p2p/base/sessionmessages.h index 7ecf0b3..ff8641c 100644 --- a/third_party/libjingle/source/talk/p2p/base/sessionmessages.h +++ b/third_party/libjingle/source/talk/p2p/base/sessionmessages.h @@ -91,19 +91,32 @@ struct SessionMessage { const buzz::XmlElement* stanza; }; -struct SessionInitiate { - // Object will have ownership of contents. - SessionInitiate() : owns_contents(true) {} +// A TransportInfo is NOT a transport-info message. It is comparable +// to a "ContentInfo". A transport-info message is basically just a +// collection of TransportInfos. +struct TransportInfo { + TransportInfo() {} + + TransportInfo(const std::string& content_name, + const std::string& transport_type, + const Candidates& candidates) + : content_name(content_name), + transport_type(transport_type), + candidates(candidates) {} + + std::string content_name; + std::string transport_type; // xmlns of <transport> + Candidates candidates; +}; - // Caller retains ownership of contents. - SessionInitiate(const std::string& transport_name, - const std::vector<ContentInfo>& contents) : - transport_name(transport_name), - contents(contents), owns_contents(false) {} +typedef std::vector<TransportInfo> TransportInfos; + +struct SessionInitiate { + SessionInitiate() : owns_contents(false) {} ~SessionInitiate() { if (owns_contents) { - for (std::vector<ContentInfo>::iterator content = contents.begin(); + for (ContentInfos::iterator content = contents.begin(); content != contents.end(); content++) { delete content->description; } @@ -111,78 +124,90 @@ struct SessionInitiate { } // Caller takes ownership of contents. - std::vector<ContentInfo> AdoptContents() { - std::vector<ContentInfo> out; + ContentInfos ClearContents() { + ContentInfos out; contents.swap(out); + owns_contents = false; return out; } - std::string transport_name; // xmlns of <transport> - // TODO(pthatcher): Jingle spec allows candidates to be in the - // initiate. We should support receiving them. - std::vector<ContentInfo> contents; bool owns_contents; + ContentInfos contents; + TransportInfos transports; }; +// Right now, a SessionAccept is functionally equivalent to a SessionInitiate. typedef SessionInitiate SessionAccept; struct SessionTerminate { - std::string reason; - std::string debug_reason; -}; + SessionTerminate() {} -struct TransportInfo { - TransportInfo() {} - - TransportInfo(const std::string& transport_name, - const Candidates& candidates) : - transport_name(transport_name), candidates(candidates) {} - - std::string transport_name; // xmlns of <transport> - Candidates candidates; -}; + explicit SessionTerminate(const std::string& reason) : + reason(reason) {} -struct SessionReject { + std::string reason; + std::string debug_reason; }; bool IsSessionMessage(const buzz::XmlElement* stanza); bool ParseSessionMessage(const buzz::XmlElement* stanza, SessionMessage* msg, ParseError* error); -bool ParseFirstContentType(const buzz::XmlElement* action_elem, - std::string* content_type, - ParseError* error); +// Will return an error if there is more than one content type. +bool ParseContentType(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, + std::string* content_type, + ParseError* error); void WriteSessionMessage(const SessionMessage& msg, const XmlElements& action_elems, buzz::XmlElement* stanza); -bool ParseSessionInitiate(const buzz::XmlElement* action_elem, +bool ParseSessionInitiate(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, const ContentParserMap& content_parsers, - SessionInitiate* init, ParseError* error); -bool WriteSessionInitiate(const SessionInitiate& init, + const TransportParserMap& transport_parsers, + SessionInitiate* init, + ParseError* error); +bool WriteSessionInitiate(SignalingProtocol protocol, + const ContentInfos& contents, + const TransportInfos& tinfos, const ContentParserMap& content_parsers, - SignalingProtocol protocol, + const TransportParserMap& transport_parsers, XmlElements* elems, WriteError* error); -bool ParseSessionAccept(const buzz::XmlElement* action_elem, +bool ParseSessionAccept(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, const ContentParserMap& content_parsers, - SessionAccept* accept, ParseError* error); -bool WriteSessionAccept(const SessionAccept& accept, + const TransportParserMap& transport_parsers, + SessionAccept* accept, + ParseError* error); +bool WriteSessionAccept(SignalingProtocol protocol, + const ContentInfos& contents, + const TransportInfos& tinfos, const ContentParserMap& content_parsers, + const TransportParserMap& transport_parsers, XmlElements* elems, WriteError* error); -bool ParseSessionTerminate(const buzz::XmlElement* action_elem, - SessionTerminate* term, ParseError* error); -bool WriteSessionTerminate(const SessionAccept& term, - XmlElements* elems, - WriteError* error); -bool ParseTransportInfo(const buzz::XmlElement* action_elem, - const TransportParserMap& trans_parsers, - TransportInfo* info, ParseError* error); -bool WriteTransportInfo(const TransportInfo& info, - const TransportParserMap& trans_parsers, - SignalingProtocol protocol, - XmlElements* elems, - WriteError* error); +bool ParseSessionTerminate(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, + SessionTerminate* term, + ParseError* error); +void WriteSessionTerminate(SignalingProtocol protocol, + const SessionTerminate& term, + XmlElements* elems); +// Since a TransportInfo is not a transport-info message, and a +// transport-info message is just a collection of TransportInfos, we +// say Parse/Write TransportInfos for transport-info messages. +bool ParseTransportInfos(SignalingProtocol protocol, + const buzz::XmlElement* action_elem, + const ContentInfos& contents, + const TransportParserMap& trans_parsers, + TransportInfos* tinfos, + ParseError* error); +bool WriteTransportInfos(SignalingProtocol protocol, + const TransportInfos& tinfos, + const TransportParserMap& trans_parsers, + XmlElements* elems, + WriteError* error); } // namespace cricket #endif // TALK_P2P_BASE_SESSIONMESSAGES_H_ diff --git a/third_party/libjingle/source/talk/p2p/base/stunport.cc b/third_party/libjingle/source/talk/p2p/base/stunport.cc index 412a661..7f5dad7 100644 --- a/third_party/libjingle/source/talk/p2p/base/stunport.cc +++ b/third_party/libjingle/source/talk/p2p/base/stunport.cc @@ -35,7 +35,7 @@ namespace cricket { -// TODO(juberti): Move these to a common place (used in relayport too) +// TODO: Move these to a common place (used in relayport too) const int KEEPALIVE_DELAY = 10 * 1000; // 10 seconds - sort timeouts const int RETRY_DELAY = 50; // 50ms, from ICE spec const int RETRY_TIMEOUT = 50 * 1000; // ICE says 50 secs @@ -238,7 +238,7 @@ void StunPort::OnResolveResult(talk_base::SignalThread* t) { PrepareAddress(); } -// TODO(juberti): merge this with SendTo above. +// TODO: merge this with SendTo above. void StunPort::OnSendPacket(const void* data, size_t size, StunRequest* req) { StunPortBindingRequest* sreq = static_cast<StunPortBindingRequest*>(req); if (socket_->SendTo(data, size, sreq->server_addr()) < 0) diff --git a/third_party/libjingle/source/talk/p2p/base/tcpport.cc b/third_party/libjingle/source/talk/p2p/base/tcpport.cc index 3dfb838..806c258 100644 --- a/third_party/libjingle/source/talk/p2p/base/tcpport.cc +++ b/third_party/libjingle/source/talk/p2p/base/tcpport.cc @@ -121,7 +121,7 @@ int TCPPort::SendTo(const void* data, size_t size, if (!socket) { LOG_J(LS_ERROR, this) << "Attempted to send to an unknown destination, " << addr.ToString(); - return -1; // TODO(juberti): Set error_ + return -1; // TODO: Set error_ } int sent = socket->Send(data, size); @@ -147,7 +147,7 @@ void TCPPort::OnAcceptEvent(talk_base::AsyncSocket* socket) { Incoming incoming; talk_base::AsyncSocket* newsocket = socket->Accept(&incoming.addr); if (!newsocket) { - // TODO(juberti): Do something better like forwarding the error to the user. + // TODO: Do something better like forwarding the error to the user. LOG_J(LS_ERROR, this) << "TCP accept failed with error " << socket_->GetError(); return; @@ -189,7 +189,7 @@ TCPConnection::TCPConnection(TCPPort* port, const Candidate& candidate, : Connection(port, 0, candidate), socket_(socket), error_(0) { bool outgoing = (socket_ == NULL); if (outgoing) { - // TODO(juberti): Handle failures here (unlikely since TCP) + // TODO: Handle failures here (unlikely since TCP) socket_ = static_cast<talk_base::AsyncTCPSocket*>(port->CreatePacketSocket( (candidate.protocol() == "ssltcp") ? PROTO_SSLTCP : PROTO_TCP)); } else { @@ -215,7 +215,7 @@ TCPConnection::~TCPConnection() { int TCPConnection::Send(const void* data, size_t size) { if (write_state() != STATE_WRITABLE) { - // TODO(bpm): Should STATE_WRITE_TIMEOUT return a non-blocking error? + // TODO: Should STATE_WRITE_TIMEOUT return a non-blocking error? error_ = EWOULDBLOCK; return SOCKET_ERROR; } diff --git a/third_party/libjingle/source/talk/p2p/base/transport.cc b/third_party/libjingle/source/talk/p2p/base/transport.cc index b42269e..663a608 100644 --- a/third_party/libjingle/source/talk/p2p/base/transport.cc +++ b/third_party/libjingle/source/talk/p2p/base/transport.cc @@ -77,10 +77,12 @@ enum { MSG_CONNECTING = 12, }; -Transport::Transport(talk_base::Thread* worker_thread, const std::string& name, +Transport::Transport(talk_base::Thread* signaling_thread, + talk_base::Thread* worker_thread, + const std::string& type, PortAllocator* allocator) - : signaling_thread_(talk_base::Thread::Current()), - worker_thread_(worker_thread), name_(name), allocator_(allocator), + : signaling_thread_(signaling_thread), + worker_thread_(worker_thread), type_(type), allocator_(allocator), destroyed_(false), readable_(false), writable_(false), connect_requested_(false), allow_local_ips_(false) { } @@ -244,6 +246,30 @@ void Transport::CallChannels_w(TransportChannelFunc func) { } } +bool Transport::VerifyCandidate(const Candidate& cand, ParseError* error) { + if (cand.address().IsLocalIP() && !allow_local_ips_) + return BadParse("candidate has local IP address", error); + + // No address zero. + if (cand.address().IsAny()) { + return BadParse("candidate has address of zero", error); + } + + // Disallow all ports below 1024, except for 80 and 443 on public addresses. + int port = cand.address().port(); + if (port < 1024) { + if ((port != 80) && (port != 443)) + return BadParse( + "candidate has port below 1024, but not 80 or 443", error); + if (cand.address().IsPrivateIP()) { + return BadParse( + "candidate has port of 80 or 443 with private IP address", error); + } + } + + return true; +} + void Transport::OnRemoteCandidates(const std::vector<Candidate>& candidates) { for (std::vector<Candidate>::const_iterator iter = candidates.begin(); iter != candidates.end(); @@ -404,41 +430,22 @@ void Transport::OnMessage(talk_base::Message* msg) { } } -bool Transport::ParseAddress(const buzz::XmlElement* elem, - const buzz::QName& address_name, - const buzz::QName& port_name, - talk_base::SocketAddress* address, - ParseError* error) { - ASSERT(elem->HasAttr(address_name)); - ASSERT(elem->HasAttr(port_name)); +bool TransportParser::ParseAddress(const buzz::XmlElement* elem, + const buzz::QName& address_name, + const buzz::QName& port_name, + talk_base::SocketAddress* address, + ParseError* error) { + if (!elem->HasAttr(address_name)) + return BadParse("address does not have " + address_name.LocalPart(), error); + if (!elem->HasAttr(port_name)) + return BadParse("address does not have " + port_name.LocalPart(), error); - // Record the parts of the address. address->SetIP(elem->Attr(address_name)); std::istringstream ist(elem->Attr(port_name)); int port; ist >> port; address->SetPort(port); - // No address zero. - if (address->IsAny()) { - return BadParse("candidate has address of zero", error); - } - - // Always disallow addresses that refer to the local host. - if (address->IsLocalIP() && !allow_local_ips_) - return BadParse("candidate has local IP address", error); - - // Disallow all ports below 1024, except for 80 and 443 on public addresses. - if (port < 1024) { - if ((port != 80) && (port != 443)) - return BadParse( - "candidate has port below 1024, but not 80 or 443", error); - if (address->IsPrivateIP()) { - return BadParse( - "candidate has port of 80 or 443 with private IP address", error); - } - } - return true; } diff --git a/third_party/libjingle/source/talk/p2p/base/transport.h b/third_party/libjingle/source/talk/p2p/base/transport.h index 09068f7..d9a2d94 100644 --- a/third_party/libjingle/source/talk/p2p/base/transport.h +++ b/third_party/libjingle/source/talk/p2p/base/transport.h @@ -83,20 +83,33 @@ typedef std::vector<Candidate> Candidates; // Create/Translate. class TransportParser { public: - virtual bool ParseCandidates(const buzz::XmlElement* elem, + virtual bool ParseCandidates(SignalingProtocol protocol, + const buzz::XmlElement* elem, Candidates* candidates, ParseError* error) = 0; - virtual bool WriteCandidates(const Candidates& candidates, - SignalingProtocol protocol, + virtual bool WriteCandidates(SignalingProtocol protocol, + const Candidates& candidates, XmlElements* candidate_elems, WriteError* error) = 0; + + // Helper function to parse an element describing an address. This + // retrieves the IP and port from the given element and verifies + // that they look like plausible values. + bool ParseAddress(const buzz::XmlElement* elem, + const buzz::QName& address_name, + const buzz::QName& port_name, + talk_base::SocketAddress* address, + ParseError* error); + virtual ~TransportParser() {} }; -class Transport : public talk_base::MessageHandler, public sigslot::has_slots<>, - public TransportParser { +class Transport : public talk_base::MessageHandler, + public sigslot::has_slots<> { public: - Transport(talk_base::Thread* worker_thread, const std::string& name, + Transport(talk_base::Thread* signaling_thread, + talk_base::Thread* worker_thread, + const std::string& type, PortAllocator* allocator); virtual ~Transport(); @@ -105,8 +118,8 @@ class Transport : public talk_base::MessageHandler, public sigslot::has_slots<>, // Returns the worker thread. The actual networking is done on this thread. talk_base::Thread* worker_thread() { return worker_thread_; } - // Returns the name of this transport. - const std::string& name() const { return name_; } + // Returns the type of this transport. + const std::string& type() const { return type_; } // Returns the port allocator object for this transport. PortAllocator* port_allocator() { return allocator_; } @@ -160,11 +173,16 @@ class Transport : public talk_base::MessageHandler, public sigslot::has_slots<>, const std::vector<Candidate>&> SignalCandidatesReady; void OnRemoteCandidates(const std::vector<Candidate>& candidates); + // If candidate is not acceptable, returns false and sets error. + // Call this before calling OnRemoteCandidates. + virtual bool VerifyCandidate(const Candidate& candidate, + ParseError* error); + // A transport message has generated an transport-specific error. The // stanza that caused the error is available in session_msg. If false is // returned, the error is considered unrecoverable, and the session is // terminated. - // TODO(pthatcher): Make OnTransportError take an abstract data type + // TODO: Make OnTransportError take an abstract data type // rather than an XmlElement. It isn't needed yet, but it might be // later for Jingle compliance. virtual void OnTransportError(const buzz::XmlElement* error) {} @@ -190,14 +208,6 @@ class Transport : public talk_base::MessageHandler, public sigslot::has_slots<>, // Informs the subclass that we received the signaling ready message. virtual void OnTransportSignalingReady() {} - // Helper function to parse an element describing an address. This - // retrieves the IP and port from the given element and verifies - // that they look like plausible values. - bool ParseAddress(const buzz::XmlElement* elem, - const buzz::QName& address_name, - const buzz::QName& port_name, - talk_base::SocketAddress* address, - ParseError* error); private: typedef std::map<std::string, TransportChannelImpl*> ChannelMap; @@ -243,7 +253,7 @@ class Transport : public talk_base::MessageHandler, public sigslot::has_slots<>, talk_base::Thread* signaling_thread_; talk_base::Thread* worker_thread_; - std::string name_; + std::string type_; PortAllocator* allocator_; bool destroyed_; bool readable_; diff --git a/third_party/libjingle/source/talk/p2p/base/transportchannel.h b/third_party/libjingle/source/talk/p2p/base/transportchannel.h index a9384af..ff252bf 100644 --- a/third_party/libjingle/source/talk/p2p/base/transportchannel.h +++ b/third_party/libjingle/source/talk/p2p/base/transportchannel.h @@ -70,7 +70,7 @@ class TransportChannel: public sigslot::has_slots<> { // This hack is here to allow the SocketMonitor to downcast to the // P2PTransportChannel safely. - // TODO(juberti): Generalize network monitoring. + // TODO: Generalize network monitoring. virtual P2PTransportChannel* GetP2PChannel() { return NULL; } // Signalled each time a packet is received on this channel. diff --git a/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc b/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc index 0a5e163..3762b34 100644 --- a/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc +++ b/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc @@ -625,7 +625,7 @@ void AllocationSequence::OnMessage(talk_base::Message* msg) { } } - // TODO(juberti): use different delays for each stage + // TODO: use different delays for each stage step_ += 1; if (running_) { session_->network_thread()->PostDelayed(ALLOCATION_STEP_DELAY, diff --git a/third_party/libjingle/source/talk/session/phone/call.cc b/third_party/libjingle/source/talk/session/phone/call.cc index 8feddc9..c85be6a 100644 --- a/third_party/libjingle/source/talk/session/phone/call.cc +++ b/third_party/libjingle/source/talk/session/phone/call.cc @@ -35,8 +35,11 @@ namespace cricket { const uint32 MSG_CHECKAUTODESTROY = 1; const uint32 MSG_TERMINATECALL = 2; +const uint32 MSG_PLAYDTMF = 3; namespace { +const int kDTMFDelay = 300; // msec +const size_t kMaxDTMFDigits = 30; const int kSendToVoicemailTimeout = 1000*20; const int kNoVoicemailTimeout = 1000*180; const int kMediaMonitorInterval = 1000*15; @@ -45,8 +48,7 @@ const int kMediaMonitorInterval = 1000*15; Call::Call(MediaSessionClient *session_client, bool video, bool mux) : id_(talk_base::CreateRandomId()), session_client_(session_client), local_renderer_(NULL), video_(video), mux_(mux), - muted_(false), send_to_voicemail_(true) -{ + muted_(false), send_to_voicemail_(true), playing_dtmf_(false) { } Call::~Call() { @@ -59,10 +61,10 @@ Call::~Call() { } Session *Call::InitiateSession(const buzz::Jid &jid) { - Session *session = session_client_->CreateSession(this); - AddSession(session); - const SessionDescription* offer = session_client_->CreateOffer(video_, mux_); + + Session *session = session_client_->CreateSession(this); + AddSession(session, offer); session->Initiate(jid.Str(), offer); // After this timeout, terminate the call because the callee isn't @@ -75,6 +77,15 @@ Session *Call::InitiateSession(const buzz::Jid &jid) { return session; } +void Call::IncomingSession( + Session* session, const SessionDescription* offer) { + AddSession(session, offer); + + // Missed the first state, the initiate, which is needed by + // call_client. + SignalSessionState(this, session, Session::STATE_RECEIVEDINITIATE); +} + void Call::AcceptSession(BaseSession *session) { std::vector<Session *>::iterator it; it = std::find(sessions_.begin(), sessions_.end(), session); @@ -89,8 +100,9 @@ void Call::RejectSession(BaseSession *session) { std::vector<Session *>::iterator it; it = std::find(sessions_.begin(), sessions_.end(), session); ASSERT(it != sessions_.end()); + // Assume polite decline. if (it != sessions_.end()) - session->Reject(); + session->Reject(STR_TERMINATE_DECLINE); } void Call::TerminateSession(BaseSession *session) { @@ -98,6 +110,7 @@ void Call::TerminateSession(BaseSession *session) { != sessions_.end()); std::vector<Session *>::iterator it; it = std::find(sessions_.begin(), sessions_.end(), session); + // Assume polite terminations. if (it != sessions_.end()) (*it)->Terminate(); } @@ -168,6 +181,8 @@ void Call::OnMessage(talk_base::Message *message) { // Callee didn't answer - terminate call Terminate(); break; + case MSG_PLAYDTMF: + ContinuePlayDTMF(); } } @@ -175,14 +190,16 @@ const std::vector<Session *> &Call::sessions() { return sessions_; } -bool Call::AddSession(Session *session) { +bool Call::AddSession(Session *session, const SessionDescription* offer) { bool succeeded = true; VoiceChannel *voice_channel = NULL; VideoChannel *video_channel = NULL; + const ContentInfo* audio_offer = GetFirstAudioContent(offer); + ASSERT(audio_offer != NULL); // Create voice channel and start a media monitor voice_channel = session_client_->channel_manager()->CreateVoiceChannel( - session, video_); + session, audio_offer->name, video_); // voice_channel can be NULL in case of NullVoiceEngine. if (voice_channel) { voice_channel_map_[session->id()] = voice_channel; @@ -195,8 +212,10 @@ bool Call::AddSession(Session *session) { // If desired, create video channel and start a media monitor if (video_ && succeeded) { + const ContentInfo* video_offer = GetFirstVideoContent(offer); + ASSERT(video_offer != NULL); video_channel = session_client_->channel_manager()->CreateVideoChannel( - session, true, voice_channel); + session, video_offer->name, true, voice_channel); // video_channel can be NULL in case of NullVideoEngine. if (video_channel) { video_channel_map_[session->id()] = video_channel; @@ -240,7 +259,7 @@ void Call::RemoveSession(Session *session) { sessions_.erase(it_session); // Destroy video channel - std::map<SessionID, VideoChannel *>::iterator it_vchannel; + std::map<std::string, VideoChannel *>::iterator it_vchannel; it_vchannel = video_channel_map_.find(session->id()); if (it_vchannel != video_channel_map_.end()) { VideoChannel *video_channel = it_vchannel->second; @@ -249,7 +268,7 @@ void Call::RemoveSession(Session *session) { } // Destroy voice channel - std::map<SessionID, VoiceChannel *>::iterator it_channel; + std::map<std::string, VoiceChannel *>::iterator it_channel; it_channel = voice_channel_map_.find(session->id()); if (it_channel != voice_channel_map_.end()) { VoiceChannel *voice_channel = it_channel->second; @@ -265,13 +284,13 @@ void Call::RemoveSession(Session *session) { } VoiceChannel* Call::GetVoiceChannel(BaseSession* session) { - std::map<SessionID, VoiceChannel *>::iterator it + std::map<std::string, VoiceChannel *>::iterator it = voice_channel_map_.find(session->id()); return (it != voice_channel_map_.end()) ? it->second : NULL; } VideoChannel* Call::GetVideoChannel(BaseSession* session) { - std::map<SessionID, VideoChannel *>::iterator it + std::map<std::string, VideoChannel *>::iterator it = video_channel_map_.find(session->id()); return (it != video_channel_map_.end()) ? it->second : NULL; } @@ -300,6 +319,43 @@ void Call::Mute(bool mute) { } } +void Call::PressDTMF(int event) { + // Queue up this digit + if (queued_dtmf_.size() < kMaxDTMFDigits) { + LOG(LS_INFO) << "Call::PressDTMF(" << event << ")"; + + queued_dtmf_.push_back(event); + + if (!playing_dtmf_) { + ContinuePlayDTMF(); + } + } +} + +void Call::ContinuePlayDTMF() { + playing_dtmf_ = false; + + // Check to see if we have a queued tone + if (queued_dtmf_.size() > 0) { + playing_dtmf_ = true; + + int tone = queued_dtmf_.front(); + queued_dtmf_.pop_front(); + + LOG(LS_INFO) << "Call::ContinuePlayDTMF(" << tone << ")"; + std::vector<Session *>::iterator it; + for (it = sessions_.begin(); it != sessions_.end(); it++) { + VoiceChannel *voice_channel = voice_channel_map_[(*it)->id()]; + if (voice_channel != NULL) { + voice_channel->PressDTMF(tone, true); + } + } + + // Post a message to play the next tone or at least clear the playing_dtmf_ + // bit. + talk_base::Thread::Current()->PostDelayed(kDTMFDelay, this, MSG_PLAYDTMF); + } +} void Call::Join(Call *call, bool enable) { while (call->sessions_.size() != 0) { @@ -313,7 +369,7 @@ void Call::Join(Call *call, bool enable) { .connect(this, &Call::OnReceivedTerminateReason); // Move voice channel - std::map<SessionID, VoiceChannel *>::iterator it_channel; + std::map<std::string, VoiceChannel *>::iterator it_channel; it_channel = call->voice_channel_map_.find(session->id()); if (it_channel != call->voice_channel_map_.end()) { VoiceChannel *voice_channel = (*it_channel).second; @@ -323,7 +379,7 @@ void Call::Join(Call *call, bool enable) { } // Move video channel - std::map<SessionID, VideoChannel *>::iterator it_vchannel; + std::map<std::string, VideoChannel *>::iterator it_vchannel; it_vchannel = call->video_channel_map_.find(session->id()); if (it_vchannel != call->video_channel_map_.end()) { VideoChannel *video_channel = (*it_vchannel).second; diff --git a/third_party/libjingle/source/talk/session/phone/call.h b/third_party/libjingle/source/talk/session/phone/call.h index 8a1feba..de92086 100644 --- a/third_party/libjingle/source/talk/session/phone/call.h +++ b/third_party/libjingle/source/talk/session/phone/call.h @@ -40,7 +40,6 @@ #include "talk/session/phone/voicechannel.h" #include "talk/session/phone/audiomonitor.h" - namespace cricket { class MediaSessionClient; @@ -66,7 +65,7 @@ class Call : public talk_base::MessageHandler, public sigslot::has_slots<> { void StartAudioMonitor(BaseSession *session, int cms); void StopAudioMonitor(BaseSession *session); void Mute(bool mute); - + void PressDTMF(int event); const std::vector<Session *> &sessions(); uint32 id(); @@ -85,13 +84,18 @@ class Call : public talk_base::MessageHandler, public sigslot::has_slots<> { sigslot::signal0<> SignalSetupToCallVoicemail; sigslot::signal2<Call *, Session *> SignalAddSession; sigslot::signal2<Call *, Session *> SignalRemoveSession; - sigslot::signal3<Call *, BaseSession *, BaseSession::State> SignalSessionState; - sigslot::signal3<Call *, BaseSession *, Session::Error> SignalSessionError; - sigslot::signal3<Call *, Session *, const std::string &> SignalReceivedTerminateReason; - sigslot::signal2<Call *, const std::vector<ConnectionInfo> &> SignalConnectionMonitor; + sigslot::signal3<Call *, BaseSession *, BaseSession::State> + SignalSessionState; + sigslot::signal3<Call *, BaseSession *, Session::Error> + SignalSessionError; + sigslot::signal3<Call *, Session *, const std::string &> + SignalReceivedTerminateReason; + sigslot::signal2<Call *, const std::vector<ConnectionInfo> &> + SignalConnectionMonitor; sigslot::signal2<Call *, const MediaInfo&> SignalMediaMonitor; sigslot::signal2<Call *, const AudioInfo&> SignalAudioMonitor; - sigslot::signal2<Call *, const std::vector<ConnectionInfo> &> SignalVideoConnectionMonitor; + sigslot::signal2<Call *, const std::vector<ConnectionInfo> &> + SignalVideoConnectionMonitor; sigslot::signal2<Call *, const MediaInfo&> SignalVideoMediaMonitor; private: @@ -99,8 +103,9 @@ class Call : public talk_base::MessageHandler, public sigslot::has_slots<> { void OnSessionState(BaseSession *session, BaseSession::State state); void OnSessionError(BaseSession *session, Session::Error error); void OnReceivedTerminateReason(Session *session, const std::string &reason); + void IncomingSession(Session *session, const SessionDescription* offer); // Returns true on success. - bool AddSession(Session *session); + bool AddSession(Session *session, const SessionDescription* offer); void RemoveSession(Session *session); void EnableChannels(bool enable); void Join(Call *call, bool enable); @@ -113,22 +118,29 @@ class Call : public talk_base::MessageHandler, public sigslot::has_slots<> { void OnMediaMonitor(VideoChannel *channel, const MediaInfo& info); VoiceChannel* GetVoiceChannel(BaseSession* session); VideoChannel* GetVideoChannel(BaseSession* session); + void ContinuePlayDTMF(); uint32 id_; MediaSessionClient *session_client_; std::vector<Session *> sessions_; - std::map<SessionID, VoiceChannel *> voice_channel_map_; - std::map<SessionID, VideoChannel *> video_channel_map_; + std::map<std::string, VoiceChannel *> voice_channel_map_; + std::map<std::string, VideoChannel *> video_channel_map_; VideoRenderer* local_renderer_; bool video_; bool mux_; bool muted_; bool send_to_voicemail_; + // DTMF tones have to be queued up so that we don't flood the call. We + // keep a deque (doubely ended queue) of them around. While one is playing we + // set the playing_dtmf_ bit and schedule a message in XX msec to clear that + // bit or start the next tone playing. + std::deque<int> queued_dtmf_; + bool playing_dtmf_; friend class MediaSessionClient; }; -} +} // namespace cricket #endif // TALK_SESSION_PHONE_CALL_H_ diff --git a/third_party/libjingle/source/talk/session/phone/channel.cc b/third_party/libjingle/source/talk/session/phone/channel.cc index b59c0f1..5fb1dab 100644 --- a/third_party/libjingle/source/talk/session/phone/channel.cc +++ b/third_party/libjingle/source/talk/session/phone/channel.cc @@ -43,9 +43,11 @@ static const char* PacketType(bool rtcp) { BaseChannel::BaseChannel(talk_base::Thread* thread, MediaEngine* media_engine, MediaChannel* media_channel, BaseSession* session, + const std::string& content_name, TransportChannel* transport_channel) : worker_thread_(thread), media_engine_(media_engine), session_(session), media_channel_(media_channel), + content_name_(content_name), transport_channel_(transport_channel), rtcp_transport_channel_(NULL), enabled_(false), writable_(false), has_codec_(false), muted_(false) { ASSERT(worker_thread_ == talk_base::Thread::Current()); @@ -58,7 +60,6 @@ BaseChannel::BaseChannel(talk_base::Thread* thread, MediaEngine* media_engine, LOG(LS_INFO) << "Created channel"; session->SignalState.connect(this, &BaseChannel::OnSessionState); - OnSessionState(session, session->state()); } BaseChannel::~BaseChannel() { @@ -71,7 +72,7 @@ BaseChannel::~BaseChannel() { delete media_channel_; set_rtcp_transport_channel(NULL); if (transport_channel_ != NULL) - session_->DestroyChannel(transport_channel_); + session_->DestroyChannel(content_name_, transport_channel_->name()); LOG(LS_INFO) << "Destroyed channel"; } @@ -138,7 +139,7 @@ void BaseChannel::StopConnectionMonitor() { void BaseChannel::set_rtcp_transport_channel(TransportChannel* channel) { if (rtcp_transport_channel_ != channel) { if (rtcp_transport_channel_) { - session_->DestroyChannel(rtcp_transport_channel_); + session_->DestroyChannel(content_name_, rtcp_transport_channel_->name()); } rtcp_transport_channel_ = channel; if (rtcp_transport_channel_) { @@ -154,7 +155,7 @@ int BaseChannel::SendPacket(const void *data, size_t len) { // SendPacket gets called from MediaEngine; send to socket // MediaEngine will call us on a random thread. The Send operation on the // socket is special in that it can handle this. - // TODO(juberti): Actually, SendPacket cannot handle this. Need to fix ASAP. + // TODO: Actually, SendPacket cannot handle this. Need to fix ASAP. return SendPacket(false, data, len); } @@ -274,7 +275,7 @@ void BaseChannel::HandlePacket(bool rtcp, const char* data, size_t len) { void BaseChannel::OnSessionState(BaseSession* session, BaseSession::State state) { - // TODO(juberti): tear down the call via session->SetError() if the + // TODO: tear down the call via session->SetError() if the // SetXXXXDescription calls fail. const MediaContentDescription* content = NULL; switch (state) { @@ -482,13 +483,17 @@ VoiceChannel::VoiceChannel(talk_base::Thread* thread, MediaEngine* media_engine, VoiceMediaChannel* media_channel, BaseSession* session, + const std::string& content_name, bool rtcp) - : BaseChannel(thread, media_engine, media_channel, session, - session->CreateChannel("rtp")), + : BaseChannel(thread, media_engine, media_channel, session, content_name, + session->CreateChannel(content_name, "rtp")), received_media_(false) { if (rtcp) { - set_rtcp_transport_channel(session->CreateChannel("rtcp")); + set_rtcp_transport_channel(session->CreateChannel(content_name, "rtcp")); } + // Can't go in BaseChannel because certain session states will + // trigger pure virtual functions, such as GetFirstContent(). + OnSessionState(session, session->state()); } VoiceChannel::~VoiceChannel() { @@ -510,7 +515,7 @@ bool VoiceChannel::SetRingbackTone(const void* buf, int len) { return true; } -// TODO(juberti): Handle early media the right way. We should get an explicit +// TODO: Handle early media the right way. We should get an explicit // ringing message telling us to start playing local ringback, which we cancel // if any early media actually arrives. For now, we do the opposite, which is // to wait 1 second for early media, and start playing local ringback if none @@ -664,6 +669,8 @@ bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, if (ret) { ret = media_channel()->SetSendCodecs(audio->codecs()); } + + // update state if (ret) { set_has_codec(true); @@ -765,14 +772,20 @@ void VoiceChannel::OnAudioMonitorUpdate(AudioMonitor* monitor, VideoChannel::VideoChannel(talk_base::Thread* thread, MediaEngine* media_engine, VideoMediaChannel* media_channel, - BaseSession* session, bool rtcp, + BaseSession* session, + const std::string& content_name, + bool rtcp, VoiceChannel* voice_channel) - : BaseChannel(thread, media_engine, media_channel, session, - session->CreateChannel("video_rtp")), + : BaseChannel(thread, media_engine, media_channel, session, content_name, + session->CreateChannel(content_name, "video_rtp")), voice_channel_(voice_channel), renderer_(NULL) { if (rtcp) { - set_rtcp_transport_channel(session->CreateChannel("video_rtcp")); + set_rtcp_transport_channel( + session->CreateChannel(content_name, "video_rtcp")); } + // Can't go in BaseChannel because certain session states will + // trigger pure virtual functions, such as GetFirstContent() + OnSessionState(session, session->state()); } VideoChannel::~VideoChannel() { @@ -867,7 +880,7 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, bool ret; // set the sending SSRC, if the remote side gave us one - // TODO(juberti): remove this, since it's not needed. + // TODO: remove this, since it's not needed. if (video->ssrc_set()) { media_channel()->SetSendSsrc(video->ssrc()); } @@ -877,7 +890,7 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, if (ret) { ret = SetRtcpMux_w(video->rtcp_mux(), action, CS_REMOTE); } - // TODO(juberti): Set bandwidth appropriately here. + // TODO: Set bandwidth appropriately here. if (ret) { ret = media_channel()->SetSendCodecs(video->codecs()); } @@ -931,7 +944,7 @@ void VideoChannel::OnMediaMonitorUpdate( SignalMediaMonitor(this, info); } -// TODO(juberti): Move to own file in a future CL. +// TODO: Move to own file in a future CL. // Leaving here for now to avoid having to mess with the Mac build. RtcpMuxFilter::RtcpMuxFilter() : state_(ST_INIT), offer_enable_(false) { } diff --git a/third_party/libjingle/source/talk/session/phone/channel.h b/third_party/libjingle/source/talk/session/phone/channel.h index ff059bb..b7981d9 100644 --- a/third_party/libjingle/source/talk/session/phone/channel.h +++ b/third_party/libjingle/source/talk/session/phone/channel.h @@ -67,7 +67,7 @@ enum { MSG_SETRTCPCNAME = 18 }; -// TODO(juberti): Move to own file. +// TODO: Move to own file. class RtcpMuxFilter { public: RtcpMuxFilter(); @@ -93,7 +93,7 @@ class RtcpMuxFilter { // BaseChannel contains logic common to voice and video, including // enable/mute, marshaling calls to a worker thread, and // connection and media monitors. -// TODO(juberti): Break the dependency on BaseSession. The only thing we need +// TODO: Break the dependency on BaseSession. The only thing we need // it for is to Create/Destroy TransportChannels, and set codecs, both of which // could be done by the calling class. class BaseChannel @@ -102,7 +102,8 @@ class BaseChannel public: BaseChannel(talk_base::Thread* thread, MediaEngine* media_engine, MediaChannel* channel, BaseSession* session, - TransportChannel* transport); + const std::string& content_name, + TransportChannel* transport_channel); ~BaseChannel(); talk_base::Thread* worker_thread() const { return worker_thread_; } @@ -229,6 +230,7 @@ class BaseChannel MediaEngine *media_engine_; BaseSession *session_; MediaChannel *media_channel_; + std::string content_name_; TransportChannel *transport_channel_; TransportChannel *rtcp_transport_channel_; SrtpFilter srtp_filter_; @@ -245,7 +247,8 @@ class BaseChannel class VoiceChannel : public BaseChannel { public: VoiceChannel(talk_base::Thread *thread, MediaEngine *media_engine, - VoiceMediaChannel *channel, BaseSession *session, bool rtcp); + VoiceMediaChannel *channel, BaseSession *session, + const std::string& content_name, bool rtcp); ~VoiceChannel(); // downcasts a MediaChannel @@ -348,7 +351,8 @@ class VoiceChannel : public BaseChannel { class VideoChannel : public BaseChannel { public: VideoChannel(talk_base::Thread *thread, MediaEngine *media_engine, - VideoMediaChannel *channel, BaseSession *session, bool rtcp, + VideoMediaChannel *channel, BaseSession *session, + const std::string& content_name, bool rtcp, VoiceChannel *voice_channel); ~VideoChannel(); diff --git a/third_party/libjingle/source/talk/session/phone/channelmanager.cc b/third_party/libjingle/source/talk/session/phone/channelmanager.cc index 8affab0..901a20a 100644 --- a/third_party/libjingle/source/talk/session/phone/channelmanager.cc +++ b/third_party/libjingle/source/talk/session/phone/channelmanager.cc @@ -66,10 +66,15 @@ enum { }; struct CreationParams : public talk_base::MessageData { - CreationParams(BaseSession* s, bool r, VoiceChannel* c) - : transport_factory(s), rtcp(r), voice_channel(c), + CreationParams(BaseSession* session, const std::string& content_name, + bool rtcp, VoiceChannel* voice_channel) + : session(session), + content_name(content_name), + rtcp(rtcp), + voice_channel(voice_channel), video_channel(NULL) {} - BaseSession* transport_factory; + BaseSession* session; + std::string content_name; bool rtcp; VoiceChannel* voice_channel; VideoChannel* video_channel; @@ -232,7 +237,7 @@ bool ChannelManager::Init() { audio_out_device_.clear(); } if (!SetVideoOptions(camera_device_)) { - // TODO(juberti): Consider resetting to the default cam here. + // TODO: Consider resetting to the default cam here. camera_device_.clear(); } // Now apply the default video codec that has been set earlier. @@ -269,14 +274,14 @@ void ChannelManager::Terminate() { initialized_ = false; } -VoiceChannel* ChannelManager::CreateVoiceChannel(BaseSession* session, - bool rtcp) { - CreationParams params(session, rtcp, NULL); +VoiceChannel* ChannelManager::CreateVoiceChannel( + BaseSession* session, const std::string& content_name, bool rtcp) { + CreationParams params(session, content_name, rtcp, NULL); return (Send(MSG_CREATEVOICECHANNEL, ¶ms)) ? params.voice_channel : NULL; } -VoiceChannel* ChannelManager::CreateVoiceChannel_w(BaseSession* session, - bool rtcp) { +VoiceChannel* ChannelManager::CreateVoiceChannel_w( + BaseSession* session, const std::string& content_name, bool rtcp) { talk_base::CritScope cs(&crit_); // This is ok to alloc from a thread other than the worker thread @@ -285,9 +290,9 @@ VoiceChannel* ChannelManager::CreateVoiceChannel_w(BaseSession* session, if (media_channel == NULL) return NULL; - VoiceChannel* voice_channel = new VoiceChannel(worker_thread_, - media_engine_.get(), - media_channel, session, rtcp); + VoiceChannel* voice_channel = new VoiceChannel( + worker_thread_, media_engine_.get(), media_channel, + session, content_name, rtcp); voice_channels_.push_back(voice_channel); return voice_channel; } @@ -313,16 +318,16 @@ void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) { delete voice_channel; } -VideoChannel* ChannelManager::CreateVideoChannel(BaseSession* session, - bool rtcp, - VoiceChannel* voice_channel) { - CreationParams params(session, rtcp, voice_channel); +VideoChannel* ChannelManager::CreateVideoChannel( + BaseSession* session, const std::string& content_name, bool rtcp, + VoiceChannel* voice_channel) { + CreationParams params(session, content_name, rtcp, voice_channel); return (Send(MSG_CREATEVIDEOCHANNEL, ¶ms)) ? params.video_channel : NULL; } -VideoChannel* ChannelManager::CreateVideoChannel_w(BaseSession* session, - bool rtcp, - VoiceChannel* voice_channel) { +VideoChannel* ChannelManager::CreateVideoChannel_w( + BaseSession* session, const std::string& content_name, bool rtcp, + VoiceChannel* voice_channel) { talk_base::CritScope cs(&crit_); // This is ok to alloc from a thread other than the worker thread @@ -334,10 +339,9 @@ VideoChannel* ChannelManager::CreateVideoChannel_w(BaseSession* session, if (media_channel == NULL) return NULL; - VideoChannel* video_channel = new VideoChannel(worker_thread_, - media_engine_.get(), - media_channel, - session, rtcp, voice_channel); + VideoChannel* video_channel = new VideoChannel( + worker_thread_, media_engine_.get(), media_channel, + session, content_name, rtcp, voice_channel); video_channels_.push_back(video_channel); return video_channel; } @@ -450,9 +454,6 @@ bool ChannelManager::SetAudioOptions_w(int opts, const Device* in_dev, // Set the audio devices if (ret) { - // Need to grab the critsection for this because SetSoundDevices in GIPS - // relies on a list of channels and our Terminate() method destroys channels - // from a different thread. talk_base::CritScope cs(&crit_); ret = media_engine_->SetSoundDevices(in_dev, out_dev); } @@ -501,8 +502,6 @@ bool ChannelManager::SetVideoOptions(const std::string& cam_name) { // If we're running, tell the media engine about it. if (ret && initialized_) { #ifdef OSX - // Defer SequenceGrabber queries until call time as they can spin up the - // high power GPU. Can remove once LMI moves to QTKit enumeration. Device sg_device; ret = device_manager_->QtKitToSgDevice(device.name, &sg_device); if (ret) { @@ -650,7 +649,8 @@ void ChannelManager::OnMessage(talk_base::Message* message) { switch (message->message_id) { case MSG_CREATEVOICECHANNEL: { CreationParams* p = static_cast<CreationParams*>(data); - p->voice_channel = CreateVoiceChannel_w(p->transport_factory, p->rtcp); + p->voice_channel = + CreateVoiceChannel_w(p->session, p->content_name, p->rtcp); break; } case MSG_DESTROYVOICECHANNEL: { @@ -661,7 +661,7 @@ void ChannelManager::OnMessage(talk_base::Message* message) { } case MSG_CREATEVIDEOCHANNEL: { CreationParams* p = static_cast<CreationParams*>(data); - p->video_channel = CreateVideoChannel_w(p->transport_factory, + p->video_channel = CreateVideoChannel_w(p->session, p->content_name, p->rtcp, p->voice_channel); break; } diff --git a/third_party/libjingle/source/talk/session/phone/channelmanager.h b/third_party/libjingle/source/talk/session/phone/channelmanager.h index 2c17fdb..c5ff45a 100644 --- a/third_party/libjingle/source/talk/session/phone/channelmanager.h +++ b/third_party/libjingle/source/talk/session/phone/channelmanager.h @@ -95,7 +95,7 @@ class ChannelManager : public talk_base::MessageHandler, bool initialized() const { return initialized_; } // Starts up the media engine. bool Init(); - // TODO(juberti): Remove this temporary API once Flute is updated. + // TODO: Remove this temporary API once Flute is updated. bool Init(talk_base::Thread* thread) { return set_worker_thread(thread) && Init(); } @@ -105,13 +105,15 @@ class ChannelManager : public talk_base::MessageHandler, // The operations below all occur on the worker thread. // Creates a voice channel, to be associated with the specified session. - VoiceChannel* CreateVoiceChannel(BaseSession* session, bool rtcp); + VoiceChannel* CreateVoiceChannel( + BaseSession* session, const std::string& content_name, bool rtcp); // Destroys a voice channel created with the Create API. void DestroyVoiceChannel(VoiceChannel* voice_channel); // Creates a video channel, synced with the specified voice channel, and // associated with the specified session. - VideoChannel* CreateVideoChannel(BaseSession* session, bool rtcp, - VoiceChannel* voice_channel); + VideoChannel* CreateVideoChannel( + BaseSession* session, const std::string& content_name, bool rtcp, + VoiceChannel* voice_channel); // Destroys a video channel created with the Create API. void DestroyVideoChannel(VideoChannel* video_channel); @@ -164,10 +166,12 @@ class ChannelManager : public talk_base::MessageHandler, void Construct(); bool Send(uint32 id, talk_base::MessageData* pdata); - VoiceChannel* CreateVoiceChannel_w(BaseSession* session, bool rtcp); + VoiceChannel* CreateVoiceChannel_w( + BaseSession* session, const std::string& content_name, bool rtcp); void DestroyVoiceChannel_w(VoiceChannel* voice_channel); - VideoChannel* CreateVideoChannel_w(BaseSession* session, bool rtcp, - VoiceChannel* voice_channel); + VideoChannel* CreateVideoChannel_w( + BaseSession* session, const std::string& content_name, bool rtcp, + VoiceChannel* voice_channel); void DestroyVideoChannel_w(VideoChannel* video_channel); Soundclip* CreateSoundclip_w(); void DestroySoundclip_w(Soundclip* soundclip); diff --git a/third_party/libjingle/source/talk/session/phone/codec.cc b/third_party/libjingle/source/talk/session/phone/codec.cc index ba617da..01d1a7b 100644 --- a/third_party/libjingle/source/talk/session/phone/codec.cc +++ b/third_party/libjingle/source/talk/session/phone/codec.cc @@ -33,8 +33,22 @@ namespace cricket { static const int kMaxStaticPayloadId = 95; bool AudioCodec::Matches(int payload, const std::string& nm) const { - return (id <= kMaxStaticPayloadId && id == payload) || - (id > kMaxStaticPayloadId && name == nm); + // Match the codec id/name based on the typical static/dynamic name rules. + return (payload <= kMaxStaticPayloadId) ? (id == payload) : (name == nm); +} + +bool AudioCodec::Matches(const AudioCodec& codec) const { + // If a nonzero clockrate is specified, it must match the actual clockrate. + // If a nonzero bitrate is specified, it must match the actual bitrate, + // unless the codec is VBR (-1), where we just force the supplied value. + // The number of channels must match exactly. + // Preference is ignored. + // TODO: Treat a zero clockrate as 8000Hz, the RTP default clockrate. + return Matches(codec.id, codec.name) && + ((codec.clockrate == 0 /*&& clockrate == 8000*/) || + clockrate == codec.clockrate) && + (codec.bitrate == 0 || bitrate == -1 || bitrate == codec.bitrate) && + (codec.channels == 0 || channels == codec.channels); } std::string AudioCodec::ToString() const { @@ -45,8 +59,13 @@ std::string AudioCodec::ToString() const { } bool VideoCodec::Matches(int payload, const std::string& nm) const { - return (id <= kMaxStaticPayloadId && id == payload) || - (id > kMaxStaticPayloadId && name == nm); + // Match the codec id/name based on the typical static/dynamic name rules. + return (payload <= kMaxStaticPayloadId) ? (id == payload) : (name == nm); +} + +bool VideoCodec::Matches(const VideoCodec& codec) const { + // Only the id and name are matched. + return Matches(codec.id, codec.name); } std::string VideoCodec::ToString() const { diff --git a/third_party/libjingle/source/talk/session/phone/codec.h b/third_party/libjingle/source/talk/session/phone/codec.h index 4a3105b..8536dbb 100644 --- a/third_party/libjingle/source/talk/session/phone/codec.h +++ b/third_party/libjingle/source/talk/session/phone/codec.h @@ -49,7 +49,9 @@ struct AudioCodec { // Creates an empty codec. AudioCodec() : id(0), clockrate(0), bitrate(0), channels(0), preference(0) {} + // Indicates if this codec is compatible with the specified codec. bool Matches(int payload, const std::string& nm) const; + bool Matches(const AudioCodec& codec) const; static bool Preferable(const AudioCodec& first, const AudioCodec& other) { return first.preference > other.preference; @@ -99,6 +101,7 @@ struct VideoCodec { : id(0), width(0), height(0), framerate(0), preference(0) {} bool Matches(int payload, const std::string& nm) const; + bool Matches(const VideoCodec& codec) const; static bool Preferable(const VideoCodec& first, const VideoCodec& other) { return first.preference > other.preference; diff --git a/third_party/libjingle/source/talk/session/phone/devicemanager.cc b/third_party/libjingle/source/talk/session/phone/devicemanager.cc index bbff3fd..e32ed63 100644 --- a/third_party/libjingle/source/talk/session/phone/devicemanager.cc +++ b/third_party/libjingle/source/talk/session/phone/devicemanager.cc @@ -82,7 +82,7 @@ class DeviceWatcher : public talk_base::Win32Window { HDEVNOTIFY video_notify_; }; #else -// TODO(juberti): Implement this for other platforms. +// TODO: Implement this for other platforms. class DeviceWatcher { public: explicit DeviceWatcher(DeviceManager* dm) {} @@ -417,7 +417,7 @@ bool DeviceManager::GetAudioDevicesByPlatform(bool input, char name[128]; talk_base::sprintfn(name, sizeof(name), "%s (%s)", card_name, snd_pcm_info_get_name(pcminfo)); - // TODO(tschmelcher): We might want to identify devices with something + // TODO: We might want to identify devices with something // more specific than just their card number (e.g., the PCM names that // aplay -L prints out). devs->push_back(Device(name, card)); @@ -436,7 +436,7 @@ bool DeviceManager::GetAudioDevicesByPlatform(bool input, #if defined(WIN32) bool GetVideoDevices(std::vector<Device>* devices) { - // TODO(juberti): Move the CoInit stuff to Initialize/Terminate. + // TODO: Move the CoInit stuff to Initialize/Terminate. HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (FAILED(hr)) { LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr; @@ -902,7 +902,7 @@ static bool GetVideoDevices(std::vector<Device>* devices) { } #endif -// TODO(tommyw): Try to get hold of a copy of Final Cut to understand why we +// TODO: Try to get hold of a copy of Final Cut to understand why we // crash while scanning their components on OS X. #ifndef LINUX static bool ShouldDeviceBeIgnored(const std::string& device_name) { diff --git a/third_party/libjingle/source/talk/session/phone/filemediaengine.cc b/third_party/libjingle/source/talk/session/phone/filemediaengine.cc new file mode 100644 index 0000000..4929933 --- /dev/null +++ b/third_party/libjingle/source/talk/session/phone/filemediaengine.cc @@ -0,0 +1,230 @@ +// libjingle +// Copyright 2004--2005, Google Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// 3. The name of the author may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "talk/session/phone/filemediaengine.h" + +#include "talk/base/event.h" +#include "talk/base/logging.h" +#include "talk/base/pathutils.h" +#include "talk/base/stream.h" +#include "talk/session/phone/rtpdump.h" + +namespace cricket { + +/////////////////////////////////////////////////////////////////////////// +// Implementation of FileMediaEngine. +/////////////////////////////////////////////////////////////////////////// +int FileMediaEngine::GetCapabilities() { + int capabilities = 0; + if (!voice_input_filename_.empty()) { + capabilities |= MediaEngine::AUDIO_SEND; + } + if (!voice_output_filename_.empty()) { + capabilities |= MediaEngine::AUDIO_RECV; + } + if (!video_input_filename_.empty()) { + capabilities |= MediaEngine::VIDEO_SEND; + } + if (!video_output_filename_.empty()) { + capabilities |= MediaEngine::VIDEO_RECV; + } + return capabilities; +} + +VoiceMediaChannel* FileMediaEngine::CreateChannel() { + if (!voice_input_filename_.empty() || !voice_output_filename_.empty()) { + return new FileVoiceChannel(voice_input_filename_, voice_output_filename_); + } else { + return NULL; + } +} + +VideoMediaChannel* FileMediaEngine::CreateVideoChannel( + VoiceMediaChannel* voice_ch) { + if (!video_input_filename_.empty() || !video_output_filename_.empty()) { + return new FileVideoChannel(video_input_filename_, video_output_filename_); + } else { + return NULL; + } +} + +/////////////////////////////////////////////////////////////////////////// +// Definition of RtpSenderReceiver. +/////////////////////////////////////////////////////////////////////////// +class RtpSenderReceiver + : public talk_base::Thread, public talk_base::MessageHandler { + public: + RtpSenderReceiver(MediaChannel* channel, const std::string& in_file, + const std::string& out_file); + + // Called by media channel. Context: media channel thread. + bool SetSend(bool send); + void OnPacketReceived(const void* data, int len); + + // Override virtual method of parent MessageHandler. Context: Worker Thread. + virtual void OnMessage(talk_base::Message* pmsg); + + private: + // Send a RTP packet to the network. The input parameter data points to the + // start of the RTP packet and len is the packet size. Return true if the sent + // size is equal to len. + bool SendRtpPacket(const void* data, size_t len); + + MediaChannel* media_channel_; + talk_base::scoped_ptr<talk_base::StreamInterface> input_stream_; + talk_base::scoped_ptr<talk_base::StreamInterface> output_stream_; + talk_base::scoped_ptr<RtpDumpLoopReader> rtp_dump_reader_; + talk_base::scoped_ptr<RtpDumpWriter> rtp_dump_writer_; + // RTP dump packet read from the input stream. + RtpDumpPacket rtp_dump_packet_; + bool sending_; + bool first_packet_; + + DISALLOW_COPY_AND_ASSIGN(RtpSenderReceiver); +}; + +/////////////////////////////////////////////////////////////////////////// +// Implementation of RtpSenderReceiver. +/////////////////////////////////////////////////////////////////////////// +RtpSenderReceiver::RtpSenderReceiver(MediaChannel* channel, + const std::string& in_file, + const std::string& out_file) + : media_channel_(channel), + sending_(false), + first_packet_(true) { + input_stream_.reset(talk_base::Filesystem::OpenFile( + talk_base::Pathname(in_file), "rb")); + if (input_stream_.get()) { + rtp_dump_reader_.reset(new RtpDumpLoopReader(input_stream_.get())); + // Start the sender thread, which reads rtp dump records, waits based on + // the record timestamps, and sends the RTP packets to the network. + Thread::Start(); + } + + // Create a rtp dump writer for the output RTP dump stream. + output_stream_.reset(talk_base::Filesystem::OpenFile( + talk_base::Pathname(out_file), "wb")); + if (output_stream_.get()) { + rtp_dump_writer_.reset(new RtpDumpWriter(output_stream_.get())); + } +} + +bool RtpSenderReceiver::SetSend(bool send) { + bool was_sending = sending_; + sending_ = send; + if (!was_sending && sending_) { + PostDelayed(0, this); // Wake up the send thread. + } + return true; +} + +void RtpSenderReceiver::OnPacketReceived(const void* data, int len) { + if (rtp_dump_writer_.get()) { + rtp_dump_writer_->WriteRtpPacket(data, len); + } +} + +void RtpSenderReceiver::OnMessage(talk_base::Message* pmsg) { + if (!sending_) { + // If the sender thread is not sending, ignore this message. The thread goes + // to sleep until SetSend(true) wakes it up. + return; + } + + uint32 prev_elapsed_time = 0xFFFFFFFF; + if (!first_packet_) { + prev_elapsed_time = rtp_dump_packet_.elapsed_time; + SendRtpPacket(&rtp_dump_packet_.data[0], rtp_dump_packet_.data.size()); + } else { + first_packet_ = false; + } + + // Read a dump packet and wait for the elapsed time. + if (talk_base::SR_SUCCESS == + rtp_dump_reader_->ReadPacket(&rtp_dump_packet_)) { + int waiting_time_ms = rtp_dump_packet_.elapsed_time > prev_elapsed_time ? + rtp_dump_packet_.elapsed_time - prev_elapsed_time : 0; + PostDelayed(waiting_time_ms, this); + } else { + Quit(); + } +} + +bool RtpSenderReceiver::SendRtpPacket(const void* data, size_t len) { + if (!media_channel_ || !media_channel_->network_interface()) { + return false; + } + + return media_channel_->network_interface()->SendPacket(data, len) == + static_cast<int>(len); +} + +/////////////////////////////////////////////////////////////////////////// +// Implementation of FileVoiceChannel. +/////////////////////////////////////////////////////////////////////////// +FileVoiceChannel::FileVoiceChannel(const std::string& in_file, + const std::string& out_file) + : rtp_sender_receiver_(new RtpSenderReceiver(this, in_file, out_file)) { +} + +FileVoiceChannel::~FileVoiceChannel() {} + +bool FileVoiceChannel::SetSendCodecs(const std::vector<AudioCodec>& codecs) { + // TODO: Check the format of RTP dump input. + return true; +} + +bool FileVoiceChannel::SetSend(SendFlags flag) { + return rtp_sender_receiver_->SetSend(flag != SEND_NOTHING); +} + +void FileVoiceChannel::OnPacketReceived(const void* data, int len) { + rtp_sender_receiver_->OnPacketReceived(data, len); +} + +/////////////////////////////////////////////////////////////////////////// +// Implementation of FileVideoChannel. +/////////////////////////////////////////////////////////////////////////// +FileVideoChannel::FileVideoChannel(const std::string& in_file, + const std::string& out_file) + : rtp_sender_receiver_(new RtpSenderReceiver(this, in_file, out_file)) { +} + +FileVideoChannel::~FileVideoChannel() {} + +bool FileVideoChannel::SetSendCodecs(const std::vector<VideoCodec>& codecs) { + // TODO: Check the format of RTP dump input. + return true; +} + +bool FileVideoChannel::SetSend(bool send) { + return rtp_sender_receiver_->SetSend(send); +} + +void FileVideoChannel::OnPacketReceived(const void* data, int len) { + rtp_sender_receiver_->OnPacketReceived(data, len); +} + +} // namespace cricket diff --git a/third_party/libjingle/source/talk/session/phone/filemediaengine.h b/third_party/libjingle/source/talk/session/phone/filemediaengine.h new file mode 100644 index 0000000..272449a --- /dev/null +++ b/third_party/libjingle/source/talk/session/phone/filemediaengine.h @@ -0,0 +1,195 @@ +// libjingle +// Copyright 2004--2005, Google Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// 3. The name of the author may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef TALK_SESSION_PHONE_FILEMEDIAENGINE_H_ +#define TALK_SESSION_PHONE_FILEMEDIAENGINE_H_ + +#include <string> +#include <vector> + +#include "talk/base/scoped_ptr.h" +#include "talk/session/phone/codec.h" +#include "talk/session/phone/mediachannel.h" +#include "talk/session/phone/mediaengine.h" + +namespace talk_base { +class StreamInterface; +} + +namespace cricket { + +// A media engine contains a capturer, an encoder, and a sender in the sender +// side and a receiver, a decoder, and a renderer in the receiver side. +// FileMediaEngine simulates the capturer and the encoder via an input RTP dump +// stream and simulates the decoder and the renderer via an output RTP dump +// stream. Depending on the parameters of the constructor, FileMediaEngine can +// act as file voice engine, file video engine, or both. Currently, we use +// only the RTP dump packets. TODO: Enable RTCP packets. +class FileMediaEngine : public MediaEngine { + public: + FileMediaEngine() {} + virtual ~FileMediaEngine() {} + + // Set the file name of the input or output RTP dump for voice or video. + // Should be called before the channel is created. + void set_voice_input_filename(const std::string& filename) { + voice_input_filename_ = filename; + } + void set_voice_output_filename(const std::string& filename) { + voice_output_filename_ = filename; + } + void set_video_input_filename(const std::string& filename) { + video_input_filename_ = filename; + } + void set_video_output_filename(const std::string& filename) { + video_output_filename_ = filename; + } + + // Should be called before codecs() and video_codecs() are called. We need to + // set the voice and video codecs; otherwise, Jingle initiation will fail. + void set_voice_codecs(const std::vector<AudioCodec>& codecs) { + voice_codecs_ = codecs; + } + void set_video_codecs(const std::vector<VideoCodec>& codecs) { + video_codecs_ = codecs; + } + + // Implement pure virtual methods of MediaEngine. + virtual bool Init() { return true; } + virtual void Terminate() {} + virtual int GetCapabilities(); + virtual VoiceMediaChannel* CreateChannel(); + virtual VideoMediaChannel* CreateVideoChannel(VoiceMediaChannel* voice_ch); + virtual SoundclipMedia* CreateSoundclip() { return NULL; } + virtual bool SetAudioOptions(int options) { return true; } + virtual bool SetVideoOptions(int options) { return true; } + virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) { + return true; + } + virtual bool SetSoundDevices(const Device* in_dev, const Device* out_dev) { + return true; + } + virtual bool SetVideoCaptureDevice(const Device* cam_device) { return true; } + virtual bool SetOutputVolume(int level) { return true; } + virtual int GetInputLevel() { return 0; } + virtual bool SetLocalMonitor(bool enable) { return true; } + virtual bool SetLocalRenderer(VideoRenderer* renderer) { return true; } + // TODO: control channel send? + virtual CaptureResult SetVideoCapture(bool capture) { return CR_SUCCESS; } + virtual const std::vector<AudioCodec>& audio_codecs() { + return voice_codecs_; + } + virtual const std::vector<VideoCodec>& video_codecs() { + return video_codecs_; + } + virtual bool FindAudioCodec(const AudioCodec& codec) { return true; } + virtual bool FindVideoCodec(const VideoCodec& codec) { return true; } + virtual void SetVoiceLogging(int min_sev, const char* filter) {} + virtual void SetVideoLogging(int min_sev, const char* filter) {} + + private: + std::string voice_input_filename_; + std::string voice_output_filename_; + std::string video_input_filename_; + std::string video_output_filename_; + std::vector<AudioCodec> voice_codecs_; + std::vector<VideoCodec> video_codecs_; + + DISALLOW_COPY_AND_ASSIGN(FileMediaEngine); +}; + +class RtpSenderReceiver; // Forward declaration. Defined in the .cc file. + +class FileVoiceChannel : public VoiceMediaChannel { + public: + FileVoiceChannel(const std::string& in_file, const std::string& out_file); + virtual ~FileVoiceChannel(); + + // Implement pure virtual methods of VoiceMediaChannel. + virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) { + return true; + } + virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs); + virtual bool SetPlayout(bool playout) { return true; } + virtual bool SetSend(SendFlags flag); + virtual bool AddStream(uint32 ssrc) { return true; } + virtual bool RemoveStream(uint32 ssrc) { return true; } + virtual bool GetActiveStreams(AudioInfo::StreamList* actives) { return true; } + virtual int GetOutputLevel() { return 0; } + virtual void SetRingbackTone(const char* buf, int len) {} + virtual bool PlayRingbackTone(bool play, bool loop) { return true; } + virtual bool PressDTMF(int event, bool playout) { return true; } + virtual bool GetStats(VoiceMediaInfo* info) { return true; } + + // Implement pure virtual methods of MediaChannel. + virtual void OnPacketReceived(const void* data, int len); + virtual void OnRtcpReceived(const void* data, int len) {} + virtual void SetSendSsrc(uint32 id) {} // TODO: change RTP packet? + virtual bool SetRtcpCName(const std::string& cname) { return true; } + virtual bool Mute(bool on) { return false; } + virtual bool SetMaxSendBandwidth(int max_bandwidth) { return true; } + virtual bool SetOptions(int options) { return true; } + + private: + talk_base::scoped_ptr<RtpSenderReceiver> rtp_sender_receiver_; + DISALLOW_COPY_AND_ASSIGN(FileVoiceChannel); +}; + +class FileVideoChannel : public VideoMediaChannel { + public: + FileVideoChannel(const std::string& in_file, const std::string& out_file); + virtual ~FileVideoChannel(); + + // Implement pure virtual methods of VideoMediaChannel. + virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) { + return true; + } + virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs); + virtual bool SetRender(bool render) { return true; } + virtual bool SetSend(bool send); + virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc) { return true; } + virtual bool RemoveStream(uint32 ssrc) { return true; } + virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) { + return true; + } + virtual bool GetStats(VoiceMediaInfo* info) { return true; } + + // Implement pure virtual methods of MediaChannel. + virtual void OnPacketReceived(const void* data, int len); + virtual void OnRtcpReceived(const void* data, int len) {} + virtual void SetSendSsrc(uint32 id) {} // TODO: change RTP packet? + virtual bool SetRtcpCName(const std::string& cname) { return true; } + virtual bool Mute(bool on) { return false; } + virtual bool SetMaxSendBandwidth(int max_bandwidth) { return true; } + virtual bool SetOptions(int options) { return true; } + + private: + talk_base::scoped_ptr<RtpSenderReceiver> rtp_sender_receiver_; + DISALLOW_COPY_AND_ASSIGN(FileVideoChannel); +}; + +} // namespace cricket + +#endif // TALK_SESSION_PHONE_FILEMEDIAENGINE_H_ diff --git a/third_party/libjingle/source/talk/session/phone/filevideoengine.h b/third_party/libjingle/source/talk/session/phone/filevideoengine.h deleted file mode 100644 index 5056ff8..0000000 --- a/third_party/libjingle/source/talk/session/phone/filevideoengine.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2008 Google Inc. All Rights Reserved. -// Author: pzembrod@google.com (Philip Zembrod) - -// FileVideoEngine shall be used to spool received video into files and to -// transmit prerecorded video from files. It is intended for use with -// call.exe clients and derived bots for 1:1 and n:n TalkVideo testing. -// Having a client without actual connection to media hardware allows to -// run several of them on one machine, together withone actual browser -// client, for single-handed manual testing and single-browser automatic -// testing. -// Currently FileVideoEngine records into file names like "video_1.rtp" or -// "somebasename_video_5.rtp". The base name can be set in the engine. -// The auxiliary rtcp streams are recorded into files with the extension -// ".rtcp". - -// FileVideoEngine is designed for the MediaEngine mechanism -// in Talk Video clients, to replace LmiVideoEngine -// in a constructor call like -// return new CompositeMediaEngine<GipsVoiceEngine, LmiVideoEngine>; -// Eventually together with a FileAudioEngine, a file based media engine -// shall be constructed with -// return new CompositeMediaEngine<FileAudioEngine, FileVideoEngine>; -// While FileAudioEngine is not available, FileVideoEngine can be combined -// with GipsVoiceEngine: -// return new CompositeMediaEngine<GipsVoiceEngine, FileVideoEngine>; -// One of these calls is performed by the static method -// MediaEngine* MediaEngine::Create() -// depending on compiler flags or through dependency injection of a -// factory. - -#ifndef TALK_SESSION_PHONE_FILEVIDEOENGINE_H__ -#define TALK_SESSION_PHONE_FILEVIDEOENGINE_H__ - -#include <string> -#include <vector> - -// basictypes.h is included for DISALLOW_EVIL_CONSTRUCTORS -#include "talk/base/basictypes.h" -// codec.h is included because std::vector<VideoCodec> must know -// VideoCodec's size -#include "talk/session/phone/codec.h" -// filevideomediachannel.h is included because in mediaengine.cc -// when compiling CompositeMediaEngine the compiler must know that -// FileVideoMediaChannel* FileVideoEngine::CreateChannel(...) -// returns a class derived from VideoMediaChannel. -#include "talk/session/phone/filevideomediachannel.h" -// Using CaptureResult enumeration from mediaengine.h. -#include "talk/session/phone/mediaengine.h" - -// Transmitting video is harder and will be implemented when -// receiving and recording works. -// TODO(pzembrod): remove all ifdef REPLAY_IMPLEMENTED once -// transmitting is implemented and tested. -#undef REPLAY_IMPLEMENTED - -namespace cricket { - -struct Device; -class VideoRenderer; -class VoiceMediaChannel; - -// See comment at top of file -class FileVideoEngine { - public: - FileVideoEngine(); - virtual ~FileVideoEngine() {} - // Init() is called by virtual bool CompositeMediaEngine::Init(). - bool Init(); - - // Accessors for file_base_name_. - // The getter is virtual to allow mocking it out. - void set_file_base_name(const std::string& file_base_name); - virtual const std::string& file_base_name() const; - - // This creates the actual worker, a FileVideoMediaChannel instance. - FileVideoMediaChannel* CreateChannel(VoiceMediaChannel* voice_media_channel); - - // All the following methods are called by corresponding - // virtual methods of CompositeMediaEngine and don't do - // anything yet. - void GetCaptureDeviceNames(std::vector<std::string>* names); - bool SetCaptureDevice(const Device* device); - bool SetCaptureFormat(int width, int height, int framerate); - void Terminate() {} - int GetCapabilities() { return 0; } - bool SetOptions(int opts) { return true; } - bool SetLocalRenderer(VideoRenderer* renderer) { return true; } - CaptureResult SetCapture(bool capture) { return CR_SUCCESS; } - const std::vector<VideoCodec>& codecs(); - bool FindCodec(const VideoCodec& codec); - bool SetDefaultEncoderConfig(const VideoEncoderConfig& config); - void SetLogging(int severity, const char* filter) {} - sigslot::signal1<bool> SignalCaptureResult; - - private: - // The engine just supports one capture device; actual name's not - // important, behind it are recorded files, of course. - static const char* const kFileCaptureDeviceName; - - // The codec in which the recording currently available for replay - // is encoded. - VideoCodec replay_codec_; - - // List of supported codecs. Published by codec(). Used by FindCodec. - // Since we could record any encoding we might like some generic - // flexibility here. Might be overkill, though. - std::vector<VideoCodec> codecs_; - - // Recording file base name for FileVideoMediaChannel. - std::string file_base_name_; - DISALLOW_EVIL_CONSTRUCTORS(FileVideoEngine); -}; - -} // namespace cricket - -#endif // TALK_SESSION_PHONE_FILEVIDEOENGINE_H__ diff --git a/third_party/libjingle/source/talk/session/phone/filevideomediachannel.h b/third_party/libjingle/source/talk/session/phone/filevideomediachannel.h deleted file mode 100644 index 5b73a8c..0000000 --- a/third_party/libjingle/source/talk/session/phone/filevideomediachannel.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2008 Google Inc. All Rights Reserved. -// Author: pzembrod@google.com (Philip Zembrod) - -// FileVideoMediaChannel is the worker channel for FileVideoEngine, -// designed for the MediaEngine mechanism in Talk Video clients -// (see comments at top of file filevideoengine.h). -// FileVideoMediaChannel takes care of the actual transmitting -// and receiving of video streams over rtp and the reading -// from and recording to files. FileVideoMediaChannel is created -// by FileVideoEngine::CreateChannel(). -// rtp (real time protocol) is a udp protocol used (here) to transfer -// audio and video streams. -// rtcp (real time control protocol), also udp-based, is an associated -// control protocol. - -#ifndef TALK_SESSION_PHONE_FILEVIDEOMEDIACHANNEL_H_ -#define TALK_SESSION_PHONE_FILEVIDEOMEDIACHANNEL_H_ - -#include <string> -#include <vector> - -#include "talk/base/criticalsection.h" -#include "talk/base/stream.h" // for StreamResult -#include "talk/session/phone/mediachannel.h" - -using talk_base::CritScope; -using talk_base::FileStream; - -namespace cricket { - -class FileVideoEngine; - -// See comment at top of file -class FileVideoMediaChannel : public VideoMediaChannel { - public: - // The creating engine is used to provide the recording file base name. - explicit FileVideoMediaChannel(FileVideoEngine* engine); - virtual ~FileVideoMediaChannel(); - // FileVideoMediaChannel can run without Init(), but then it doesn't record. - // Calling Init() again restarts recording to engine's current file name. - // If the file name has changed since the last Init() call, the old files - // are closed and new files (one for rtp, one for rtcp) opened. - virtual void Init(); - - virtual bool SetOptions(int options) { - return true; - } - virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) { - return true; - } - - // This is called after initiating or accepting a call - // with the possible codecs of a session. The channel has to - // choose one it can handle and inform the session of the choice. - virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs); - - // Called on receiving a rtp packet. packet_data points to a buffer - // containing the packet's bytes, packet_length is the buffer's length. - virtual void OnPacketReceived(const void* packet_data, int packet_length); - // Called on receiving a rtcp packet. packet_data points to a buffer - // containing the packet's bytes, packet_length is the buffer's length. - virtual void OnRtcpReceived(const void* packet_data, int packet_length); - - // Remaining pure virtual methods of MediaChannel which are - // not overridden in VideoMediaChannel are overridden with - // empty implementations here to be able to run the class. - // Most or all of them will doubtless be filled out with - // useful code later. - virtual bool SetRenderer(uint32 ssrc, VideoRenderer* r) { return true; } - virtual bool SetRender(bool render) { return true; } - virtual bool AddScreencast(uint32 ssrc, talk_base::WindowId id) { - return true; - } - virtual bool RemoveScreencast(uint32 ssrc) { return true; } - virtual bool SetSend(bool send) { return true; } - virtual void SetSendSsrc(uint32 id) {} - virtual bool SetRtcpCName(const std::string& cname) { return true; } - virtual bool SetMaxSendBandwidth(int max_bandwidth) { return false; } - virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc) { return false; } - virtual bool RemoveStream(uint32 ssrc) { return false; } - virtual bool Mute(bool muted) { return false; } - virtual bool GetStats(VideoMediaInfo* info) { return false; } - - // Builds the file name for rtp recording. - // public for testing. - std::string rtp_filename() const; - // Builds the file name for rtcp recording. - // public for testing. - std::string rtcp_filename() const; - - private: - // Common inner function for rtp_filename() and rtcp_filename(). Does - // all the work except for the extensions ".rtp"/".rtcp". - std::string file_name() const; - - // Creates and opens rtp_writer_ for writing (mode "w") into file - // rtp_filename(). - void OpenRtpFile(); - // Creates and opens rtcp_writer_ for writing (mode "w") into file - // rtcp_filename(). - void OpenRtcpFile(); - - // Closes and deletes rtp_writer_. - void CloseRtpFile(); - // Closes and deletes rtcp_writer_. - void CloseRtcpFile(); - - // Helper function for OpenRtpFile() and OpenRtcpFile(). - // Creates, opens and returns FileStream object. - // Params as in FileStream::Open(). Returns NULL on failure. - FileStream* OpenFileStream(const std::string& file_name, const char* mode); - - // Helper function for OnPacketReceived() and OnRtcpReceived(). - // Writes rtp or rtcp packet in packet_data/packet_length to writer. - // FileStream *writer my be NULL, then nothing is written. - // protocol_name should be "rtp" or "rtcp" and is used in - // logging messages only. - void WritePacket(FileStream* writer, const std::string& protocol_name, - const void* packet_data, int packet_length); - - // Helper method for WritePacket(). It's a wrapper around - // FileStream::Write() with error logging and returns the - // return value of FileStream::Write(), SR_SUCCESS on success. - // *what_is_written is used for the error message and should be - // something like "rtp packet size" or "rtp packet data". - // writer must not be NULL. - talk_base::StreamResult WriteAndCheck(FileStream* writer, - const std::string& what_is_written, const void* data, int length); - - // Engine creating FileVideoMediaChannel instance, used to - // provide file_base_name() for recording. - FileVideoEngine* engine_; - // FileStream for recording rtp packages - talk_base::scoped_ptr<FileStream> rtp_writer_; - // FileStream for recording rtcp packages - talk_base::scoped_ptr<FileStream> rtcp_writer_; - - // ID to create unique filenames for several instances - // which might exist in parallel. - int id_; - // Static counter to create these IDs. - static int id_generator_; - // Mutex for id_generator_. - static talk_base::CriticalSection cs_id_generator_; - DISALLOW_EVIL_CONSTRUCTORS(FileVideoMediaChannel); -}; - -} // namespace cricket - -#endif // TALK_SESSION_PHONE_FILEVIDEOMEDIACHANNEL_H_ diff --git a/third_party/libjingle/source/talk/session/phone/mediachannel.h b/third_party/libjingle/source/talk/session/phone/mediachannel.h index 962aec3..ee9d3c7 100644 --- a/third_party/libjingle/source/talk/session/phone/mediachannel.h +++ b/third_party/libjingle/source/talk/session/phone/mediachannel.h @@ -35,7 +35,7 @@ #include "talk/base/sigslot.h" #include "talk/base/socket.h" #include "talk/session/phone/codec.h" -// TODO(juberti): re-evaluate this include +// TODO: re-evaluate this include #include "talk/session/phone/audiomonitor.h" namespace flute { @@ -49,6 +49,7 @@ enum VoiceMediaChannelOptions { OPT_ENERGYLEVEL = 0x20000, // include the energy level in RTP packets, as // defined in https://datatracker.ietf.org/drafts/ // draft-lennox-avt-rtp-audio-level-exthdr/ + }; enum VideoMediaChannelOptions { @@ -100,7 +101,7 @@ enum SendFlags { SEND_MICROPHONE }; -// TODO(juberti): separate into VoiceMediaInfo and VideoMediaInfo +// TODO: separate into VoiceMediaInfo and VideoMediaInfo struct MediaInfo { int fraction_lost; int cum_lost; @@ -172,7 +173,7 @@ class VideoFrame { virtual size_t GetPixelWidth() const = 0; virtual size_t GetPixelHeight() const = 0; - // TODO(whyuan): Add a fourcc format here and probably combine VideoFrame + // TODO: Add a fourcc format here and probably combine VideoFrame // with CapturedFrame. virtual int64 GetElapsedTime() const = 0; virtual int64 GetTimeStamp() const = 0; @@ -232,7 +233,7 @@ class VideoFrame { protected: // The frame needs to be rendered to magiccam only once. - // TODO(geer): Remove this flag once magiccam rendering is fully replaced + // TODO: Remove this flag once magiccam rendering is fully replaced // by client3d rendering. mutable bool rendered_; }; diff --git a/third_party/libjingle/source/talk/session/phone/mediaengine.cc b/third_party/libjingle/source/talk/session/phone/mediaengine.cc index 1b59d5c..66eb18e 100644 --- a/third_party/libjingle/source/talk/session/phone/mediaengine.cc +++ b/third_party/libjingle/source/talk/session/phone/mediaengine.cc @@ -30,7 +30,7 @@ namespace cricket { -// TODO(pthatcher): according to thaloun, HAVE_GIPSVIDEO will always +// TODO: according to thaloun, HAVE_GIPSVIDEO will always // be false, so we can get rid of it. MediaEngine* MediaEngine::Create( diff --git a/third_party/libjingle/source/talk/session/phone/mediaengine.h b/third_party/libjingle/source/talk/session/phone/mediaengine.h index eade188..c42e8ef 100644 --- a/third_party/libjingle/source/talk/session/phone/mediaengine.h +++ b/third_party/libjingle/source/talk/session/phone/mediaengine.h @@ -68,7 +68,7 @@ class SoundclipMedia { // between both media types. class MediaEngine { public: - // TODO(juberti): Move this to a global location (also used in DeviceManager) + // TODO: Move this to a global location (also used in DeviceManager) // Capabilities of the media engine. enum Capabilities { AUDIO_RECV = 1 << 0, @@ -124,7 +124,7 @@ class MediaEngine { = 0; // Device selection - // TODO(tschmelcher): Add method for selecting the soundclip device. + // TODO: Add method for selecting the soundclip device. virtual bool SetSoundDevices(const Device* in_device, const Device* out_device) = 0; virtual bool SetVideoCaptureDevice(const Device* cam_device) = 0; diff --git a/third_party/libjingle/source/talk/session/phone/mediasessionclient.cc b/third_party/libjingle/source/talk/session/phone/mediasessionclient.cc index fa07ccc..001cf73 100644 --- a/third_party/libjingle/source/talk/session/phone/mediasessionclient.cc +++ b/third_party/libjingle/source/talk/session/phone/mediasessionclient.cc @@ -57,8 +57,7 @@ MediaSessionClient::MediaSessionClient( void MediaSessionClient::Construct() { // Register ourselves as the handler of phone and video sessions. - session_manager_->AddClient(NS_GINGLE_AUDIO, this); - session_manager_->AddClient(NS_GINGLE_VIDEO, this); + session_manager_->AddClient(NS_JINGLE_RTP, this); // Forward device notifications. SignalDevicesChange.repeat(channel_manager_->SignalDevicesChange); // Bring up the channel manager. @@ -79,8 +78,7 @@ MediaSessionClient::~MediaSessionClient() { delete channel_manager_; // Remove ourselves from the client map. - session_manager_->RemoveClient(NS_GINGLE_VIDEO); - session_manager_->RemoveClient(NS_GINGLE_AUDIO); + session_manager_->RemoveClient(NS_JINGLE_RTP); } SessionDescription* MediaSessionClient::CreateOffer(bool video, bool set_ssrc) { @@ -91,14 +89,14 @@ SessionDescription* MediaSessionClient::CreateOffer(bool video, bool set_ssrc) { AudioCodecs audio_codecs; channel_manager_->GetSupportedAudioCodecs(&audio_codecs); for (AudioCodecs::const_iterator codec = audio_codecs.begin(); - codec != audio_codecs.end(); codec++) { + codec != audio_codecs.end(); ++codec) { audio->AddCodec(*codec); } if (set_ssrc) { audio->set_ssrc(0); } audio->SortCodecs(); - offer->AddContent(CN_AUDIO, NS_GINGLE_AUDIO, audio); + offer->AddContent(CN_AUDIO, NS_JINGLE_RTP, audio); // add video codecs, if this is a video call if (video) { @@ -106,37 +104,51 @@ SessionDescription* MediaSessionClient::CreateOffer(bool video, bool set_ssrc) { VideoCodecs video_codecs; channel_manager_->GetSupportedVideoCodecs(&video_codecs); for (VideoCodecs::const_iterator codec = video_codecs.begin(); - codec != video_codecs.end(); codec++) { + codec != video_codecs.end(); ++codec) { video->AddCodec(*codec); } if (set_ssrc) { video->set_ssrc(0); } video->SortCodecs(); - offer->AddContent(CN_VIDEO, NS_GINGLE_VIDEO, video); + offer->AddContent(CN_VIDEO, NS_JINGLE_RTP, video); } return offer; } const ContentInfo* GetFirstMediaContent(const SessionDescription* sdesc, - const std::string& content_type) { + MediaType media_type) { if (sdesc == NULL) return NULL; - return sdesc->FirstContentByType(content_type); + const ContentInfos& contents = sdesc->contents(); + for (ContentInfos::const_iterator content = contents.begin(); + content != contents.end(); content++) { + if (content->type == NS_JINGLE_RTP) { + const MediaContentDescription* media = + static_cast<const MediaContentDescription*>(content->description); + if (media->type() == media_type) { + return &*content; + } + } + } + return NULL; } const ContentInfo* GetFirstAudioContent(const SessionDescription* sdesc) { - return GetFirstMediaContent(sdesc, NS_GINGLE_AUDIO); + return GetFirstMediaContent(sdesc, MEDIA_TYPE_AUDIO); } const ContentInfo* GetFirstVideoContent(const SessionDescription* sdesc) { - return GetFirstMediaContent(sdesc, NS_GINGLE_VIDEO); + return GetFirstMediaContent(sdesc, MEDIA_TYPE_VIDEO); } SessionDescription* MediaSessionClient::CreateAnswer( const SessionDescription* offer) { + // The answer contains the intersection of the codecs in the offer with the + // codecs we support, ordered by our local preference. As indicated by + // XEP-0167, we retain the same payload ids from the offer in the answer. SessionDescription* accept = new SessionDescription(); const ContentInfo* audio_content = GetFirstAudioContent(offer); @@ -144,12 +156,20 @@ SessionDescription* MediaSessionClient::CreateAnswer( const AudioContentDescription* audio_offer = static_cast<const AudioContentDescription*>(audio_content->description); AudioContentDescription* audio_accept = new AudioContentDescription(); - for (AudioCodecs::const_iterator codec = audio_offer->codecs().begin(); - codec != audio_offer->codecs().end(); codec++) { - if (channel_manager_->FindAudioCodec(*codec)) { - audio_accept->AddCodec(*codec); + AudioCodecs audio_codecs; + channel_manager_->GetSupportedAudioCodecs(&audio_codecs); + for (AudioCodecs::const_iterator ours = audio_codecs.begin(); + ours != audio_codecs.end(); ++ours) { + for (AudioCodecs::const_iterator theirs = audio_offer->codecs().begin(); + theirs != audio_offer->codecs().end(); ++theirs) { + if (ours->Matches(*theirs)) { + AudioCodec negotiated(*ours); + negotiated.id = theirs->id; + audio_accept->AddCodec(negotiated); + } } } + audio_accept->SortCodecs(); accept->AddContent(audio_content->name, audio_content->type, audio_accept); } @@ -159,12 +179,20 @@ SessionDescription* MediaSessionClient::CreateAnswer( const VideoContentDescription* video_offer = static_cast<const VideoContentDescription*>(video_content->description); VideoContentDescription* video_accept = new VideoContentDescription(); - for (VideoCodecs::const_iterator codec = video_offer->codecs().begin(); - codec != video_offer->codecs().end(); codec++) { - if (channel_manager_->FindVideoCodec(*codec)) { - video_accept->AddCodec(*codec); + VideoCodecs video_codecs; + channel_manager_->GetSupportedVideoCodecs(&video_codecs); + for (VideoCodecs::const_iterator ours = video_codecs.begin(); + ours != video_codecs.end(); ++ours) { + for (VideoCodecs::const_iterator theirs = video_offer->codecs().begin(); + theirs != video_offer->codecs().end(); ++theirs) { + if (ours->Matches(*theirs)) { + VideoCodec negotiated(*ours); + negotiated.id = theirs->id; + video_accept->AddCodec(negotiated); + } } } + video_accept->SortCodecs(); accept->AddContent(video_content->name, video_content->type, video_accept); } @@ -183,25 +211,37 @@ void MediaSessionClient::OnSessionCreate(Session *session, bool received_initiate) { if (received_initiate) { session->SignalState.connect(this, &MediaSessionClient::OnSessionState); - - Call *call = CreateCall(session->content_type() == NS_GINGLE_VIDEO); - session_map_[session->id()] = call; - call->AddSession(session); } } -void MediaSessionClient::OnSessionState(BaseSession *session, +void MediaSessionClient::OnSessionState(BaseSession* base_session, BaseSession::State state) { + // MediaSessionClient can only be used with a Session*, so it's + // safe to cast here. + Session* session = static_cast<Session*>(base_session); + if (state == Session::STATE_RECEIVEDINITIATE) { + // The creation of the call must happen after the session has + // processed the initiate message because we need the + // remote_description to know what content names to use in the + // call. + // If our accept would have no codecs, then we must reject this call. - SessionDescription* accept = CreateAnswer(session->remote_description()); + const SessionDescription* offer = session->remote_description(); + const SessionDescription* accept = CreateAnswer(offer); const ContentInfo* audio_content = GetFirstAudioContent(accept); + const ContentInfo* video_content = GetFirstVideoContent(accept); const AudioContentDescription* audio_accept = (!audio_content) ? NULL : static_cast<const AudioContentDescription*>(audio_content->description); + // For some reason, we need to create the call even when we + // reject. + Call *call = CreateCall(video_content != NULL); + session_map_[session->id()] = call; + call->IncomingSession(session, offer); + if (!audio_accept || audio_accept->codecs().size() == 0) { - // TODO(?): include an error description with the rejection. - session->Reject(); + session->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS); } delete accept; } @@ -226,7 +266,7 @@ void MediaSessionClient::DestroyCall(Call *call) { void MediaSessionClient::OnSessionDestroy(Session *session) { // Find the call this session is in, remove it - std::map<SessionID, Call *>::iterator it = session_map_.find(session->id()); + std::map<std::string, Call *>::iterator it = session_map_.find(session->id()); ASSERT(it != session_map_.end()); if (it != session_map_.end()) { Call *call = (*it).second; @@ -262,14 +302,13 @@ void MediaSessionClient::JoinCalls(Call *call_to_join, Call *call) { } Session *MediaSessionClient::CreateSession(Call *call) { - const std::string& type = call->video() ? NS_GINGLE_VIDEO : NS_GINGLE_AUDIO; + const std::string& type = NS_JINGLE_RTP; Session *session = session_manager_->CreateSession(jid().Str(), type); session_map_[session->id()] = call; return session; } -bool MediaSessionClient::ParseAudioCodec(const buzz::XmlElement* element, - AudioCodec* out) { +bool ParseGingleAudioCodec(const buzz::XmlElement* element, AudioCodec* out) { int id = GetXmlAttr(element, QN_ID, -1); if (id < 0) return false; @@ -282,8 +321,7 @@ bool MediaSessionClient::ParseAudioCodec(const buzz::XmlElement* element, return true; } -bool MediaSessionClient::ParseVideoCodec(const buzz::XmlElement* element, - VideoCodec* out) { +bool ParseGingleVideoCodec(const buzz::XmlElement* element, VideoCodec* out) { int id = GetXmlAttr(element, QN_ID, -1); if (id < 0) return false; @@ -292,67 +330,191 @@ bool MediaSessionClient::ParseVideoCodec(const buzz::XmlElement* element, int width = GetXmlAttr(element, QN_WIDTH, 0); int height = GetXmlAttr(element, QN_HEIGHT, 0); int framerate = GetXmlAttr(element, QN_FRAMERATE, 0); + *out = VideoCodec(id, name, width, height, framerate, 0); return true; } -bool MediaSessionClient::ParseContent(const buzz::XmlElement* elem, - const ContentDescription** content, - ParseError* error) { - const std::string& content_type = elem->Name().Namespace(); - if (NS_GINGLE_AUDIO == content_type) { - AudioContentDescription* audio = new AudioContentDescription(); - - if (elem->FirstElement()) { - for (const buzz::XmlElement* codec_elem = - elem->FirstNamed(QN_GINGLE_AUDIO_PAYLOADTYPE); - codec_elem != NULL; - codec_elem = codec_elem->NextNamed(QN_GINGLE_AUDIO_PAYLOADTYPE)) { - AudioCodec audio_codec; - if (ParseAudioCodec(codec_elem, &audio_codec)) { - audio->AddCodec(audio_codec); - } +void ParseGingleSsrc(const buzz::XmlElement* parent_elem, + const buzz::QName& name, + MediaContentDescription* content) { + const buzz::XmlElement* ssrc_elem = parent_elem->FirstNamed(name); + if (ssrc_elem) { + content->set_ssrc(strtoul(ssrc_elem->BodyText().c_str(), NULL, 10)); + } +} + +bool ParseGingleAudioContent(const buzz::XmlElement* content_elem, + const ContentDescription** content, + ParseError* error) { + AudioContentDescription* audio = new AudioContentDescription(); + + if (content_elem->FirstElement()) { + for (const buzz::XmlElement* codec_elem = + content_elem->FirstNamed(QN_GINGLE_AUDIO_PAYLOADTYPE); + codec_elem != NULL; + codec_elem = codec_elem->NextNamed(QN_GINGLE_AUDIO_PAYLOADTYPE)) { + AudioCodec codec; + if (ParseGingleAudioCodec(codec_elem, &codec)) { + audio->AddCodec(codec); } - } else { - // For backward compatibility, we can assume the other client is - // an old version of Talk if it has no audio payload types at all. - audio->AddCodec(AudioCodec(103, "ISAC", 16000, -1, 1, 1)); - audio->AddCodec(AudioCodec(0, "PCMU", 8000, 64000, 1, 0)); } + } else { + // For backward compatibility, we can assume the other client is + // an old version of Talk if it has no audio payload types at all. + audio->AddCodec(AudioCodec(103, "ISAC", 16000, -1, 1, 1)); + audio->AddCodec(AudioCodec(0, "PCMU", 8000, 64000, 1, 0)); + } + + ParseGingleSsrc(content_elem, QN_GINGLE_VIDEO_SRCID, audio); + + *content = audio; + return true; +} + - const buzz::XmlElement* src_id = elem->FirstNamed(QN_GINGLE_AUDIO_SRCID); - if (src_id) { - audio->set_ssrc(strtoul(src_id->BodyText().c_str(), NULL, 10)); +bool ParseGingleVideoContent(const buzz::XmlElement* content_elem, + const ContentDescription** content, + ParseError* error) { + VideoContentDescription* video = new VideoContentDescription(); + + for (const buzz::XmlElement* codec_elem = + content_elem->FirstNamed(QN_GINGLE_VIDEO_PAYLOADTYPE); + codec_elem != NULL; + codec_elem = codec_elem->NextNamed(QN_GINGLE_VIDEO_PAYLOADTYPE)) { + VideoCodec codec; + if (ParseGingleVideoCodec(codec_elem, &codec)) { + video->AddCodec(codec); } + } - *content = audio; - } else if (NS_GINGLE_VIDEO == content_type) { - VideoContentDescription* video = new VideoContentDescription(); + ParseGingleSsrc(content_elem, QN_GINGLE_VIDEO_SRCID, video); - for (const buzz::XmlElement* codec_elem = - elem->FirstNamed(QN_GINGLE_VIDEO_PAYLOADTYPE); - codec_elem != NULL; - codec_elem = codec_elem->NextNamed(QN_GINGLE_VIDEO_PAYLOADTYPE)) { - VideoCodec video_codec; - if (ParseVideoCodec(codec_elem, &video_codec)) { - video->AddCodec(video_codec); - } + *content = video; + return true; +} + +void ParsePayloadTypeParameters(const buzz::XmlElement* element, + std::map<std::string, std::string>* paramap) { + for (const buzz::XmlElement* param = element->FirstNamed(QN_PARAMETER); + param != NULL; param = param->NextNamed(QN_PARAMETER)) { + std::string name = GetXmlAttr(param, QN_PAYLOADTYPE_PARAMETER_NAME, ""); + std::string value = GetXmlAttr(param, QN_PAYLOADTYPE_PARAMETER_VALUE, ""); + if (!name.empty() && !value.empty()) { + paramap->insert(make_pair(name, value)); } + } +} - const buzz::XmlElement* src_id = elem->FirstNamed(QN_GINGLE_VIDEO_SRCID); - if (src_id) { - video->set_ssrc(strtoul(src_id->BodyText().c_str(), NULL, 10)); +int FindWithDefault(const std::map<std::string, std::string>& map, + const std::string& key, const int def) { + std::map<std::string, std::string>::const_iterator iter = map.find(key); + return (iter == map.end()) ? def : atoi(iter->second.c_str()); +} + +bool ParseJingleAudioCodec(const buzz::XmlElement* elem, AudioCodec* codec) { + int id = GetXmlAttr(elem, QN_ID, -1); + if (id < 0) + return false; + + std::string name = GetXmlAttr(elem, QN_NAME, ""); + int clockrate = GetXmlAttr(elem, QN_CLOCKRATE, 0); + int channels = GetXmlAttr(elem, QN_CHANNELS, 1); + + std::map<std::string, std::string> paramap; + ParsePayloadTypeParameters(elem, ¶map); + int bitrate = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_BITRATE, 0); + + *codec = AudioCodec(id, name, clockrate, bitrate, channels, 0); + return true; +} + +bool ParseJingleVideoCodec(const buzz::XmlElement* elem, VideoCodec* codec) { + int id = GetXmlAttr(elem, QN_ID, -1); + if (id < 0) + return false; + + std::string name = GetXmlAttr(elem, QN_NAME, ""); + + std::map<std::string, std::string> paramap; + ParsePayloadTypeParameters(elem, ¶map); + int width = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_WIDTH, 0); + int height = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_HEIGHT, 0); + int framerate = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_FRAMERATE, 0); + + *codec = VideoCodec(id, name, width, height, framerate, 0); + return true; +} + +bool ParseJingleAudioContent(const buzz::XmlElement* content_elem, + const ContentDescription** content, + ParseError* error) { + AudioContentDescription* audio = new AudioContentDescription(); + + for (const buzz::XmlElement* payload_elem = + content_elem->FirstNamed(QN_JINGLE_RTP_PAYLOADTYPE); + payload_elem != NULL; + payload_elem = payload_elem->NextNamed(QN_JINGLE_RTP_PAYLOADTYPE)) { + AudioCodec codec; + if (ParseJingleAudioCodec(payload_elem, &codec)) { + audio->AddCodec(codec); } + } - *content = video; - } else { - return BadParse("unknown media content type: " + content_type, error); + // TODO: Figure out how to integrate SSRC into Jingle. + *content = audio; + return true; +} + +bool ParseJingleVideoContent(const buzz::XmlElement* content_elem, + const ContentDescription** content, + ParseError* error) { + VideoContentDescription* video = new VideoContentDescription(); + + for (const buzz::XmlElement* payload_elem = + content_elem->FirstNamed(QN_JINGLE_RTP_PAYLOADTYPE); + payload_elem != NULL; + payload_elem = payload_elem->NextNamed(QN_JINGLE_RTP_PAYLOADTYPE)) { + VideoCodec codec; + if (ParseJingleVideoCodec(payload_elem, &codec)) { + video->AddCodec(codec); + } } + // TODO: Figure out how to integrate SSRC into Jingle. + *content = video; return true; } -buzz::XmlElement* WriteAudioCodec(const AudioCodec& codec) { +bool MediaSessionClient::ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* content_elem, + const ContentDescription** content, + ParseError* error) { + if (protocol == PROTOCOL_GINGLE) { + const std::string& content_type = content_elem->Name().Namespace(); + if (NS_GINGLE_AUDIO == content_type) { + return ParseGingleAudioContent(content_elem, content, error); + } else if (NS_GINGLE_VIDEO == content_type) { + return ParseGingleVideoContent(content_elem, content, error); + } else { + return BadParse("Unknown content type: " + content_type, error); + } + } else { + std::string media; + if (!RequireXmlAttr(content_elem, QN_JINGLE_CONTENT_MEDIA, &media, error)) + return false; + + if (media == JINGLE_CONTENT_MEDIA_AUDIO) { + return ParseJingleAudioContent(content_elem, content, error); + } else if (media == JINGLE_CONTENT_MEDIA_VIDEO) { + return ParseJingleVideoContent(content_elem, content, error); + } else { + return BadParse("Unknown media: " + media, error); + } + } +} + +buzz::XmlElement* CreateGingleAudioCodecElem(const AudioCodec& codec) { buzz::XmlElement* payload_type = new buzz::XmlElement(QN_GINGLE_AUDIO_PAYLOADTYPE, true); AddXmlAttr(payload_type, QN_ID, codec.id); @@ -366,7 +528,7 @@ buzz::XmlElement* WriteAudioCodec(const AudioCodec& codec) { return payload_type; } -buzz::XmlElement* WriteVideoCodec(const VideoCodec& codec) { +buzz::XmlElement* CreateGingleVideoCodecElem(const VideoCodec& codec) { buzz::XmlElement* payload_type = new buzz::XmlElement(QN_GINGLE_VIDEO_PAYLOADTYPE, true); AddXmlAttr(payload_type, QN_ID, codec.id); @@ -377,53 +539,152 @@ buzz::XmlElement* WriteVideoCodec(const VideoCodec& codec) { return payload_type; } -bool MediaSessionClient::WriteContent(const ContentDescription* untyped_content, +buzz::XmlElement* CreateGingleSsrcElem(const buzz::QName& name, uint32 ssrc) { + buzz::XmlElement* elem = new buzz::XmlElement(name, true); + if (ssrc) { + SetXmlBody(elem, ssrc); + } + return elem; +} + +buzz::XmlElement* CreateGingleAudioContentElem( + const AudioContentDescription* audio) { + buzz::XmlElement* elem = + new buzz::XmlElement(QN_GINGLE_AUDIO_CONTENT, true); + + for (AudioCodecs::const_iterator codec = audio->codecs().begin(); + codec != audio->codecs().end(); ++codec) { + elem->AddElement(CreateGingleAudioCodecElem(*codec)); + } + if (audio->ssrc_set()) { + elem->AddElement(CreateGingleSsrcElem( + QN_GINGLE_AUDIO_SRCID, audio->ssrc())); + } + + + return elem; +} + +buzz::XmlElement* CreateGingleVideoContentElem( + const VideoContentDescription* video) { + buzz::XmlElement* elem = + new buzz::XmlElement(QN_GINGLE_VIDEO_CONTENT, true); + + for (VideoCodecs::const_iterator codec = video->codecs().begin(); + codec != video->codecs().end(); ++codec) { + elem->AddElement(CreateGingleVideoCodecElem(*codec)); + } + if (video->ssrc_set()) { + elem->AddElement(CreateGingleSsrcElem( + QN_GINGLE_VIDEO_SRCID, video->ssrc())); + } + + return elem; +} + +buzz::XmlElement* CreatePayloadTypeParameterElem( + const std::string& name, int value) { + buzz::XmlElement* elem = new buzz::XmlElement(QN_PARAMETER); + + elem->AddAttr(QN_PAYLOADTYPE_PARAMETER_NAME, name); + AddXmlAttr(elem, QN_PAYLOADTYPE_PARAMETER_VALUE, value); + + return elem; +} + +buzz::XmlElement* CreateJingleAudioCodecElem(const AudioCodec& codec) { + buzz::XmlElement* elem = new buzz::XmlElement(QN_JINGLE_RTP_PAYLOADTYPE); + + AddXmlAttr(elem, QN_ID, codec.id); + elem->AddAttr(QN_NAME, codec.name); + if (codec.clockrate > 0) { + AddXmlAttr(elem, QN_CLOCKRATE, codec.clockrate); + } + if (codec.bitrate > 0) { + elem->AddElement(CreatePayloadTypeParameterElem( + PAYLOADTYPE_PARAMETER_BITRATE, codec.bitrate)); + } + if (codec.channels > 1) { + AddXmlAttr(elem, QN_CHANNELS, codec.channels); + } + + return elem; +} + +buzz::XmlElement* CreateJingleVideoCodecElem(const VideoCodec& codec) { + buzz::XmlElement* elem = new buzz::XmlElement(QN_JINGLE_RTP_PAYLOADTYPE); + + AddXmlAttr(elem, QN_ID, codec.id); + elem->AddAttr(QN_NAME, codec.name); + elem->AddElement(CreatePayloadTypeParameterElem( + PAYLOADTYPE_PARAMETER_WIDTH, codec.width)); + elem->AddElement(CreatePayloadTypeParameterElem( + PAYLOADTYPE_PARAMETER_HEIGHT, codec.height)); + elem->AddElement(CreatePayloadTypeParameterElem( + PAYLOADTYPE_PARAMETER_FRAMERATE, codec.framerate)); + + return elem; +} + +buzz::XmlElement* CreateJingleAudioContentElem( + const AudioContentDescription* audio) { + buzz::XmlElement* elem = + new buzz::XmlElement(QN_JINGLE_RTP_CONTENT, true); + + elem->SetAttr(QN_JINGLE_CONTENT_MEDIA, JINGLE_CONTENT_MEDIA_AUDIO); + + for (AudioCodecs::const_iterator codec = audio->codecs().begin(); + codec != audio->codecs().end(); ++codec) { + elem->AddElement(CreateJingleAudioCodecElem(*codec)); + } + + // TODO: Figure out how to integrate SSRC into Jingle. + return elem; +} + +buzz::XmlElement* CreateJingleVideoContentElem( + const VideoContentDescription* video) { + buzz::XmlElement* elem = + new buzz::XmlElement(QN_JINGLE_RTP_CONTENT, true); + + elem->SetAttr(QN_JINGLE_CONTENT_MEDIA, JINGLE_CONTENT_MEDIA_VIDEO); + + for (VideoCodecs::const_iterator codec = video->codecs().begin(); + codec != video->codecs().end(); ++codec) { + elem->AddElement(CreateJingleVideoCodecElem(*codec)); + } + + // TODO: Figure out how to integrate SSRC into Jingle. + return elem; +} + +bool MediaSessionClient::WriteContent(SignalingProtocol protocol, + const ContentDescription* content, buzz::XmlElement** elem, WriteError* error) { const MediaContentDescription* media = - static_cast<const MediaContentDescription*>(untyped_content); + static_cast<const MediaContentDescription*>(content); - buzz::XmlElement* content_elem; if (media->type() == MEDIA_TYPE_AUDIO) { const AudioContentDescription* audio = - static_cast<const AudioContentDescription*>(untyped_content); - content_elem = new buzz::XmlElement(QN_GINGLE_AUDIO_CONTENT, true); - - for (AudioCodecs::const_iterator codec = audio->codecs().begin(); - codec != audio->codecs().end(); codec++) { - content_elem->AddElement(WriteAudioCodec(*codec)); - } - if (audio->ssrc_set()) { - buzz::XmlElement* src_id = - new buzz::XmlElement(QN_GINGLE_AUDIO_SRCID, true); - if (audio->ssrc()) { - SetXmlBody(src_id, audio->ssrc()); - } - content_elem->AddElement(src_id); + static_cast<const AudioContentDescription*>(media); + if (protocol == PROTOCOL_GINGLE) { + *elem = CreateGingleAudioContentElem(audio); + } else { + *elem = CreateJingleAudioContentElem(audio); } - - - *elem = content_elem; } else if (media->type() == MEDIA_TYPE_VIDEO) { const VideoContentDescription* video = - static_cast<const VideoContentDescription*>(untyped_content); - content_elem = new buzz::XmlElement(QN_GINGLE_VIDEO_CONTENT, true); - - for (VideoCodecs::const_iterator codec = video->codecs().begin(); - codec != video->codecs().end(); codec++) { - content_elem->AddElement(WriteVideoCodec(*codec)); - } - if (video->ssrc_set()) { - buzz::XmlElement* src_id = - new buzz::XmlElement(QN_GINGLE_VIDEO_SRCID, true); - if (video->ssrc()) { - SetXmlBody(src_id, video->ssrc()); - } - content_elem->AddElement(src_id); + static_cast<const VideoContentDescription*>(media); + if (protocol == PROTOCOL_GINGLE) { + *elem = CreateGingleVideoContentElem(video); + } else { + *elem = CreateJingleVideoContentElem(video); } - - *elem = content_elem; + } else { + return BadWrite("Unknown content type: " + media->type(), error); } + return true; } diff --git a/third_party/libjingle/source/talk/session/phone/mediasessionclient.h b/third_party/libjingle/source/talk/session/phone/mediasessionclient.h index 246e58e..533341b 100644 --- a/third_party/libjingle/source/talk/session/phone/mediasessionclient.h +++ b/third_party/libjingle/source/talk/session/phone/mediasessionclient.h @@ -108,24 +108,22 @@ class MediaSessionClient: public SessionClient, public sigslot::has_slots<> { void OnSessionCreate(Session *session, bool received_initiate); void OnSessionState(BaseSession *session, BaseSession::State state); void OnSessionDestroy(Session *session); - virtual bool ParseContent(const buzz::XmlElement* elem, + virtual bool ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* elem, const ContentDescription** content, ParseError* error); - virtual bool WriteContent(const ContentDescription* content, + virtual bool WriteContent(SignalingProtocol protocol, + const ContentDescription* content, buzz::XmlElement** elem, WriteError* error); Session *CreateSession(Call *call); - static bool ParseAudioCodec(const buzz::XmlElement* element, AudioCodec* out); - static bool ParseVideoCodec(const buzz::XmlElement* element, VideoCodec* out); - - buzz::Jid jid_; SessionManager* session_manager_; Call *focus_call_; ChannelManager *channel_manager_; std::map<uint32, Call *> calls_; - std::map<SessionID, Call *> session_map_; + std::map<std::string, Call *> session_map_; friend class Call; }; @@ -192,11 +190,15 @@ class MediaContentDescriptionImpl : public MediaContentDescription { class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> { public: + AudioContentDescription() + {} + virtual MediaType type() const { return MEDIA_TYPE_AUDIO; } const std::string &lang() const { return lang_; } void set_lang(const std::string &lang) { lang_ = lang; } + private: std::string lang_; }; diff --git a/third_party/libjingle/source/talk/session/phone/rtpdump.cc b/third_party/libjingle/source/talk/session/phone/rtpdump.cc new file mode 100644 index 0000000..1006015 --- /dev/null +++ b/third_party/libjingle/source/talk/session/phone/rtpdump.cc @@ -0,0 +1,322 @@ +/* + * libjingle + * Copyright 2010, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "talk/session/phone/rtpdump.h" + +#include <string> + +#include "talk/base/bytebuffer.h" +#include "talk/base/logging.h" +#include "talk/base/time.h" + +namespace cricket { + +static const char kRtpDumpFileFirstLine[] = "#!rtpplay1.0 0.0.0.0/0\n"; + +struct RtpDumpFileHeader { + RtpDumpFileHeader(uint32 start_ms, uint32 s, uint16 p) + : start_sec(start_ms / 1000), + start_usec(start_ms % 1000 * 1000), + source(s), + port(p), + padding(0) { + } + + void WriteToByteBuffer(talk_base::ByteBuffer* buf) { + buf->WriteUInt32(start_sec); + buf->WriteUInt32(start_usec); + buf->WriteUInt32(source); + buf->WriteUInt16(port); + buf->WriteUInt16(padding); + } + + static const size_t kHeaderLength = 16; + uint32 start_sec; // start of recording, the seconds part. + uint32 start_usec; // start of recording, the microseconds part. + uint32 source; // network source (multicast address). + uint16 port; // UDP port. + uint16 padding; // 2 bytes padding. +}; + +// RTP packet format (http://www.networksorcery.com/enp/protocol/rtp.htm). +static const int kRtpSeqNumOffset = 2; +static const int kRtpSeqNumAndTimestampSize = 6; +static const uint32 kDefaultTimeIncrease = 30; + +bool RtpDumpPacket::IsValidRtpPacket() const { + return !is_rtcp && + data.size() >= kRtpSeqNumOffset + kRtpSeqNumAndTimestampSize; +} + +/////////////////////////////////////////////////////////////////////////// +// Implementation of RtpDumpReader. +/////////////////////////////////////////////////////////////////////////// +talk_base::StreamResult RtpDumpReader::ReadPacket(RtpDumpPacket* packet) { + if (!packet) return talk_base::SR_ERROR; + + talk_base::StreamResult res = talk_base::SR_SUCCESS; + // Read the file header if it has not been read yet. + if (!file_header_read_) { + res = ReadFileHeader(); + if (res != talk_base::SR_SUCCESS) { + return res; + } + file_header_read_ = true; + } + + // Read the RTP dump packet header. + char header[RtpDumpPacket::kHeaderLength]; + res = stream_->ReadAll(header, sizeof(header), NULL, NULL); + if (res != talk_base::SR_SUCCESS) { + return res; + } + talk_base::ByteBuffer buf(header, sizeof(header)); + uint16 dump_packet_len; + uint16 data_len; + buf.ReadUInt16(&dump_packet_len); + buf.ReadUInt16(&data_len); // data.size() for RTP, 0 for RTCP. + packet->is_rtcp = (0 == data_len); + buf.ReadUInt32(&packet->elapsed_time); + packet->data.resize(dump_packet_len - sizeof(header)); + + // Read the actual RTP or RTCP packet. + return stream_->ReadAll(&packet->data[0], packet->data.size(), NULL, NULL); +} + +talk_base::StreamResult RtpDumpReader::ReadFileHeader() { + // Read the first line. + std::string first_line; + talk_base::StreamResult res = stream_->ReadLine(&first_line); + if (res != talk_base::SR_SUCCESS) { + return res; + } + if (!CheckFirstLine(first_line)) { + return talk_base::SR_ERROR; + } + + // Read the 16 byte file header. + char header[RtpDumpFileHeader::kHeaderLength]; + res = stream_->ReadAll(header, sizeof(header), NULL, NULL); + if (res == talk_base::SR_SUCCESS) { + talk_base::ByteBuffer buf(header, sizeof(header)); + uint32 start_sec; + uint32 start_usec; + buf.ReadUInt32(&start_sec); + buf.ReadUInt32(&start_usec); + start_time_ms_ = start_sec * 1000 + start_usec / 1000; + // Increase the length by 1 since first_line does not contain the ending \n. + first_line_and_file_header_len_ = first_line.size() + 1 + sizeof(header); + } + return res; +} + +bool RtpDumpReader::CheckFirstLine(const std::string& first_line) { + // The first line is like "#!rtpplay1.0 address/port" + bool matched = (0 == first_line.find("#!rtpplay1.0 ")); + + // The address could be IP or hostname. We do not check it here. Instead, we + // check the port at the end. + size_t pos = first_line.find('/'); + matched &= (pos != std::string::npos && pos < first_line.size() - 1); + for (++pos; pos < first_line.size() && matched; ++pos) { + matched &= (0 != isdigit(first_line[pos])); + } + + return matched; +} + +/////////////////////////////////////////////////////////////////////////// +// Implementation of RtpDumpLoopReader. +/////////////////////////////////////////////////////////////////////////// +RtpDumpLoopReader::RtpDumpLoopReader(talk_base::StreamInterface* stream) + : RtpDumpReader(stream), + loop_count_(0), + elapsed_time_increases_(0), + rtp_seq_num_increase_(0), + rtp_timestamp_increase_(0), + packet_count_(0), + frame_count_(0), + first_elapsed_time_(0), + first_rtp_seq_num_(0), + first_rtp_timestamp_(0), + prev_elapsed_time_(0), + prev_rtp_seq_num_(0), + prev_rtp_timestamp_(0) { +} + +talk_base::StreamResult RtpDumpLoopReader::ReadPacket(RtpDumpPacket* packet) { + if (!packet) return talk_base::SR_ERROR; + + talk_base::StreamResult res = RtpDumpReader::ReadPacket(packet); + if (talk_base::SR_SUCCESS == res) { + if (0 == loop_count_) { + // During the first loop, we update the statistics of the input stream. + UpdateStreamStatistics(*packet); + } + } else if (talk_base::SR_EOS == res) { + if (0 == loop_count_) { + // At the end of the first loop, calculate elapsed_time_increases_, + // rtp_seq_num_increase_, and rtp_timestamp_increase_, which will be + // used during the second and later loops. + CalculateIncreases(); + } + + // Rewind the input stream to the first dump packet and read again. + ++loop_count_; + if (RewindToFirstDumpPacket()) { + res = RtpDumpReader::ReadPacket(packet); + } + } + + if (talk_base::SR_SUCCESS == res && loop_count_ > 0) { + // During the second and later loops, we update the elapsed time of the dump + // packet. If the dumped packet is a RTP packet, we also update its RTP + // sequence number and timestamp. + UpdateDumpPacket(packet); + } + + return res; +} + +void RtpDumpLoopReader::UpdateStreamStatistics(const RtpDumpPacket& packet) { + // Get the RTP sequence number and timestamp of the dump packet. + uint16 rtp_seq_num = 0; + uint32 rtp_timestamp = 0; + if (packet.IsValidRtpPacket()) { + ReadRtpSeqNumAndTimestamp(packet, &rtp_seq_num, &rtp_timestamp); + } + + // Get the timestamps and sequence number for the first dump packet. + if (0 == packet_count_++) { + first_elapsed_time_ = packet.elapsed_time; + first_rtp_seq_num_ = rtp_seq_num; + first_rtp_timestamp_ = rtp_timestamp; + // The first packet belongs to a new payload frame. + ++frame_count_; + } else if (rtp_timestamp != prev_rtp_timestamp_) { + // The current and previous packets belong to different payload frames. + ++frame_count_; + } + + prev_elapsed_time_ = packet.elapsed_time; + prev_rtp_timestamp_ = rtp_timestamp; + prev_rtp_seq_num_ = rtp_seq_num; +} + +void RtpDumpLoopReader::CalculateIncreases() { + // At this time, prev_elapsed_time_, prev_rtp_seq_num_, and + // prev_rtp_timestamp_ are values of the last dump packet in the input stream. + rtp_seq_num_increase_ = prev_rtp_seq_num_ - first_rtp_seq_num_ + 1; + // If we have only one packet or frame, we use the default timestamp + // increase. Otherwise, we use the difference between the first and the last + // packets or frames. + elapsed_time_increases_ = packet_count_ <= 1 ? kDefaultTimeIncrease : + (prev_elapsed_time_ - first_elapsed_time_) * packet_count_ / + (packet_count_ - 1); + rtp_timestamp_increase_ = frame_count_ <= 1 ? kDefaultTimeIncrease : + (prev_rtp_timestamp_ - first_rtp_timestamp_) * frame_count_ / + (frame_count_ - 1); +} + +void RtpDumpLoopReader::UpdateDumpPacket(RtpDumpPacket* packet) { + // Increase the elapsed time of the dump packet. + packet->elapsed_time += loop_count_ * elapsed_time_increases_; + + if (packet->IsValidRtpPacket()) { + // Get the old RTP sequence number and timestamp. + uint16 sequence; + uint32 timestamp; + ReadRtpSeqNumAndTimestamp(*packet, &sequence, ×tamp); + // Increase the RTP sequence number and timestamp. + sequence += loop_count_ * rtp_seq_num_increase_; + timestamp += loop_count_ * rtp_timestamp_increase_; + // Write the updated sequence number and timestamp back to the RTP packet. + talk_base::ByteBuffer buffer; + buffer.WriteUInt16(sequence); + buffer.WriteUInt32(timestamp); + memcpy(&packet->data[0] + kRtpSeqNumOffset, buffer.Data(), buffer.Length()); + } +} + +void RtpDumpLoopReader::ReadRtpSeqNumAndTimestamp( + const RtpDumpPacket& packet, uint16* sequence, uint32* timestamp) { + talk_base::ByteBuffer buffer( + reinterpret_cast<const char*>(&packet.data[0] + kRtpSeqNumOffset), + kRtpSeqNumAndTimestampSize); + buffer.ReadUInt16(sequence); + buffer.ReadUInt32(timestamp); +} + +/////////////////////////////////////////////////////////////////////////// +// Implementation of RtpDumpWriter. +/////////////////////////////////////////////////////////////////////////// +uint32 RtpDumpWriter::GetElapsedTime() const { + return talk_base::TimeSince(start_time_ms_); +} + +talk_base::StreamResult RtpDumpWriter::WritePacket( + const void* data, size_t data_len, uint32 elapsed, bool rtcp) { + if (!data || 0 == data_len) return talk_base::SR_ERROR; + + talk_base::StreamResult res = talk_base::SR_SUCCESS; + // Write the file header if it has not been written yet. + if (!file_header_written_) { + res = WriteFileHeader(); + if (res != talk_base::SR_SUCCESS) { + return res; + } + file_header_written_ = true; + } + + // Write the dump packet header. + talk_base::ByteBuffer buf; + buf.WriteUInt16(static_cast<uint16>(RtpDumpPacket::kHeaderLength + data_len)); + buf.WriteUInt16(static_cast<uint16>(rtcp ? 0 : data_len)); + buf.WriteUInt32(elapsed); + res = stream_->WriteAll(buf.Data(), buf.Length(), NULL, NULL); + if (res != talk_base::SR_SUCCESS) { + return res; + } + + // Write the actual RTP or RTCP packet. + return stream_->WriteAll(data, data_len, NULL, NULL); +} + +talk_base::StreamResult RtpDumpWriter::WriteFileHeader() { + talk_base::StreamResult res = stream_->WriteAll( + kRtpDumpFileFirstLine, strlen(kRtpDumpFileFirstLine), NULL, NULL); + if (res != talk_base::SR_SUCCESS) { + return res; + } + + talk_base::ByteBuffer buf; + RtpDumpFileHeader file_header(talk_base::Time(), 0, 0); + file_header.WriteToByteBuffer(&buf); + return stream_->WriteAll(buf.Data(), buf.Length(), NULL, NULL); +} + +} // namespace cricket diff --git a/third_party/libjingle/source/talk/session/phone/rtpdump.h b/third_party/libjingle/source/talk/session/phone/rtpdump.h new file mode 100644 index 0000000..40c4e03 --- /dev/null +++ b/third_party/libjingle/source/talk/session/phone/rtpdump.h @@ -0,0 +1,184 @@ +/* + * libjingle + * Copyright 2010, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TALK_SESSION_PHONE_RTPDUMP_H_ +#define TALK_SESSION_PHONE_RTPDUMP_H_ + +#include <cstring> +#include <string> +#include <vector> + +#include "talk/base/basictypes.h" +#include "talk/base/stream.h" + +namespace cricket { + +// We use the RTP dump file format compatible to the format used by rtptools +// (http://www.cs.columbia.edu/irt/software/rtptools/) and Wireshark +// (http://wiki.wireshark.org/rtpdump). In particular, the file starts with the +// first line "#!rtpplay1.0 address/port\n", followed by a 16 byte file header. +// For each packet, the file contains a 8 byte dump packet header, followed by +// the actual RTP or RTCP packet. + +struct RtpDumpPacket { + RtpDumpPacket() {} + + RtpDumpPacket(const void* d, size_t s, uint32 elapsed, bool rtcp) + : elapsed_time(elapsed), + is_rtcp(rtcp) { + data.resize(s); + memcpy(&data[0], d, s); + } + + // Check if the dumped packet is a valid RTP packet with the sequence number + // and timestamp. + bool IsValidRtpPacket() const; + + static const size_t kHeaderLength = 8; + uint32 elapsed_time; // Milliseconds since the start of recording. + bool is_rtcp; // True if the data below is a RTCP packet. + std::vector<uint8> data; // The actual RTP or RTCP packet. +}; + +class RtpDumpReader { + public: + explicit RtpDumpReader(talk_base::StreamInterface* stream) + : stream_(stream), + file_header_read_(false), + first_line_and_file_header_len_(0), + start_time_ms_(0) { + } + virtual ~RtpDumpReader() {} + + virtual talk_base::StreamResult ReadPacket(RtpDumpPacket* packet); + + protected: + talk_base::StreamResult ReadFileHeader(); + bool RewindToFirstDumpPacket() { + return stream_->SetPosition(first_line_and_file_header_len_); + } + + private: + // Check if its matches "#!rtpplay1.0 address/port\n". + bool CheckFirstLine(const std::string& first_line); + + talk_base::StreamInterface* stream_; + bool file_header_read_; + size_t first_line_and_file_header_len_; + uint32 start_time_ms_; + DISALLOW_COPY_AND_ASSIGN(RtpDumpReader); +}; + +// RtpDumpLoopReader reads RTP dump packets from the input stream and rewinds +// the stream when it ends. RtpDumpLoopReader maintains the elapsed time, the +// RTP sequence number and the RTP timestamp properly. RtpDumpLoopReader can +// handle both RTP dump and RTCP dump. We assume that the dump does not mix +// RTP packets and RTCP packets. +class RtpDumpLoopReader : public RtpDumpReader { + public: + explicit RtpDumpLoopReader(talk_base::StreamInterface* stream); + virtual talk_base::StreamResult ReadPacket(RtpDumpPacket* packet); + + private: + // Read the sequence number and timestamp from the RTP dump packet. + static void ReadRtpSeqNumAndTimestamp(const RtpDumpPacket& packet, + uint16* seq_num, uint32* timestamp); + + // During the first loop, update the statistics, including packet count, frame + // count, timestamps, and sequence number, of the input stream. + void UpdateStreamStatistics(const RtpDumpPacket& packet); + + // At the end of first loop, calculate elapsed_time_increases_, + // rtp_seq_num_increase_, and rtp_timestamp_increase_. + void CalculateIncreases(); + + // During the second and later loops, update the elapsed time of the dump + // packet. If the dumped packet is a RTP packet, update its RTP sequence + // number and timestamp as well. + void UpdateDumpPacket(RtpDumpPacket* packet); + + int loop_count_; + // How much to increase the elapsed time, RTP sequence number, RTP timestampe + // for each loop. They are calcualted with the variables below during the + // first loop. + uint32 elapsed_time_increases_; + uint16 rtp_seq_num_increase_; + uint32 rtp_timestamp_increase_; + // How many RTP packets and how many payload frames in the input stream. RTP + // packets belong to the same frame have the same RTP timestamp, different + // dump timestamp, and different RTP sequence number. + uint32 packet_count_; + uint32 frame_count_; + // The elapsed time, RTP sequence number, and RTP timestamp of the first and + // the previous dump packets in the input stream. + uint32 first_elapsed_time_; + uint16 first_rtp_seq_num_; + uint32 first_rtp_timestamp_; + uint32 prev_elapsed_time_; + uint16 prev_rtp_seq_num_; + uint32 prev_rtp_timestamp_; + + DISALLOW_COPY_AND_ASSIGN(RtpDumpLoopReader); +}; + +class RtpDumpWriter { + public: + explicit RtpDumpWriter(talk_base::StreamInterface* stream) + : stream_(stream), + file_header_written_(false), + start_time_ms_(0) { + } + // Write a RTP or RTCP packet. The parameters data points to the packet and + // data_len is its length. + talk_base::StreamResult WriteRtpPacket(const void* data, size_t data_len) { + return WritePacket(data, data_len, GetElapsedTime(), false); + } + talk_base::StreamResult WriteRtcpPacket(const void* data, size_t data_len) { + return WritePacket(data, data_len, GetElapsedTime(), true); + } + talk_base::StreamResult WritePacket(const RtpDumpPacket& packet) { + return WritePacket(&packet.data[0], packet.data.size(), packet.elapsed_time, + packet.is_rtcp); + } + uint32 GetElapsedTime() const; + + protected: + talk_base::StreamResult WriteFileHeader(); + + private: + talk_base::StreamResult WritePacket(const void* data, size_t data_len, + uint32 elapsed, bool rtcp); + + talk_base::StreamInterface* stream_; + bool file_header_written_; + uint32 start_time_ms_; // Time when the record starts. + DISALLOW_COPY_AND_ASSIGN(RtpDumpWriter); +}; + +} // namespace cricket + +#endif // TALK_SESSION_PHONE_RTPDUMP_H_ diff --git a/third_party/libjingle/source/talk/session/phone/srtpfilter.cc b/third_party/libjingle/source/talk/session/phone/srtpfilter.cc index 2770281..63daed6 100644 --- a/third_party/libjingle/source/talk/session/phone/srtpfilter.cc +++ b/third_party/libjingle/source/talk/session/phone/srtpfilter.cc @@ -35,7 +35,7 @@ #include "talk/base/base64.h" #include "talk/base/logging.h" -// TODO(juberti): For the XCode build, we force SRTP (b/2500074) +// TODO: For the XCode build, we force SRTP (b/2500074) #if defined(OSX) && !defined(HAVE_SRTP) #define HAVE_SRTP 1 #endif @@ -175,7 +175,7 @@ bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, bool SrtpFilter::ApplyParams(const CryptoParams& send_params, const CryptoParams& recv_params) { - // TODO(juberti): Zero these buffers after use. + // TODO: Zero these buffers after use. bool ret; uint8 send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN]; ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) && @@ -334,7 +334,7 @@ bool SrtpSession::SetKey(int type, const std::string& cs, policy.ssrc.type = static_cast<ssrc_type_t>(type); policy.ssrc.value = 0; policy.key = const_cast<uint8*>(key); - // TODO(astor) parse window size from WSH session-param + // TODO parse window size from WSH session-param policy.window_size = 1024; policy.allow_repeat_tx = 1; policy.next = NULL; @@ -375,7 +375,7 @@ bool SrtpSession::Init() { } void SrtpSession::HandleEvent(const srtp_event_data_t* ev) { - // TODO(juberti): Do something about events. + // TODO: Do something about events. } void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { diff --git a/third_party/libjingle/source/talk/session/phone/srtpfilter.h b/third_party/libjingle/source/talk/session/phone/srtpfilter.h index 032c112..71b74e0 100644 --- a/third_party/libjingle/source/talk/session/phone/srtpfilter.h +++ b/third_party/libjingle/source/talk/session/phone/srtpfilter.h @@ -91,7 +91,7 @@ class SrtpSession { // Initialize by calling SetSend with the local security params, then call // SetRecv once the remote security params are received. At that point // Protect/UnprotectRt(c)p can be called to encrypt/decrypt data. -// TODO(juberti): Figure out concurrency policy for SrtpFilter. +// TODO: Figure out concurrency policy for SrtpFilter. class SrtpFilter { public: SrtpFilter(); diff --git a/third_party/libjingle/source/talk/session/phone/testdata/video.rtpdump b/third_party/libjingle/source/talk/session/phone/testdata/video.rtpdump Binary files differnew file mode 100644 index 0000000..3b0139b --- /dev/null +++ b/third_party/libjingle/source/talk/session/phone/testdata/video.rtpdump diff --git a/third_party/libjingle/source/talk/session/phone/testdata/voice.rtpdump b/third_party/libjingle/source/talk/session/phone/testdata/voice.rtpdump Binary files differnew file mode 100644 index 0000000..5920d1d --- /dev/null +++ b/third_party/libjingle/source/talk/session/phone/testdata/voice.rtpdump diff --git a/third_party/libjingle/source/talk/session/phone/v4llookup.cc b/third_party/libjingle/source/talk/session/phone/v4llookup.cc index 7a283a0..e8436e1 100644 --- a/third_party/libjingle/source/talk/session/phone/v4llookup.cc +++ b/third_party/libjingle/source/talk/session/phone/v4llookup.cc @@ -1,6 +1,6 @@ /* * Copyright 2009, Google Inc. - * Author: lexnikitin + * Author: lexnikitin@google.com (Alexey Nikitin) * * V4LLookup provides basic functionality to work with V2L2 devices in Linux * The functionality is implemented as a class with virtual methods for diff --git a/third_party/libjingle/source/talk/session/phone/v4llookup.h b/third_party/libjingle/source/talk/session/phone/v4llookup.h index 64313a8..1150172 100644 --- a/third_party/libjingle/source/talk/session/phone/v4llookup.h +++ b/third_party/libjingle/source/talk/session/phone/v4llookup.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Google Inc. - * Author: lexnikitin + * Author: lexnikitin@google.com (Alexey Nikitin) * * V4LLookup provides basic functionality to work with V2L2 devices in Linux * The functionality is implemented as a class with virtual methods for diff --git a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc b/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc index 3df3bfc..0448853 100644 --- a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc +++ b/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc @@ -25,9 +25,11 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <string> #include "talk/base/basictypes.h" #include "talk/base/common.h" #include "talk/base/logging.h" +#include "talk/base/scoped_ptr.h" #include "talk/base/stringutils.h" #include "talk/p2p/base/transportchannel.h" #include "pseudotcpchannel.h" @@ -116,7 +118,8 @@ PseudoTcpChannel::~PseudoTcpChannel() { ASSERT(tcp_ == NULL); } -bool PseudoTcpChannel::Connect(const std::string& channel_name) { +bool PseudoTcpChannel::Connect(const std::string& content_name, + const std::string& channel_name) { ASSERT(signal_thread_->IsCurrent()); CritScope lock(&cs_); @@ -125,7 +128,8 @@ bool PseudoTcpChannel::Connect(const std::string& channel_name) { ASSERT(session_ != NULL); worker_thread_ = session_->session_manager()->worker_thread(); - channel_ = session_->CreateChannel(channel_name); + content_name_ = content_name; + channel_ = session_->CreateChannel(content_name, channel_name); channel_name_ = channel_name; channel_->SetOption(Socket::OPT_DONTFRAGMENT, 1); @@ -450,7 +454,7 @@ void PseudoTcpChannel::OnMessage(Message* pmsg) { LOG_F(LS_INFO) << "(MSG_SI_DESTROYCHANNEL)"; ASSERT(session_ != NULL); ASSERT(channel_ != NULL); - session_->DestroyChannel(channel_); + session_->DestroyChannel(content_name_, channel_->name()); } else if (pmsg->message_id == MSG_SI_DESTROY) { diff --git a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h b/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h index ff1db96..fbcb611 100644 --- a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h +++ b/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h @@ -66,7 +66,8 @@ public: PseudoTcpChannel(talk_base::Thread* stream_thread, Session* session); - bool Connect(const std::string& channel_name); + bool Connect(const std::string& content_name, + const std::string& channel_name); talk_base::StreamInterface* GetStream(); sigslot::signal1<PseudoTcpChannel*> SignalChannelClosed; @@ -112,6 +113,7 @@ private: talk_base::Thread* signal_thread_, * worker_thread_, * stream_thread_; Session* session_; TransportChannel* channel_; + std::string content_name_; std::string channel_name_; PseudoTcp* tcp_; InternalStream* stream_; diff --git a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.cc b/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.cc index 2ac23f0..84ec5e0 100644 --- a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.cc +++ b/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.cc @@ -129,21 +129,27 @@ TunnelSession* SecureTunnelSessionClient::MakeTunnelSession( return new SecureTunnelSession(this, session, stream_thread, role); } -const SecureTunnelContentDescription* FindSecureTunnelContent( - const cricket::SessionDescription* sdesc) { +bool FindSecureTunnelContent(const cricket::SessionDescription* sdesc, + std::string* name, + const SecureTunnelContentDescription** content) { const ContentInfo* cinfo = sdesc->FirstContentByType(NS_SECURE_TUNNEL); if (cinfo == NULL) - return NULL; + return false; - return static_cast<const SecureTunnelContentDescription*>( + *name = cinfo->name; + *content = static_cast<const SecureTunnelContentDescription*>( cinfo->description); + return true; } void SecureTunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid, Session *session) { - const SecureTunnelContentDescription* content = - FindSecureTunnelContent(session->remote_description()); - ASSERT(content != NULL); + std::string content_name; + const SecureTunnelContentDescription* content = NULL; + if (!FindSecureTunnelContent(session->remote_description(), + &content_name, &content)) { + ASSERT(false); + } // Validate the certificate talk_base::scoped_ptr<talk_base::SSLCertificate> peer_cert( @@ -206,7 +212,8 @@ void SecureTunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid, // </iq> -bool SecureTunnelSessionClient::ParseContent(const buzz::XmlElement* elem, +bool SecureTunnelSessionClient::ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* elem, const ContentDescription** content, ParseError* error) { const buzz::XmlElement* type_elem = elem->FirstNamed(QN_SECURE_TUNNEL_TYPE); @@ -232,7 +239,7 @@ bool SecureTunnelSessionClient::ParseContent(const buzz::XmlElement* elem, } bool SecureTunnelSessionClient::WriteContent( - const ContentDescription* untyped_content, + SignalingProtocol protocol, const ContentDescription* untyped_content, buzz::XmlElement** elem, WriteError* error) { const SecureTunnelContentDescription* content = static_cast<const SecureTunnelContentDescription*>(untyped_content); @@ -259,9 +266,9 @@ bool SecureTunnelSessionClient::WriteContent( } SessionDescription* NewSecureTunnelSessionDescription( - const ContentDescription* content) { + const std::string& content_name, const ContentDescription* content) { SessionDescription* sdesc = new SessionDescription(); - sdesc->AddContent(CN_SECURE_TUNNEL, NS_SECURE_TUNNEL, content); + sdesc->AddContent(content_name, NS_SECURE_TUNNEL, content); return sdesc; } @@ -271,14 +278,15 @@ SessionDescription* SecureTunnelSessionClient::CreateOffer( // description. std::string pem_cert = GetIdentity().certificate().ToPEMString(); return NewSecureTunnelSessionDescription( + CN_SECURE_TUNNEL, new SecureTunnelContentDescription(description, pem_cert, "")); } SessionDescription* SecureTunnelSessionClient::CreateAnswer( const SessionDescription* offer) { - const SecureTunnelContentDescription* offer_tunnel = - FindSecureTunnelContent(offer); - if (offer_tunnel == NULL) + std::string content_name; + const SecureTunnelContentDescription* offer_tunnel = NULL; + if (!FindSecureTunnelContent(offer, &content_name, &offer_tunnel)) return NULL; // We are accepting a session request. We need to add our cert, the @@ -286,6 +294,7 @@ SessionDescription* SecureTunnelSessionClient::CreateAnswer( // in OnIncomingTunnel(). ASSERT(!offer_tunnel->client_pem_certificate.empty()); return NewSecureTunnelSessionDescription( + content_name, new SecureTunnelContentDescription( offer_tunnel->description, offer_tunnel->client_pem_certificate, @@ -336,9 +345,13 @@ void SecureTunnelSession::OnAccept() { // connect the tunnel. First we must set the peer certificate. ASSERT(channel_ != NULL); ASSERT(session_ != NULL); - const SecureTunnelContentDescription* remote_tunnel = - FindSecureTunnelContent(session_->remote_description()); - ASSERT(remote_tunnel != NULL); + std::string content_name; + const SecureTunnelContentDescription* remote_tunnel = NULL; + if (!FindSecureTunnelContent(session_->remote_description(), + &content_name, &remote_tunnel)) { + session_->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS); + return; + } const std::string& cert_pem = role_ == INITIATOR ? remote_tunnel->server_pem_certificate : @@ -349,7 +362,7 @@ void SecureTunnelSession::OnAccept() { ASSERT(role_ == INITIATOR); // when RESPONDER we validated it earlier LOG(LS_ERROR) << "Rejecting secure tunnel accept with invalid cetificate"; - session_->Terminate(); + session_->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS); return; } ASSERT(ssl_stream_reference_.get() != NULL); @@ -363,7 +376,7 @@ void SecureTunnelSession::OnAccept() { // This will try to connect the PseudoTcpChannel. If and when that // succeeds, then ssl negotiation will take place, and when that // succeeds, the tunnel stream will finally open. - VERIFY(channel_->Connect("tcp")); + VERIFY(channel_->Connect(content_name, "tcp")); } } // namespace cricket diff --git a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.h b/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.h index 6b0abd7..cb9a99c 100644 --- a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.h +++ b/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.h @@ -81,10 +81,12 @@ class SecureTunnelSessionClient : public TunnelSessionClient { // Inherited methods virtual void OnIncomingTunnel(const buzz::Jid& jid, Session *session); - virtual bool ParseContent(const buzz::XmlElement* elem, + virtual bool ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* elem, const ContentDescription** content, ParseError* error); - virtual bool WriteContent(const ContentDescription* content, + virtual bool WriteContent(SignalingProtocol protocol, + const ContentDescription* content, buzz::XmlElement** elem, WriteError* error); virtual SessionDescription* CreateOffer( diff --git a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc b/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc index facb08b..13d5c10 100644 --- a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc +++ b/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc @@ -31,6 +31,7 @@ #include "talk/base/helpers.h" #include "talk/base/logging.h" #include "talk/base/stringutils.h" +#include "talk/p2p/base/constants.h" #include "talk/p2p/base/transportchannel.h" #include "talk/xmllite/xmlelement.h" #include "pseudotcpchannel.h" @@ -174,7 +175,7 @@ talk_base::StreamInterface* TunnelSessionClientBase::AcceptTunnel( void TunnelSessionClientBase::DeclineTunnel(Session* session) { ASSERT(session_manager_->signaling_thread()->IsCurrent()); - session->Reject(); + session->Reject(STR_TERMINATE_DECLINE); } void TunnelSessionClientBase::OnMessage(talk_base::Message* pmsg) { @@ -216,7 +217,8 @@ TunnelSessionClient::~TunnelSessionClient() { } -bool TunnelSessionClient::ParseContent(const buzz::XmlElement* elem, +bool TunnelSessionClient::ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* elem, const ContentDescription** content, ParseError* error) { if (const buzz::XmlElement* type_elem = elem->FirstNamed(QN_TUNNEL_TYPE)) { @@ -227,6 +229,7 @@ bool TunnelSessionClient::ParseContent(const buzz::XmlElement* elem, } bool TunnelSessionClient::WriteContent( + SignalingProtocol protocol, const ContentDescription* untyped_content, buzz::XmlElement** elem, WriteError* error) { const TunnelContentDescription* content = @@ -241,27 +244,34 @@ bool TunnelSessionClient::WriteContent( } SessionDescription* NewTunnelSessionDescription( - const ContentDescription* content) { + const std::string& content_name, const ContentDescription* content) { SessionDescription* sdesc = new SessionDescription(); - sdesc->AddContent(CN_TUNNEL, NS_TUNNEL, content); + sdesc->AddContent(content_name, NS_TUNNEL, content); return sdesc; } -const TunnelContentDescription* FindTunnelContent( - const cricket::SessionDescription* sdesc) { +bool FindTunnelContent(const cricket::SessionDescription* sdesc, + std::string* name, + const TunnelContentDescription** content) { const ContentInfo* cinfo = sdesc->FirstContentByType(NS_TUNNEL); if (cinfo == NULL) - return NULL; + return false; - return static_cast<const TunnelContentDescription*>( + *name = cinfo->name; + *content = static_cast<const TunnelContentDescription*>( cinfo->description); + return true; } void TunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid, Session *session) { - const TunnelContentDescription* content = FindTunnelContent( - session->remote_description()); - ASSERT(content != NULL); + std::string content_name; + const TunnelContentDescription* content = NULL; + if (!FindTunnelContent(session->remote_description(), + &content_name, &content)) { + session->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS); + return; + } SignalIncomingTunnel(this, jid, content->description, session); } @@ -269,17 +279,18 @@ void TunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid, SessionDescription* TunnelSessionClient::CreateOffer( const buzz::Jid &jid, const std::string &description) { return NewTunnelSessionDescription( - new TunnelContentDescription(description)); + CN_TUNNEL, new TunnelContentDescription(description)); } SessionDescription* TunnelSessionClient::CreateAnswer( const SessionDescription* offer) { - const TunnelContentDescription* offer_tunnel = FindTunnelContent(offer); - if (offer_tunnel == NULL) + std::string content_name; + const TunnelContentDescription* offer_tunnel = NULL; + if (!FindTunnelContent(offer, &content_name, &offer_tunnel)) return NULL; return NewTunnelSessionDescription( - new TunnelContentDescription(offer_tunnel->description)); + content_name, new TunnelContentDescription(offer_tunnel->description)); } /////////////////////////////////////////////////////////////////////////////// // TunnelSession @@ -365,7 +376,10 @@ void TunnelSession::OnInitiate() { void TunnelSession::OnAccept() { ASSERT(channel_ != NULL); - VERIFY(channel_->Connect("tcp")); + const ContentInfo* content = + session_->remote_description()->FirstContentByType(NS_TUNNEL); + ASSERT(content != NULL); + VERIFY(channel_->Connect(content->name, "tcp")); } void TunnelSession::OnTerminate() { diff --git a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.h b/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.h index 6746ced..7259fa1 100644 --- a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.h +++ b/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.h @@ -29,8 +29,10 @@ #define __TUNNELSESSIONCLIENT_H__ #include <vector> + #include "talk/base/criticalsection.h" #include "talk/base/stream.h" +#include "talk/p2p/base/constants.h" #include "talk/p2p/base/pseudotcp.h" #include "talk/p2p/base/session.h" #include "talk/p2p/base/sessiondescription.h" @@ -110,10 +112,12 @@ public: const std::string &ns); virtual ~TunnelSessionClient(); - virtual bool ParseContent(const buzz::XmlElement* elem, + virtual bool ParseContent(SignalingProtocol protocol, + const buzz::XmlElement* elem, const ContentDescription** content, ParseError* error); - virtual bool WriteContent(const ContentDescription* content, + virtual bool WriteContent(SignalingProtocol protocol, + const ContentDescription* content, buzz::XmlElement** elem, WriteError* error); @@ -140,7 +144,7 @@ public: /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // TunnelStream -// Note: Because TunnelStream provides a stream interface, it's lifetime is +// Note: Because TunnelStream provides a stream interface, its lifetime is // controlled by the owner of the stream pointer. As a result, we must support // both the TunnelSession disappearing before TunnelStream, and vice versa. /////////////////////////////////////////////////////////////////////////////// diff --git a/third_party/libjingle/source/talk/site_scons/site_tools/talk_noops.pyc b/third_party/libjingle/source/talk/site_scons/site_tools/talk_noops.pyc Binary files differnew file mode 100644 index 0000000..d25fa59 --- /dev/null +++ b/third_party/libjingle/source/talk/site_scons/site_tools/talk_noops.pyc diff --git a/third_party/libjingle/source/talk/site_scons/talk.py b/third_party/libjingle/source/talk/site_scons/talk.py index 50cff66..e5ede4f 100644 --- a/third_party/libjingle/source/talk/site_scons/talk.py +++ b/third_party/libjingle/source/talk/site_scons/talk.py @@ -6,6 +6,9 @@ # import os +# Keep a global list of what libraries have a 64 bit version. We use it for +# replacements when linking a 64 bit dylib or executable. +libs64 = [] def Library(env, **kwargs): """Extends ComponentLibrary to support multiplatform builds. @@ -15,7 +18,10 @@ def Library(env, **kwargs): kwargs: The keyword arguments. """ params = CombineDicts(kwargs, {'COMPONENT_STATIC': True}) - return ExtendComponent(env, env.ComponentLibrary, **params) + if params.has_key('also64bit'): + libs64.append(params['name']) + + return ExtendComponent(env, 'ComponentLibrary', **params) def DynamicLibrary(env, **kwargs): @@ -30,11 +36,11 @@ def DynamicLibrary(env, **kwargs): See swtoolkit ComponentLibrary """ params = CombineDicts(kwargs, {'COMPONENT_STATIC': False}) - return ExtendComponent(env, env.ComponentLibrary, **params) + return ExtendComponent(env, 'ComponentLibrary', **params) def Object(env, **kwargs): - return ExtendComponent(env, env.ComponentObject, **kwargs) + return ExtendComponent(env, 'ComponentObject', **kwargs) def Unittest(env, **kwargs): @@ -73,7 +79,7 @@ def Unittest(env, **kwargs): ] params = CombineDicts(kwargs, common_test_params) - return ExtendComponent(env, env.ComponentTestProgram, **params) + return ExtendComponent(env, 'ComponentTestProgram', **params) def App(env, **kwargs): @@ -103,7 +109,7 @@ def App(env, **kwargs): params = CombineDicts(kwargs, common_app_params) else: params = kwargs - return ExtendComponent(env, env.ComponentProgram, **params) + return ExtendComponent(env, 'ComponentProgram', **params) def WiX(env, **kwargs): """ Extends the WiX builder @@ -114,7 +120,7 @@ def WiX(env, **kwargs): Returns: The node produced by the environment's wix builder """ - return ExtendComponent(env, env.WiX, **kwargs) + return ExtendComponent(env, 'WiX', **kwargs) def Repository(env, at, path): """Maps a directory external to $MAIN_DIR to the given path so that sources @@ -293,12 +299,6 @@ def ReadVersion(filename): # Helper methods for translating talk.Foo() declarations in to manipulations of # environmuent construction variables, including parameter parsing and merging, # -def Depends(env, name, kwargs): - depends = GetEntry(kwargs, 'depends') - if depends is not None: - env.Depends(name, depends) - - def GetEntry(dict, key): """Get the value from a dictionary by key. If the key isn't in the dictionary then None is returned. If it is in @@ -371,15 +371,9 @@ def MergeAndFilterByPlatform(env, params): def ExtendComponent(env, component, **kwargs): """A wrapper around a scons builder function that preprocesses and post- processes its inputs and outputs. For example, it merges and filters - fields based on platform and build mode, factors out common includes, - and can make a digitally signed copy of the output. - - Why do we build everything up in to the params dict and pass explicitly - to component? We've just always done it that way? It's probably more - conventional to clone env, append or prepend in to env's existing - construction variables, then call component(srcs, target) without any extra - paremters. Both methods ensure settings from one target don't leak back in - to the original env polluting later targets. + certain keyword arguments before appending them to the environments + construction variables. It can build signed targets and 64bit copies + of targets as well. Args: env: The hammer environment with which to build the target @@ -392,51 +386,106 @@ def ExtendComponent(env, component, **kwargs): The output node returned by the call to component, or a subsequent signed dependant node. """ + env = env.Clone() - # get our target identifier + # get the 'target' field name = GetEntry(kwargs, 'name') - signed = env.Bit('windows') and kwargs.has_key('signed') and kwargs['signed'] + # if this is a signed binary we need to make an unsigned version first + signed = env.Bit('windows') and GetEntry(kwargs, 'signed') if signed: name = 'unsigned_' + name - if (kwargs.has_key('include_talk_media_libs') and - kwargs['include_talk_media_libs']): + also64bit = env.Bit('linux') and GetEntry(kwargs, 'also64bit') + + # add default values + if GetEntry(kwargs, 'include_talk_media_libs'): kwargs = AddMediaLibs(env, **kwargs) - # prune parameters for inactive platforms or modes - # and combine the rest of the platforms + # prune parameters intended for other platforms, then merge params = MergeAndFilterByPlatform(env, kwargs) - # apply any explicit dependencies - Depends(env, name, kwargs) - - AddToDict(params, 'CPPDEFINES', env.Dictionary('CPPDEFINES'), False) - AddToDict(params, 'CPPPATH', env.Dictionary('CPPPATH'), False) - AddToDict(params, 'CCFLAGS', env.Dictionary('CCFLAGS'), False) - AddToDict(params, 'LIBPATH', env.Dictionary('LIBPATH'), False) - AddToDict(params, 'LINKFLAGS', env.Dictionary('LINKFLAGS'), False) - if env.Bit('mac'): - AddToDict(params, 'FRAMEWORKS', env.Dictionary('FRAMEWORKS'), False) - - RenameKey(params, 'cppdefines', 'CPPDEFINES') - if params.has_key('prepend_includedirs'): - RenameKey(params, 'includedirs', 'CPPPATH', False) - else: - RenameKey(params, 'includedirs', 'CPPPATH') - RenameKey(params, 'ccflags', 'CCFLAGS', False) - RenameKey(params, 'libdirs', 'LIBPATH') - RenameKey(params, 'link_flags', 'LINKFLAGS') - RenameKey(params, 'libs', 'LIBS') - + # potentially exit now srcs = GetEntry(params, 'srcs') - if srcs is None or len(srcs) == 0: + if not srcs or not hasattr(env, component): return None - # invoke the builder function - node = component(name, srcs, **params) + # apply any explicit dependencies + dependencies = GetEntry(kwargs, 'depends') + if dependencies is not None: + env.Depends(name, dependencies) + + # put the contents of params into the environment + # some entries are renamed then appended, others renamed then prepended + appends = { + 'cppdefines' : 'CPPDEFINES', + 'libdirs' : 'LIBPATH', + 'link_flags' : 'LINKFLAGS', + 'libs' : 'LIBS', + 'FRAMEWORKS' : 'FRAMEWORKS', + } + prepends = { + 'ccflags' : 'CCFLAGS', + } + if GetEntry(params, 'prepend_includedirs'): + prepends['includedirs'] = 'CPPPATH' + else: + appends['includedirs'] = 'CPPPATH' + + for field, var in appends.items(): + values = GetEntry(params, field) + if values is not None: + env.Append(**{var : values}) + for field, var in prepends.items(): + values = GetEntry(params, field) + if values is not None: + env.Prepend(**{var : values}) + + # workaround for pulse stripping link flag for unknown reason + if env.Bit('linux'): + env['SHLINKCOM'] = ('$SHLINK -o $TARGET -m32 $SHLINKFLAGS $SOURCES ' + '$_LIBDIRFLAGS $_LIBFLAGS') + env['LINKCOM'] = ('$LINK -o $TARGET -m32 $LINKFLAGS $SOURCES ' + '$_LIBDIRFLAGS $_LIBFLAGS') + + # any other parameters are replaced without renaming + for field, value in params.items(): + env.Replace(**{field : value}) - if signed: + # invoke the builder function + builder = getattr(env, component) + + node = builder(name, srcs) + + # make a parallel 64bit version if requested + if also64bit: + env_64bit = env.Clone() + env_64bit.FilterOut(CCFLAGS = ['-m32'], LINKFLAGS = ['-m32']) + env_64bit.Prepend(CCFLAGS = ['-m64', '-fPIC'], LINKFLAGS = ['-m64']) + name_64bit = name + '64' + env_64bit.Replace(OBJSUFFIX = '64' + env_64bit['OBJSUFFIX']) + env_64bit.Replace(SHOBJSUFFIX = '64' + env_64bit['SHOBJSUFFIX']) + if ('ComponentProgram' == component or + ('ComponentLibrary' == component and + env_64bit['COMPONENT_STATIC'] == False)): + # link 64 bit versions of libraries + libs = [] + for lib in env_64bit['LIBS']: + if lib in set(libs64): + libs.append(lib + '64') + else: + libs.append(lib) + env_64bit.Replace(LIBS = libs) + + env_64bit['SHLINKCOM'] = ('$SHLINK -o $TARGET -m64 $SHLINKFLAGS $SOURCES ' + '$_LIBDIRFLAGS $_LIBFLAGS') + env_64bit['LINKCOM'] = ('$LINK -o $TARGET -m64 $LINKFLAGS $SOURCES ' + '$_LIBDIRFLAGS $_LIBFLAGS') + builder = getattr(env_64bit, component) + nodes = [node, builder(name_64bit, srcs)] + return nodes + + if signed: # Note currently incompatible with 64Bit flag # Get the name of the built binary, then get the name of the final signed # version from it. We need the output path since we don't know the file # extension beforehand. @@ -447,8 +496,8 @@ def ExtendComponent(env, component, **kwargs): ) env.Alias('signed_binaries', signed_node) return signed - else: - return node + + return node def AddToDict(dictionary, key, values, append=True): @@ -464,7 +513,7 @@ def AddToDict(dictionary, key, values, append=True): return cur = dictionary[key] - # TODO(dape): Make sure that there are no duplicates + # TODO: Make sure that there are no duplicates # in the list. I can't use python set for this since # the nodes that are returned by the SCONS builders # are not hashable. diff --git a/third_party/libjingle/source/talk/site_scons/talk.pyc b/third_party/libjingle/source/talk/site_scons/talk.pyc Binary files differnew file mode 100644 index 0000000..308d2e8 --- /dev/null +++ b/third_party/libjingle/source/talk/site_scons/talk.pyc diff --git a/third_party/libjingle/source/talk/third_party/expat/BUILD b/third_party/libjingle/source/talk/third_party/expat/BUILD deleted file mode 100644 index 1293685..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/BUILD +++ /dev/null @@ -1,9 +0,0 @@ -# -*- mode: python; -*- -# -# Copyright 2007 Google Inc. -# All Rights Reserved. -# -# Description: -# Expat - a small open-source XML parser. - -licenses(['notice']) # MIT diff --git a/third_party/libjingle/source/talk/third_party/expat/COPYING.txt b/third_party/libjingle/source/talk/third_party/expat/COPYING.txt deleted file mode 100644 index dcb4506..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/COPYING.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - and Clark Cooper -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/libjingle/source/talk/third_party/expat/OWNERS b/third_party/libjingle/source/talk/third_party/expat/OWNERS deleted file mode 100644 index 82f5639..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -dimich -moishel - diff --git a/third_party/libjingle/source/talk/third_party/expat/README.google b/third_party/libjingle/source/talk/third_party/expat/README.google deleted file mode 100644 index 21ef9ec..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/README.google +++ /dev/null @@ -1,14 +0,0 @@ -URL: http://sourceforge.net/projects/expat/ -License: MIT -License File: COPYING.txt - -Description: -This is Expat XML parser - very lightweight C library for -parsing XML, typically linked as a static lib. - -The typical usage of the library is to compile it in or compile it -into a static lib and link in. - -Please refer to the specific version's README.google for more -information on how to build/use etc. - diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/BUILD b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/BUILD deleted file mode 100644 index 1293685..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/BUILD +++ /dev/null @@ -1,9 +0,0 @@ -# -*- mode: python; -*- -# -# Copyright 2007 Google Inc. -# All Rights Reserved. -# -# Description: -# Expat - a small open-source XML parser. - -licenses(['notice']) # MIT diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/COPYING.txt b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/COPYING.txt deleted file mode 100644 index dcb4506..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/COPYING.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - and Clark Cooper -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Changes.txt b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Changes.txt deleted file mode 100644 index 1e885ab..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Changes.txt +++ /dev/null @@ -1,169 +0,0 @@ -Release 2.0.1 Tue June 5 2007 - - Fixed bugs #1515266, 1515600: The character data handler's calling - of XML_StopParser() was not handled properly; if the parser was - stopped and the handler set to NULL, the parser would segfault. - - Fixed bug #1690883: Expat failed on EBCDIC systems as it assumed - some character constants to be ASCII encoded. - - Minor cleanups of the test harness. - - Fixed xmlwf bug #1513566: "out of memory" error on file size zero. - - Fixed outline.c bug #1543233: missing a final XML_ParserFree() call. - - Fixes and improvements for Windows platform: - bugs #1409451, #1476160, 1548182, 1602769, 1717322. - - Build fixes for various platforms: - HP-UX, Tru64, Solaris 9: patch #1437840, bug #1196180. - All Unix: #1554618 (refreshed config.sub/config.guess). - #1490371, #1613457: support both, DESTDIR and INSTALL_ROOT, - without relying on GNU-Make specific features. - #1647805: Patched configure.in to work better with Intel compiler. - - Fixes to Makefile.in to have make check work correctly: - bugs #1408143, #1535603, #1536684. - - Added Open Watcom support: patch #1523242. - -Release 2.0.0 Wed Jan 11 2006 - - We no longer use the "check" library for C unit testing; we - always use the (partial) internal implementation of the API. - - Report XML_NS setting via XML_GetFeatureList(). - - Fixed headers for use from C++. - - XML_GetCurrentLineNumber() and XML_GetCurrentColumnNumber() - now return unsigned integers. - - Added XML_LARGE_SIZE switch to enable 64-bit integers for - byte indexes and line/column numbers. - - Updated to use libtool 1.5.22 (the most recent). - - Added support for AmigaOS. - - Some mostly minor bug fixes. SF issues include: 1006708, - 1021776, 1023646, 1114960, 1156398, 1221160, 1271642. - -Release 1.95.8 Fri Jul 23 2004 - - Major new feature: suspend/resume. Handlers can now request - that a parse be suspended for later resumption or aborted - altogether. See "Temporarily Stopping Parsing" in the - documentation for more details. - - Some mostly minor bug fixes, but compilation should no - longer generate warnings on most platforms. SF issues - include: 827319, 840173, 846309, 888329, 896188, 923913, - 928113, 961698, 985192. - -Release 1.95.7 Mon Oct 20 2003 - - Fixed enum XML_Status issue (reported on SourceForge many - times), so compilers that are properly picky will be happy. - - Introduced an XMLCALL macro to control the calling - convention used by the Expat API; this macro should be used - to annotate prototypes and definitions of callback - implementations in code compiled with a calling convention - other than the default convention for the host platform. - - Improved ability to build without the configure-generated - expat_config.h header. This is useful for applications - which embed Expat rather than linking in the library. - - Fixed a variety of bugs: see SF issues 458907, 609603, - 676844, 679754, 692878, 692964, 695401, 699323, 699487, - 820946. - - Improved hash table lookups. - - Added more regression tests and improved documentation. - -Release 1.95.6 Tue Jan 28 2003 - - Added XML_FreeContentModel(). - - Added XML_MemMalloc(), XML_MemRealloc(), XML_MemFree(). - - Fixed a variety of bugs: see SF issues 615606, 616863, - 618199, 653180, 673791. - - Enhanced the regression test suite. - - Man page improvements: includes SF issue 632146. - -Release 1.95.5 Fri Sep 6 2002 - - Added XML_UseForeignDTD() for improved SAX2 support. - - Added XML_GetFeatureList(). - - Defined XML_Bool type and the values XML_TRUE and XML_FALSE. - - Use an incomplete struct instead of a void* for the parser - (may not retain). - - Fixed UTF-8 decoding bug that caused legal UTF-8 to be rejected. - - Finally fixed bug where default handler would report DTD - events that were already handled by another handler. - Initial patch contributed by Darryl Miles. - - Removed unnecessary DllMain() function that caused static - linking into a DLL to be difficult. - - Added VC++ projects for building static libraries. - - Reduced line-length for all source code and headers to be - no longer than 80 characters, to help with AS/400 support. - - Reduced memory copying during parsing (SF patch #600964). - - Fixed a variety of bugs: see SF issues 580793, 434664, - 483514, 580503, 581069, 584041, 584183, 584832, 585537, - 596555, 596678, 598352, 598944, 599715, 600479, 600971. - -Release 1.95.4 Fri Jul 12 2002 - - Added support for VMS, contributed by Craig Berry. See - vms/README.vms for more information. - - Added Mac OS (classic) support, with a makefile for MPW, - contributed by Thomas Wegner and Daryle Walker. - - Added Borland C++ Builder 5 / BCC 5.5 support, contributed - by Patrick McConnell (SF patch #538032). - - Fixed a variety of bugs: see SF issues 441449, 563184, - 564342, 566334, 566901, 569461, 570263, 575168, 579196. - - Made skippedEntityHandler conform to SAX2 (see source comment) - - Re-implemented WFC: Entity Declared from XML 1.0 spec and - added a new error "entity declared in parameter entity": - see SF bug report 569461 and SF patch 578161 - - Re-implemented section 5.1 from XML 1.0 spec: - see SF bug report 570263 and SF patch 578161 - -Release 1.95.3 Mon Jun 3 2002 - - Added a project to the MSVC workspace to create a wchar_t - version of the library; the DLLs are named libexpatw.dll. - - Changed the name of the Windows DLLs from expat.dll to - libexpat.dll; this fixes SF bug #432456. - - Added the XML_ParserReset() API function. - - Fixed XML_SetReturnNSTriplet() to work for element names. - - Made the XML_UNICODE builds usable (thanks, Karl!). - - Allow xmlwf to read from standard input. - - Install a man page for xmlwf on Unix systems. - - Fixed many bugs; see SF bug reports 231864, 461380, 464837, - 466885, 469226, 477667, 484419, 487840, 494749, 496505, - 547350. Other bugs which we can't test as easily may also - have been fixed, especially in the area of build support. - -Release 1.95.2 Fri Jul 27 2001 - - More changes to make MSVC happy with the build; add a single - workspace to support both the library and xmlwf application. - - Added a Windows installer for Windows users; includes - xmlwf.exe. - - Added compile-time constants that can be used to determine the - Expat version - - Removed a lot of GNU-specific dependencies to aide portability - among the various Unix flavors. - - Fix the UTF-8 BOM bug. - - Cleaned up warning messages for several compilers. - - Added the -Wall, -Wstrict-prototypes options for GCC. - -Release 1.95.1 Sun Oct 22 15:11:36 EDT 2000 - - Changes to get expat to build under Microsoft compiler - - Removed all aborts and instead return an UNEXPECTED_STATE error. - - Fixed a bug where a stray '%' in an entity value would cause an - abort. - - Defined XML_SetEndNamespaceDeclHandler. Thanks to Darryl Miles for - finding this oversight. - - Changed default patterns in lib/Makefile.in to fit non-GNU makes - Thanks to robin@unrated.net for reporting and providing an - account to test on. - - The reference had the wrong label for XML_SetStartNamespaceDecl. - Reported by an anonymous user. - -Release 1.95.0 Fri Sep 29 2000 - - XML_ParserCreate_MM - Allows you to set a memory management suite to replace the - standard malloc,realloc, and free. - - XML_SetReturnNSTriplet - If you turn this feature on when namespace processing is in - effect, then qualified, prefixed element and attribute names - are returned as "uri|name|prefix" where '|' is whatever - separator character is used in namespace processing. - - Merged in features from perl-expat - o XML_SetElementDeclHandler - o XML_SetAttlistDeclHandler - o XML_SetXmlDeclHandler - o XML_SetEntityDeclHandler - o StartDoctypeDeclHandler takes 3 additional parameters: - sysid, pubid, has_internal_subset - o Many paired handler setters (like XML_SetElementHandler) - now have corresponding individual handler setters - o XML_GetInputContext for getting the input context of - the current parse position. - - Added reference material - - Packaged into a distribution that builds a sharable library diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/expat.png b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/expat.png Binary files differdeleted file mode 100644 index 5bc0726..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/expat.png +++ /dev/null diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/reference.html b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/reference.html deleted file mode 100644 index a315870..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/reference.html +++ /dev/null @@ -1,2341 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html> -<head> -<!-- Copyright 1999,2000 Clark Cooper <coopercc@netheaven.com> - All rights reserved. - This is free software. You may distribute or modify according to - the terms of the MIT/X License --> - <title>Expat XML Parser</title> - <meta name="author" content="Clark Cooper, coopercc@netheaven.com" /> - <meta http-equiv="Content-Style-Type" content="text/css" /> - <link href="style.css" rel="stylesheet" type="text/css" /> -</head> -<body> - <table cellspacing="0" cellpadding="0" width="100%"> - <tr> - <td class="corner"><img src="expat.png" alt="(Expat logo)" /></td> - <td class="banner"><h1>The Expat XML Parser</h1></td> - </tr> - <tr> - <td class="releaseno">Release 2.0.1</td> - <td></td> - </tr> - </table> -<div class="content"> - -<p>Expat is a library, written in C, for parsing XML documents. It's -the underlying XML parser for the open source Mozilla project, Perl's -<code>XML::Parser</code>, Python's <code>xml.parsers.expat</code>, and -other open-source XML parsers.</p> - -<p>This library is the creation of James Clark, who's also given us -groff (an nroff look-alike), Jade (an implemention of ISO's DSSSL -stylesheet language for SGML), XP (a Java XML parser package), XT (a -Java XSL engine). James was also the technical lead on the XML -Working Group at W3C that produced the XML specification.</p> - -<p>This is free software, licensed under the <a -href="../COPYING">MIT/X Consortium license</a>. You may download it -from <a href="http://www.libexpat.org/">the Expat home page</a>. -</p> - -<p>The bulk of this document was originally commissioned as an article -by <a href="http://www.xml.com/">XML.com</a>. They graciously allowed -Clark Cooper to retain copyright and to distribute it with Expat. -This version has been substantially extended to include documentation -on features which have been added since the original article was -published, and additional information on using the original -interface.</p> - -<hr /> -<h2>Table of Contents</h2> -<ul> - <li><a href="#overview">Overview</a></li> - <li><a href="#building">Building and Installing</a></li> - <li><a href="#using">Using Expat</a></li> - <li><a href="#reference">Reference</a> - <ul> - <li><a href="#creation">Parser Creation Functions</a> - <ul> - <li><a href="#XML_ParserCreate">XML_ParserCreate</a></li> - <li><a href="#XML_ParserCreateNS">XML_ParserCreateNS</a></li> - <li><a href="#XML_ParserCreate_MM">XML_ParserCreate_MM</a></li> - <li><a href="#XML_ExternalEntityParserCreate">XML_ExternalEntityParserCreate</a></li> - <li><a href="#XML_ParserFree">XML_ParserFree</a></li> - <li><a href="#XML_ParserReset">XML_ParserReset</a></li> - </ul> - </li> - <li><a href="#parsing">Parsing Functions</a> - <ul> - <li><a href="#XML_Parse">XML_Parse</a></li> - <li><a href="#XML_ParseBuffer">XML_ParseBuffer</a></li> - <li><a href="#XML_GetBuffer">XML_GetBuffer</a></li> - <li><a href="#XML_StopParser">XML_StopParser</a></li> - <li><a href="#XML_ResumeParser">XML_ResumeParser</a></li> - <li><a href="#XML_GetParsingStatus">XML_GetParsingStatus</a></li> - </ul> - </li> - <li><a href="#setting">Handler Setting Functions</a> - <ul> - <li><a href="#XML_SetStartElementHandler">XML_SetStartElementHandler</a></li> - <li><a href="#XML_SetEndElementHandler">XML_SetEndElementHandler</a></li> - <li><a href="#XML_SetElementHandler">XML_SetElementHandler</a></li> - <li><a href="#XML_SetCharacterDataHandler">XML_SetCharacterDataHandler</a></li> - <li><a href="#XML_SetProcessingInstructionHandler">XML_SetProcessingInstructionHandler</a></li> - <li><a href="#XML_SetCommentHandler">XML_SetCommentHandler</a></li> - <li><a href="#XML_SetStartCdataSectionHandler">XML_SetStartCdataSectionHandler</a></li> - <li><a href="#XML_SetEndCdataSectionHandler">XML_SetEndCdataSectionHandler</a></li> - <li><a href="#XML_SetCdataSectionHandler">XML_SetCdataSectionHandler</a></li> - <li><a href="#XML_SetDefaultHandler">XML_SetDefaultHandler</a></li> - <li><a href="#XML_SetDefaultHandlerExpand">XML_SetDefaultHandlerExpand</a></li> - <li><a href="#XML_SetExternalEntityRefHandler">XML_SetExternalEntityRefHandler</a></li> - <li><a href="#XML_SetExternalEntityRefHandlerArg">XML_SetExternalEntityRefHandlerArg</a></li> - <li><a href="#XML_SetSkippedEntityHandler">XML_SetSkippedEntityHandler</a></li> - <li><a href="#XML_SetUnknownEncodingHandler">XML_SetUnknownEncodingHandler</a></li> - <li><a href="#XML_SetStartNamespaceDeclHandler">XML_SetStartNamespaceDeclHandler</a></li> - <li><a href="#XML_SetEndNamespaceDeclHandler">XML_SetEndNamespaceDeclHandler</a></li> - <li><a href="#XML_SetNamespaceDeclHandler">XML_SetNamespaceDeclHandler</a></li> - <li><a href="#XML_SetXmlDeclHandler">XML_SetXmlDeclHandler</a></li> - <li><a href="#XML_SetStartDoctypeDeclHandler">XML_SetStartDoctypeDeclHandler</a></li> - <li><a href="#XML_SetEndDoctypeDeclHandler">XML_SetEndDoctypeDeclHandler</a></li> - <li><a href="#XML_SetDoctypeDeclHandler">XML_SetDoctypeDeclHandler</a></li> - <li><a href="#XML_SetElementDeclHandler">XML_SetElementDeclHandler</a></li> - <li><a href="#XML_SetAttlistDeclHandler">XML_SetAttlistDeclHandler</a></li> - <li><a href="#XML_SetEntityDeclHandler">XML_SetEntityDeclHandler</a></li> - <li><a href="#XML_SetUnparsedEntityDeclHandler">XML_SetUnparsedEntityDeclHandler</a></li> - <li><a href="#XML_SetNotationDeclHandler">XML_SetNotationDeclHandler</a></li> - <li><a href="#XML_SetNotStandaloneHandler">XML_SetNotStandaloneHandler</a></li> - </ul> - </li> - <li><a href="#position">Parse Position and Error Reporting Functions</a> - <ul> - <li><a href="#XML_GetErrorCode">XML_GetErrorCode</a></li> - <li><a href="#XML_ErrorString">XML_ErrorString</a></li> - <li><a href="#XML_GetCurrentByteIndex">XML_GetCurrentByteIndex</a></li> - <li><a href="#XML_GetCurrentLineNumber">XML_GetCurrentLineNumber</a></li> - <li><a href="#XML_GetCurrentColumnNumber">XML_GetCurrentColumnNumber</a></li> - <li><a href="#XML_GetCurrentByteCount">XML_GetCurrentByteCount</a></li> - <li><a href="#XML_GetInputContext">XML_GetInputContext</a></li> - </ul> - </li> - <li><a href="#miscellaneous">Miscellaneous Functions</a> - <ul> - <li><a href="#XML_SetUserData">XML_SetUserData</a></li> - <li><a href="#XML_GetUserData">XML_GetUserData</a></li> - <li><a href="#XML_UseParserAsHandlerArg">XML_UseParserAsHandlerArg</a></li> - <li><a href="#XML_SetBase">XML_SetBase</a></li> - <li><a href="#XML_GetBase">XML_GetBase</a></li> - <li><a href="#XML_GetSpecifiedAttributeCount">XML_GetSpecifiedAttributeCount</a></li> - <li><a href="#XML_GetIdAttributeIndex">XML_GetIdAttributeIndex</a></li> - <li><a href="#XML_SetEncoding">XML_SetEncoding</a></li> - <li><a href="#XML_SetParamEntityParsing">XML_SetParamEntityParsing</a></li> - <li><a href="#XML_UseForeignDTD">XML_UseForeignDTD</a></li> - <li><a href="#XML_SetReturnNSTriplet">XML_SetReturnNSTriplet</a></li> - <li><a href="#XML_DefaultCurrent">XML_DefaultCurrent</a></li> - <li><a href="#XML_ExpatVersion">XML_ExpatVersion</a></li> - <li><a href="#XML_ExpatVersionInfo">XML_ExpatVersionInfo</a></li> - <li><a href="#XML_GetFeatureList">XML_GetFeatureList</a></li> - <li><a href="#XML_FreeContentModel">XML_FreeContentModel</a></li> - <li><a href="#XML_MemMalloc">XML_MemMalloc</a></li> - <li><a href="#XML_MemRealloc">XML_MemRealloc</a></li> - <li><a href="#XML_MemFree">XML_MemFree</a></li> - </ul> - </li> - </ul> - </li> -</ul> - -<hr /> -<h2><a name="overview">Overview</a></h2> - -<p>Expat is a stream-oriented parser. You register callback (or -handler) functions with the parser and then start feeding it the -document. As the parser recognizes parts of the document, it will -call the appropriate handler for that part (if you've registered one.) -The document is fed to the parser in pieces, so you can start parsing -before you have all the document. This also allows you to parse really -huge documents that won't fit into memory.</p> - -<p>Expat can be intimidating due to the many kinds of handlers and -options you can set. But you only need to learn four functions in -order to do 90% of what you'll want to do with it:</p> - -<dl> - -<dt><code><a href= "#XML_ParserCreate" - >XML_ParserCreate</a></code></dt> - <dd>Create a new parser object.</dd> - -<dt><code><a href= "#XML_SetElementHandler" - >XML_SetElementHandler</a></code></dt> - <dd>Set handlers for start and end tags.</dd> - -<dt><code><a href= "#XML_SetCharacterDataHandler" - >XML_SetCharacterDataHandler</a></code></dt> - <dd>Set handler for text.</dd> - -<dt><code><a href= "#XML_Parse" - >XML_Parse</a></code></dt> - <dd>Pass a buffer full of document to the parser</dd> -</dl> - -<p>These functions and others are described in the <a -href="#reference">reference</a> part of this document. The reference -section also describes in detail the parameters passed to the -different types of handlers.</p> - -<p>Let's look at a very simple example program that only uses 3 of the -above functions (it doesn't need to set a character handler.) The -program <a href="../examples/outline.c">outline.c</a> prints an -element outline, indenting child elements to distinguish them from the -parent element that contains them. The start handler does all the -work. It prints two indenting spaces for every level of ancestor -elements, then it prints the element and attribute -information. Finally it increments the global <code>Depth</code> -variable.</p> - -<pre class="eg"> -int Depth; - -void XMLCALL -start(void *data, const char *el, const char **attr) { - int i; - - for (i = 0; i < Depth; i++) - printf(" "); - - printf("%s", el); - - for (i = 0; attr[i]; i += 2) { - printf(" %s='%s'", attr[i], attr[i + 1]); - } - - printf("\n"); - Depth++; -} /* End of start handler */ -</pre> - -<p>The end tag simply does the bookkeeping work of decrementing -<code>Depth</code>.</p> -<pre class="eg"> -void XMLCALL -end(void *data, const char *el) { - Depth--; -} /* End of end handler */ -</pre> - -<p>Note the <code>XMLCALL</code> annotation used for the callbacks. -This is used to ensure that the Expat and the callbacks are using the -same calling convention in case the compiler options used for Expat -itself and the client code are different. Expat tries not to care -what the default calling convention is, though it may require that it -be compiled with a default convention of "cdecl" on some platforms. -For code which uses Expat, however, the calling convention is -specified by the <code>XMLCALL</code> annotation on most platforms; -callbacks should be defined using this annotation.</p> - -<p>The <code>XMLCALL</code> annotation was added in Expat 1.95.7, but -existing working Expat applications don't need to add it (since they -are already using the "cdecl" calling convention, or they wouldn't be -working). The annotation is only needed if the default calling -convention may be something other than "cdecl". To use the annotation -safely with older versions of Expat, you can conditionally define it -<em>after</em> including Expat's header file:</p> - -<pre class="eg"> -#include <expat.h> - -#ifndef XMLCALL -#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) -#define XMLCALL __cdecl -#elif defined(__GNUC__) -#define XMLCALL __attribute__((cdecl)) -#else -#define XMLCALL -#endif -#endif -</pre> - -<p>After creating the parser, the main program just has the job of -shoveling the document to the parser so that it can do its work.</p> - -<hr /> -<h2><a name="building">Building and Installing Expat</a></h2> - -<p>The Expat distribution comes as a compressed (with GNU gzip) tar -file. You may download the latest version from <a href= -"http://sourceforge.net/projects/expat/" >Source Forge</a>. After -unpacking this, cd into the directory. Then follow either the Win32 -directions or Unix directions below.</p> - -<h3>Building under Win32</h3> - -<p>If you're using the GNU compiler under cygwin, follow the Unix -directions in the next section. Otherwise if you have Microsoft's -Developer Studio installed, then from Windows Explorer double-click on -"expat.dsp" in the lib directory and build and install in the usual -manner.</p> - -<p>Alternatively, you may download the Win32 binary package that -contains the "expat.h" include file and a pre-built DLL.</p> - -<h3>Building under Unix (or GNU)</h3> - -<p>First you'll need to run the configure shell script in order to -configure the Makefiles and headers for your system.</p> - -<p>If you're happy with all the defaults that configure picks for you, -and you have permission on your system to install into /usr/local, you -can install Expat with this sequence of commands:</p> - -<pre class="eg"> -./configure -make -make install -</pre> - -<p>There are some options that you can provide to this script, but the -only one we'll mention here is the <code>--prefix</code> option. You -can find out all the options available by running configure with just -the <code>--help</code> option.</p> - -<p>By default, the configure script sets things up so that the library -gets installed in <code>/usr/local/lib</code> and the associated -header file in <code>/usr/local/include</code>. But if you were to -give the option, <code>--prefix=/home/me/mystuff</code>, then the -library and header would get installed in -<code>/home/me/mystuff/lib</code> and -<code>/home/me/mystuff/include</code> respectively.</p> - -<h3>Configuring Expat Using the Pre-Processor</h3> - -<p>Expat's feature set can be configured using a small number of -pre-processor definitions. The definition of this symbols does not -affect the set of entry points for Expat, only the behavior of the API -and the definition of character types in the case of -<code>XML_UNICODE_WCHAR_T</code>. The symbols are:</p> - -<dl class="cpp-symbols"> -<dt>XML_DTD</dt> -<dd>Include support for using and reporting DTD-based content. If -this is defined, default attribute values from an external DTD subset -are reported and attribute value normalization occurs based on the -type of attributes defined in the external subset. Without -this, Expat has a smaller memory footprint and can be faster, but will -not load external entities or process conditional sections. This does -not affect the set of functions available in the API.</dd> - -<dt>XML_NS</dt> -<dd>When defined, support for the <cite><a href= -"http://www.w3.org/TR/REC-xml-names/" >Namespaces in XML</a></cite> -specification is included.</dd> - -<dt>XML_UNICODE</dt> -<dd>When defined, character data reported to the application is -encoded in UTF-16 using wide characters of the type -<code>XML_Char</code>. This is implied if -<code>XML_UNICODE_WCHAR_T</code> is defined.</dd> - -<dt>XML_UNICODE_WCHAR_T</dt> -<dd>If defined, causes the <code>XML_Char</code> character type to be -defined using the <code>wchar_t</code> type; otherwise, <code>unsigned -short</code> is used. Defining this implies -<code>XML_UNICODE</code>.</dd> - -<dt>XML_LARGE_SIZE</dt> -<dd>If defined, causes the <code>XML_Size</code> and <code>XML_Index</code> -integer types to be at least 64 bits in size. This is intended to support -processing of very large input streams, where the return values of -<code><a href="#XML_GetCurrentByteIndex" >XML_GetCurrentByteIndex</a></code>, -<code><a href="#XML_GetCurrentLineNumber" >XML_GetCurrentLineNumber</a></code> and -<code><a href="#XML_GetCurrentColumnNumber" >XML_GetCurrentColumnNumber</a></code> -could overflow. It may not be supported by all compilers, and is turned -off by default.</dd> - -<dt>XML_CONTEXT_BYTES</dt> -<dd>The number of input bytes of markup context which the parser will -ensure are available for reporting via <code><a href= -"#XML_GetInputContext" >XML_GetInputContext</a></code>. This is -normally set to 1024, and must be set to a positive interger. If this -is not defined, the input context will not be available and <code><a -href= "#XML_GetInputContext" >XML_GetInputContext</a></code> will -always report NULL. Without this, Expat has a smaller memory -footprint and can be faster.</dd> - -<dt>XML_STATIC</dt> -<dd>On Windows, this should be set if Expat is going to be linked -statically with the code that calls it; this is required to get all -the right MSVC magic annotations correct. This is ignored on other -platforms.</dd> -</dl> - -<hr /> -<h2><a name="using">Using Expat</a></h2> - -<h3>Compiling and Linking Against Expat</h3> - -<p>Unless you installed Expat in a location not expected by your -compiler and linker, all you have to do to use Expat in your programs -is to include the Expat header (<code>#include <expat.h></code>) -in your files that make calls to it and to tell the linker that it -needs to link against the Expat library. On Unix systems, this would -usually be done with the <code>-lexpat</code> argument. Otherwise, -you'll need to tell the compiler where to look for the Expat header -and the linker where to find the Expat library. You may also need to -take steps to tell the operating system where to find this library at -run time.</p> - -<p>On a Unix-based system, here's what a Makefile might look like when -Expat is installed in a standard location:</p> - -<pre class="eg"> -CC=cc -LDFLAGS= -LIBS= -lexpat -xmlapp: xmlapp.o - $(CC) $(LDFLAGS) -o xmlapp xmlapp.o $(LIBS) -</pre> - -<p>If you installed Expat in, say, <code>/home/me/mystuff</code>, then -the Makefile would look like this:</p> - -<pre class="eg"> -CC=cc -CFLAGS= -I/home/me/mystuff/include -LDFLAGS= -LIBS= -L/home/me/mystuff/lib -lexpat -xmlapp: xmlapp.o - $(CC) $(LDFLAGS) -o xmlapp xmlapp.o $(LIBS) -</pre> - -<p>You'd also have to set the environment variable -<code>LD_LIBRARY_PATH</code> to <code>/home/me/mystuff/lib</code> (or -to <code>${LD_LIBRARY_PATH}:/home/me/mystuff/lib</code> if -LD_LIBRARY_PATH already has some directories in it) in order to run -your application.</p> - -<h3>Expat Basics</h3> - -<p>As we saw in the example in the overview, the first step in parsing -an XML document with Expat is to create a parser object. There are <a -href="#creation">three functions</a> in the Expat API for creating a -parser object. However, only two of these (<code><a href= -"#XML_ParserCreate" >XML_ParserCreate</a></code> and <code><a href= -"#XML_ParserCreateNS" >XML_ParserCreateNS</a></code>) can be used for -constructing a parser for a top-level document. The object returned -by these functions is an opaque pointer (i.e. "expat.h" declares it as -void *) to data with further internal structure. In order to free the -memory associated with this object you must call <code><a href= -"#XML_ParserFree" >XML_ParserFree</a></code>. Note that if you have -provided any <a href="#userdata">user data</a> that gets stored in the -parser, then your application is responsible for freeing it prior to -calling <code>XML_ParserFree</code>.</p> - -<p>The objects returned by the parser creation functions are good for -parsing only one XML document or external parsed entity. If your -application needs to parse many XML documents, then it needs to create -a parser object for each one. The best way to deal with this is to -create a higher level object that contains all the default -initialization you want for your parser objects.</p> - -<p>Walking through a document hierarchy with a stream oriented parser -will require a good stack mechanism in order to keep track of current -context. For instance, to answer the simple question, "What element -does this text belong to?" requires a stack, since the parser may have -descended into other elements that are children of the current one and -has encountered this text on the way out.</p> - -<p>The things you're likely to want to keep on a stack are the -currently opened element and it's attributes. You push this -information onto the stack in the start handler and you pop it off in -the end handler.</p> - -<p>For some tasks, it is sufficient to just keep information on what -the depth of the stack is (or would be if you had one.) The outline -program shown above presents one example. Another such task would be -skipping over a complete element. When you see the start tag for the -element you want to skip, you set a skip flag and record the depth at -which the element started. When the end tag handler encounters the -same depth, the skipped element has ended and the flag may be -cleared. If you follow the convention that the root element starts at -1, then you can use the same variable for skip flag and skip -depth.</p> - -<pre class="eg"> -void -init_info(Parseinfo *info) { - info->skip = 0; - info->depth = 1; - /* Other initializations here */ -} /* End of init_info */ - -void XMLCALL -rawstart(void *data, const char *el, const char **attr) { - Parseinfo *inf = (Parseinfo *) data; - - if (! inf->skip) { - if (should_skip(inf, el, attr)) { - inf->skip = inf->depth; - } - else - start(inf, el, attr); /* This does rest of start handling */ - } - - inf->depth++; -} /* End of rawstart */ - -void XMLCALL -rawend(void *data, const char *el) { - Parseinfo *inf = (Parseinfo *) data; - - inf->depth--; - - if (! inf->skip) - end(inf, el); /* This does rest of end handling */ - - if (inf->skip == inf->depth) - inf->skip = 0; -} /* End rawend */ -</pre> - -<p>Notice in the above example the difference in how depth is -manipulated in the start and end handlers. The end tag handler should -be the mirror image of the start tag handler. This is necessary to -properly model containment. Since, in the start tag handler, we -incremented depth <em>after</em> the main body of start tag code, then -in the end handler, we need to manipulate it <em>before</em> the main -body. If we'd decided to increment it first thing in the start -handler, then we'd have had to decrement it last thing in the end -handler.</p> - -<h3 id="userdata">Communicating between handlers</h3> - -<p>In order to be able to pass information between different handlers -without using globals, you'll need to define a data structure to hold -the shared variables. You can then tell Expat (with the <code><a href= -"#XML_SetUserData" >XML_SetUserData</a></code> function) to pass a -pointer to this structure to the handlers. This is the first -argument received by most handlers. In the <a href="#reference" ->reference section</a>, an argument to a callback function is named -<code>userData</code> and have type <code>void *</code> if the user -data is passed; it will have the type <code>XML_Parser</code> if the -parser itself is passed. When the parser is passed, the user data may -be retrieved using <code><a href="#XML_GetUserData" ->XML_GetUserData</a></code>.</p> - -<p>One common case where multiple calls to a single handler may need -to communicate using an application data structure is the case when -content passed to the character data handler (set by <code><a href= -"#XML_SetCharacterDataHandler" ->XML_SetCharacterDataHandler</a></code>) needs to be accumulated. A -common first-time mistake with any of the event-oriented interfaces to -an XML parser is to expect all the text contained in an element to be -reported by a single call to the character data handler. Expat, like -many other XML parsers, reports such data as a sequence of calls; -there's no way to know when the end of the sequence is reached until a -different callback is made. A buffer referenced by the user data -structure proves both an effective and convenient place to accumulate -character data.</p> - -<!-- XXX example needed here --> - - -<h3>XML Version</h3> - -<p>Expat is an XML 1.0 parser, and as such never complains based on -the value of the <code>version</code> pseudo-attribute in the XML -declaration, if present.</p> - -<p>If an application needs to check the version number (to support -alternate processing), it should use the <code><a href= -"#XML_SetXmlDeclHandler" >XML_SetXmlDeclHandler</a></code> function to -set a handler that uses the information in the XML declaration to -determine what to do. This example shows how to check that only a -version number of <code>"1.0"</code> is accepted:</p> - -<pre class="eg"> -static int wrong_version; -static XML_Parser parser; - -static void XMLCALL -xmldecl_handler(void *userData, - const XML_Char *version, - const XML_Char *encoding, - int standalone) -{ - static const XML_Char Version_1_0[] = {'1', '.', '0', 0}; - - int i; - - for (i = 0; i < (sizeof(Version_1_0) / sizeof(Version_1_0[0])); ++i) { - if (version[i] != Version_1_0[i]) { - wrong_version = 1; - /* also clear all other handlers: */ - XML_SetCharacterDataHandler(parser, NULL); - ... - return; - } - } - ... -} -</pre> - -<h3>Namespace Processing</h3> - -<p>When the parser is created using the <code><a href= -"#XML_ParserCreateNS" >XML_ParserCreateNS</a></code>, function, Expat -performs namespace processing. Under namespace processing, Expat -consumes <code>xmlns</code> and <code>xmlns:...</code> attributes, -which declare namespaces for the scope of the element in which they -occur. This means that your start handler will not see these -attributes. Your application can still be informed of these -declarations by setting namespace declaration handlers with <a href= -"#XML_SetNamespaceDeclHandler" -><code>XML_SetNamespaceDeclHandler</code></a>.</p> - -<p>Element type and attribute names that belong to a given namespace -are passed to the appropriate handler in expanded form. By default -this expanded form is a concatenation of the namespace URI, the -separator character (which is the 2nd argument to <code><a href= -"#XML_ParserCreateNS" >XML_ParserCreateNS</a></code>), and the local -name (i.e. the part after the colon). Names with undeclared prefixes -are not well-formed when namespace processing is enabled, and will -trigger an error. Unprefixed attribute names are never expanded, -and unprefixed element names are only expanded when they are in the -scope of a default namespace.</p> - -<p>However if <code><a href= "#XML_SetReturnNSTriplet" ->XML_SetReturnNSTriplet</a></code> has been called with a non-zero -<code>do_nst</code> parameter, then the expanded form for names with -an explicit prefix is a concatenation of: URI, separator, local name, -separator, prefix.</p> - -<p>You can set handlers for the start of a namespace declaration and -for the end of a scope of a declaration with the <code><a href= -"#XML_SetNamespaceDeclHandler" >XML_SetNamespaceDeclHandler</a></code> -function. The StartNamespaceDeclHandler is called prior to the start -tag handler and the EndNamespaceDeclHandler is called after the -corresponding end tag that ends the namespace's scope. The namespace -start handler gets passed the prefix and URI for the namespace. For a -default namespace declaration (xmlns='...'), the prefix will be null. -The URI will be null for the case where the default namespace is being -unset. The namespace end handler just gets the prefix for the closing -scope.</p> - -<p>These handlers are called for each declaration. So if, for -instance, a start tag had three namespace declarations, then the -StartNamespaceDeclHandler would be called three times before the start -tag handler is called, once for each declaration.</p> - -<h3>Character Encodings</h3> - -<p>While XML is based on Unicode, and every XML processor is required -to recognized UTF-8 and UTF-16 (1 and 2 byte encodings of Unicode), -other encodings may be declared in XML documents or entities. For the -main document, an XML declaration may contain an encoding -declaration:</p> -<pre> -<?xml version="1.0" encoding="ISO-8859-2"?> -</pre> - -<p>External parsed entities may begin with a text declaration, which -looks like an XML declaration with just an encoding declaration:</p> -<pre> -<?xml encoding="Big5"?> -</pre> - -<p>With Expat, you may also specify an encoding at the time of -creating a parser. This is useful when the encoding information may -come from a source outside the document itself (like a higher level -protocol.)</p> - -<p><a name="builtin_encodings"></a>There are four built-in encodings -in Expat:</p> -<ul> -<li>UTF-8</li> -<li>UTF-16</li> -<li>ISO-8859-1</li> -<li>US-ASCII</li> -</ul> - -<p>Anything else discovered in an encoding declaration or in the -protocol encoding specified in the parser constructor, triggers a call -to the <code>UnknownEncodingHandler</code>. This handler gets passed -the encoding name and a pointer to an <code>XML_Encoding</code> data -structure. Your handler must fill in this structure and return -<code>XML_STATUS_OK</code> if it knows how to deal with the -encoding. Otherwise the handler should return -<code>XML_STATUS_ERROR</code>. The handler also gets passed a pointer -to an optional application data structure that you may indicate when -you set the handler.</p> - -<p>Expat places restrictions on character encodings that it can -support by filling in the <code>XML_Encoding</code> structure. -include file:</p> -<ol> -<li>Every ASCII character that can appear in a well-formed XML document -must be represented by a single byte, and that byte must correspond to -it's ASCII encoding (except for the characters $@\^'{}~)</li> -<li>Characters must be encoded in 4 bytes or less.</li> -<li>All characters encoded must have Unicode scalar values less than or -equal to 65535 (0xFFFF)<em>This does not apply to the built-in support -for UTF-16 and UTF-8</em></li> -<li>No character may be encoded by more that one distinct sequence of -bytes</li> -</ol> - -<p><code>XML_Encoding</code> contains an array of integers that -correspond to the 1st byte of an encoding sequence. If the value in -the array for a byte is zero or positive, then the byte is a single -byte encoding that encodes the Unicode scalar value contained in the -array. A -1 in this array indicates a malformed byte. If the value is --2, -3, or -4, then the byte is the beginning of a 2, 3, or 4 byte -sequence respectively. Multi-byte sequences are sent to the convert -function pointed at in the <code>XML_Encoding</code> structure. This -function should return the Unicode scalar value for the sequence or -1 -if the sequence is malformed.</p> - -<p>One pitfall that novice Expat users are likely to fall into is that -although Expat may accept input in various encodings, the strings that -it passes to the handlers are always encoded in UTF-8 or UTF-16 -(depending on how Expat was compiled). Your application is responsible -for any translation of these strings into other encodings.</p> - -<h3>Handling External Entity References</h3> - -<p>Expat does not read or parse external entities directly. Note that -any external DTD is a special case of an external entity. If you've -set no <code>ExternalEntityRefHandler</code>, then external entity -references are silently ignored. Otherwise, it calls your handler with -the information needed to read and parse the external entity.</p> - -<p>Your handler isn't actually responsible for parsing the entity, but -it is responsible for creating a subsidiary parser with <code><a href= -"#XML_ExternalEntityParserCreate" ->XML_ExternalEntityParserCreate</a></code> that will do the job. This -returns an instance of <code>XML_Parser</code> that has handlers and -other data structures initialized from the parent parser. You may then -use <code><a href= "#XML_Parse" >XML_Parse</a></code> or <code><a -href= "#XML_ParseBuffer">XML_ParseBuffer</a></code> calls against this -parser. Since external entities my refer to other external entities, -your handler should be prepared to be called recursively.</p> - -<h3>Parsing DTDs</h3> - -<p>In order to parse parameter entities, before starting the parse, -you must call <code><a href= "#XML_SetParamEntityParsing" ->XML_SetParamEntityParsing</a></code> with one of the following -arguments:</p> -<dl> -<dt><code>XML_PARAM_ENTITY_PARSING_NEVER</code></dt> -<dd>Don't parse parameter entities or the external subset</dd> -<dt><code>XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE</code></dt> -<dd>Parse parameter entites and the external subset unless -<code>standalone</code> was set to "yes" in the XML declaration.</dd> -<dt><code>XML_PARAM_ENTITY_PARSING_ALWAYS</code></dt> -<dd>Always parse parameter entities and the external subset</dd> -</dl> - -<p>In order to read an external DTD, you also have to set an external -entity reference handler as described above.</p> - -<h3 id="stop-resume">Temporarily Stopping Parsing</h3> - -<p>Expat 1.95.8 introduces a new feature: its now possible to stop -parsing temporarily from within a handler function, even if more data -has already been passed into the parser. Applications for this -include</p> - -<ul> - <li>Supporting the <a href= "http://www.w3.org/TR/xinclude/" - >XInclude</a> specification.</li> - - <li>Delaying further processing until additional information is - available from some other source.</li> - - <li>Adjusting processor load as task priorities shift within an - application.</li> - - <li>Stopping parsing completely (simply free or reset the parser - instead of resuming in the outer parsing loop). This can be useful - if a application-domain error is found in the XML being parsed or if - the result of the parse is determined not to be useful after - all.</li> -</ul> - -<p>To take advantage of this feature, the main parsing loop of an -application needs to support this specifically. It cannot be -supported with a parsing loop compatible with Expat 1.95.7 or -earlier (though existing loops will continue to work without -supporting the stop/resume feature).</p> - -<p>An application that uses this feature for a single parser will have -the rough structure (in pseudo-code):</p> - -<pre class="pseudocode"> -fd = open_input() -p = create_parser() - -if parse_xml(p, fd) { - /* suspended */ - - int suspended = 1; - - while (suspended) { - do_something_else() - if ready_to_resume() { - suspended = continue_parsing(p, fd); - } - } -} -</pre> - -<p>An application that may resume any of several parsers based on -input (either from the XML being parsed or some other source) will -certainly have more interesting control structures.</p> - -<p>This C function could be used for the <code>parse_xml</code> -function mentioned in the pseudo-code above:</p> - -<pre class="eg"> -#define BUFF_SIZE 10240 - -/* Parse a document from the open file descriptor 'fd' until the parse - is complete (the document has been completely parsed, or there's - been an error), or the parse is stopped. Return non-zero when - the parse is merely suspended. -*/ -int -parse_xml(XML_Parser p, int fd) -{ - for (;;) { - int last_chunk; - int bytes_read; - enum XML_Status status; - - void *buff = XML_GetBuffer(p, BUFF_SIZE); - if (buff == NULL) { - /* handle error... */ - return 0; - } - bytes_read = read(fd, buff, BUFF_SIZE); - if (bytes_read < 0) { - /* handle error... */ - return 0; - } - status = XML_ParseBuffer(p, bytes_read, bytes_read == 0); - switch (status) { - case XML_STATUS_ERROR: - /* handle error... */ - return 0; - case XML_STATUS_SUSPENDED: - return 1; - } - if (bytes_read == 0) - return 0; - } -} -</pre> - -<p>The corresponding <code>continue_parsing</code> function is -somewhat simpler, since it only need deal with the return code from -<code><a href= "#XML_ResumeParser">XML_ResumeParser</a></code>; it can -delegate the input handling to the <code>parse_xml</code> -function:</p> - -<pre class="eg"> -/* Continue parsing a document which had been suspended. The 'p' and - 'fd' arguments are the same as passed to parse_xml(). Return - non-zero when the parse is suspended. -*/ -int -continue_parsing(XML_Parser p, int fd) -{ - enum XML_Status status = XML_ResumeParser(p); - switch (status) { - case XML_STATUS_ERROR: - /* handle error... */ - return 0; - case XML_ERROR_NOT_SUSPENDED: - /* handle error... */ - return 0;. - case XML_STATUS_SUSPENDED: - return 1; - } - return parse_xml(p, fd); -} -</pre> - -<p>Now that we've seen what a mess the top-level parsing loop can -become, what have we gained? Very simply, we can now use the <code><a -href= "#XML_StopParser" >XML_StopParser</a></code> function to stop -parsing, without having to go to great lengths to avoid additional -processing that we're expecting to ignore. As a bonus, we get to stop -parsing <em>temporarily</em>, and come back to it when we're -ready.</p> - -<p>To stop parsing from a handler function, use the <code><a href= -"#XML_StopParser" >XML_StopParser</a></code> function. This function -takes two arguments; the parser being stopped and a flag indicating -whether the parse can be resumed in the future.</p> - -<!-- XXX really need more here --> - - -<hr /> -<!-- ================================================================ --> - -<h2><a name="reference">Expat Reference</a></h2> - -<h3><a name="creation">Parser Creation</a></h3> - -<pre class="fcndec" id="XML_ParserCreate"> -XML_Parser XMLCALL -XML_ParserCreate(const XML_Char *encoding); -</pre> -<div class="fcndef"> -Construct a new parser. If encoding is non-null, it specifies a -character encoding to use for the document. This overrides the document -encoding declaration. There are four built-in encodings: -<ul> -<li>US-ASCII</li> -<li>UTF-8</li> -<li>UTF-16</li> -<li>ISO-8859-1</li> -</ul> -Any other value will invoke a call to the UnknownEncodingHandler. -</div> - -<pre class="fcndec" id="XML_ParserCreateNS"> -XML_Parser XMLCALL -XML_ParserCreateNS(const XML_Char *encoding, - XML_Char sep); -</pre> -<div class="fcndef"> -Constructs a new parser that has namespace processing in effect. Namespace -expanded element names and attribute names are returned as a concatenation -of the namespace URI, <em>sep</em>, and the local part of the name. This -means that you should pick a character for <em>sep</em> that can't be -part of a legal URI. There is a special case when <em>sep</em> is the null -character <code>'\0'</code>: the namespace URI and the local part will be -concatenated without any separator - this is intended to support RDF processors. -It is a programming error to use the null separator with -<a href= "#XML_SetReturnNSTriplet">namespace triplets</a>.</div> - -<pre class="fcndec" id="XML_ParserCreate_MM"> -XML_Parser XMLCALL -XML_ParserCreate_MM(const XML_Char *encoding, - const XML_Memory_Handling_Suite *ms, - const XML_Char *sep); -</pre> -<pre class="signature"> -typedef struct { - void *(XMLCALL *malloc_fcn)(size_t size); - void *(XMLCALL *realloc_fcn)(void *ptr, size_t size); - void (XMLCALL *free_fcn)(void *ptr); -} XML_Memory_Handling_Suite; -</pre> -<div class="fcndef"> -<p>Construct a new parser using the suite of memory handling functions -specified in <code>ms</code>. If <code>ms</code> is NULL, then use the -standard set of memory management functions. If <code>sep</code> is -non NULL, then namespace processing is enabled in the created parser -and the character pointed at by sep is used as the separator between -the namespace URI and the local part of the name.</p> -</div> - -<pre class="fcndec" id="XML_ExternalEntityParserCreate"> -XML_Parser XMLCALL -XML_ExternalEntityParserCreate(XML_Parser p, - const XML_Char *context, - const XML_Char *encoding); -</pre> -<div class="fcndef"> -Construct a new <code>XML_Parser</code> object for parsing an external -general entity. Context is the context argument passed in a call to a -ExternalEntityRefHandler. Other state information such as handlers, -user data, namespace processing is inherited from the parser passed as -the 1st argument. So you shouldn't need to call any of the behavior -changing functions on this parser (unless you want it to act -differently than the parent parser). -</div> - -<pre class="fcndec" id="XML_ParserFree"> -void XMLCALL -XML_ParserFree(XML_Parser p); -</pre> -<div class="fcndef"> -Free memory used by the parser. Your application is responsible for -freeing any memory associated with <a href="#userdata">user data</a>. -</div> - -<pre class="fcndec" id="XML_ParserReset"> -XML_Bool XMLCALL -XML_ParserReset(XML_Parser p, - const XML_Char *encoding); -</pre> -<div class="fcndef"> -Clean up the memory structures maintained by the parser so that it may -be used again. After this has been called, <code>parser</code> is -ready to start parsing a new document. All handlers are cleared from -the parser, except for the unknownEncodingHandler. The parser's external -state is re-initialized except for the values of ns and ns_triplets. -This function may not be used on a parser created using <code><a href= -"#XML_ExternalEntityParserCreate" >XML_ExternalEntityParserCreate</a -></code>; it will return <code>XML_FALSE</code> in that case. Returns -<code>XML_TRUE</code> on success. Your application is responsible for -dealing with any memory associated with <a href="#userdata">user data</a>. -</div> - -<h3><a name="parsing">Parsing</a></h3> - -<p>To state the obvious: the three parsing functions <code><a href= -"#XML_Parse" >XML_Parse</a></code>, <code><a href= "#XML_ParseBuffer"> -XML_ParseBuffer</a></code> and <code><a href= "#XML_GetBuffer"> -XML_GetBuffer</a></code> must not be called from within a handler -unless they operate on a separate parser instance, that is, one that -did not call the handler. For example, it is OK to call the parsing -functions from within an <code>XML_ExternalEntityRefHandler</code>, -if they apply to the parser created by -<code><a href= "#XML_ExternalEntityParserCreate" ->XML_ExternalEntityParserCreate</a></code>.</p> - -<p>Note: the <code>len</code> argument passed to these functions -should be considerably less than the maximum value for an integer, -as it could create an integer overflow situation if the added -lengths of a buffer and the unprocessed portion of the previous buffer -exceed the maximum integer value. Input data at the end of a buffer -will remain unprocessed if it is part of an XML token for which the -end is not part of that buffer.</p> - -<pre class="fcndec" id="XML_Parse"> -enum XML_Status XMLCALL -XML_Parse(XML_Parser p, - const char *s, - int len, - int isFinal); -</pre> -<pre class="signature"> -enum XML_Status { - XML_STATUS_ERROR = 0, - XML_STATUS_OK = 1 -}; -</pre> -<div class="fcndef"> -Parse some more of the document. The string <code>s</code> is a buffer -containing part (or perhaps all) of the document. The number of bytes of s -that are part of the document is indicated by <code>len</code>. This means -that <code>s</code> doesn't have to be null terminated. It also means that -if <code>len</code> is larger than the number of bytes in the block of -memory that <code>s</code> points at, then a memory fault is likely. The -<code>isFinal</code> parameter informs the parser that this is the last -piece of the document. Frequently, the last piece is empty (i.e. -<code>len</code> is zero.) -If a parse error occurred, it returns <code>XML_STATUS_ERROR</code>. -Otherwise it returns <code>XML_STATUS_OK</code> value. -</div> - -<pre class="fcndec" id="XML_ParseBuffer"> -enum XML_Status XMLCALL -XML_ParseBuffer(XML_Parser p, - int len, - int isFinal); -</pre> -<div class="fcndef"> -This is just like <code><a href= "#XML_Parse" >XML_Parse</a></code>, -except in this case Expat provides the buffer. By obtaining the -buffer from Expat with the <code><a href= "#XML_GetBuffer" ->XML_GetBuffer</a></code> function, the application can avoid double -copying of the input. -</div> - -<pre class="fcndec" id="XML_GetBuffer"> -void * XMLCALL -XML_GetBuffer(XML_Parser p, - int len); -</pre> -<div class="fcndef"> -Obtain a buffer of size <code>len</code> to read a piece of the document -into. A NULL value is returned if Expat can't allocate enough memory for -this buffer. This has to be called prior to every call to -<code><a href= "#XML_ParseBuffer" >XML_ParseBuffer</a></code>. A -typical use would look like this: - -<pre class="eg"> -for (;;) { - int bytes_read; - void *buff = XML_GetBuffer(p, BUFF_SIZE); - if (buff == NULL) { - /* handle error */ - } - - bytes_read = read(docfd, buff, BUFF_SIZE); - if (bytes_read < 0) { - /* handle error */ - } - - if (! XML_ParseBuffer(p, bytes_read, bytes_read == 0)) { - /* handle parse error */ - } - - if (bytes_read == 0) - break; -} -</pre> -</div> - -<pre class="fcndec" id="XML_StopParser"> -enum XML_Status XMLCALL -XML_StopParser(XML_Parser p, - XML_Bool resumable); -</pre> -<div class="fcndef"> - -<p>Stops parsing, causing <code><a href= "#XML_Parse" ->XML_Parse</a></code> or <code><a href= "#XML_ParseBuffer" ->XML_ParseBuffer</a></code> to return. Must be called from within a -call-back handler, except when aborting (when <code>resumable</code> -is <code>XML_FALSE</code>) an already suspended parser. Some -call-backs may still follow because they would otherwise get -lost, including -<ul> - <li> the end element handler for empty elements when stopped in the - start element handler,</li> - <li> the end namespace declaration handler when stopped in the end - element handler,</li> - <li> the character data handler when stopped in the character data handler - while making multiple call-backs on a contiguous chunk of characters,</li> -</ul> -and possibly others.</p> - -<p>This can be called from most handlers, including DTD related -call-backs, except when parsing an external parameter entity and -<code>resumable</code> is <code>XML_TRUE</code>. Returns -<code>XML_STATUS_OK</code> when successful, -<code>XML_STATUS_ERROR</code> otherwise. The possible error codes -are:</p> -<dl> - <dt><code>XML_ERROR_SUSPENDED</code></dt> - <dd>when suspending an already suspended parser.</dd> - <dt><code>XML_ERROR_FINISHED</code></dt> - <dd>when the parser has already finished.</dd> - <dt><code>XML_ERROR_SUSPEND_PE</code></dt> - <dd>when suspending while parsing an external PE.</dd> -</dl> - -<p>Since the stop/resume feature requires application support in the -outer parsing loop, it is an error to call this function for a parser -not being handled appropriately; see <a href= "#stop-resume" ->Temporarily Stopping Parsing</a> for more information.</p> - -<p>When <code>resumable</code> is <code>XML_TRUE</code> then parsing -is <em>suspended</em>, that is, <code><a href= "#XML_Parse" ->XML_Parse</a></code> and <code><a href= "#XML_ParseBuffer" ->XML_ParseBuffer</a></code> return <code>XML_STATUS_SUSPENDED</code>. -Otherwise, parsing is <em>aborted</em>, that is, <code><a href= -"#XML_Parse" >XML_Parse</a></code> and <code><a href= -"#XML_ParseBuffer" >XML_ParseBuffer</a></code> return -<code>XML_STATUS_ERROR</code> with error code -<code>XML_ERROR_ABORTED</code>.</p> - -<p><strong>Note:</strong> -This will be applied to the current parser instance only, that is, if -there is a parent parser then it will continue parsing when the -external entity reference handler returns. It is up to the -implementation of that handler to call <code><a href= -"#XML_StopParser" >XML_StopParser</a></code> on the parent parser -(recursively), if one wants to stop parsing altogether.</p> - -<p>When suspended, parsing can be resumed by calling <code><a href= -"#XML_ResumeParser" >XML_ResumeParser</a></code>.</p> - -<p>New in Expat 1.95.8.</p> -</div> - -<pre class="fcndec" id="XML_ResumeParser"> -enum XML_Status XMLCALL -XML_ResumeParser(XML_Parser p); -</pre> -<div class="fcndef"> -<p>Resumes parsing after it has been suspended with <code><a href= -"#XML_StopParser" >XML_StopParser</a></code>. Must not be called from -within a handler call-back. Returns same status codes as <code><a -href= "#XML_Parse">XML_Parse</a></code> or <code><a href= -"#XML_ParseBuffer" >XML_ParseBuffer</a></code>. An additional error -code, <code>XML_ERROR_NOT_SUSPENDED</code>, will be returned if the -parser was not currently suspended.</p> - -<p><strong>Note:</strong> -This must be called on the most deeply nested child parser instance -first, and on its parent parser only after the child parser has -finished, to be applied recursively until the document entity's parser -is restarted. That is, the parent parser will not resume by itself -and it is up to the application to call <code><a href= -"#XML_ResumeParser" >XML_ResumeParser</a></code> on it at the -appropriate moment.</p> - -<p>New in Expat 1.95.8.</p> -</div> - -<pre class="fcndec" id="XML_GetParsingStatus"> -void XMLCALL -XML_GetParsingStatus(XML_Parser p, - XML_ParsingStatus *status); -</pre> -<pre class="signature"> -enum XML_Parsing { - XML_INITIALIZED, - XML_PARSING, - XML_FINISHED, - XML_SUSPENDED -}; - -typedef struct { - enum XML_Parsing parsing; - XML_Bool finalBuffer; -} XML_ParsingStatus; -</pre> -<div class="fcndef"> -<p>Returns status of parser with respect to being initialized, -parsing, finished, or suspended, and whether the final buffer is being -processed. The <code>status</code> parameter <em>must not</em> be -NULL.</p> - -<p>New in Expat 1.95.8.</p> -</div> - - -<h3><a name="setting">Handler Setting</a></h3> - -<p>Although handlers are typically set prior to parsing and left alone, an -application may choose to set or change the handler for a parsing event -while the parse is in progress. For instance, your application may choose -to ignore all text not descended from a <code>para</code> element. One -way it could do this is to set the character handler when a para start tag -is seen, and unset it for the corresponding end tag.</p> - -<p>A handler may be <em>unset</em> by providing a NULL pointer to the -appropriate handler setter. None of the handler setting functions have -a return value.</p> - -<p>Your handlers will be receiving strings in arrays of type -<code>XML_Char</code>. This type is conditionally defined in expat.h as -either <code>char</code>, <code>wchar_t</code> or <code>unsigned short</code>. -The former implies UTF-8 encoding, the latter two imply UTF-16 encoding. -Note that you'll receive them in this form independent of the original -encoding of the document.</p> - -<div class="handler"> -<pre class="setter" id="XML_SetStartElementHandler"> -void XMLCALL -XML_SetStartElementHandler(XML_Parser p, - XML_StartElementHandler start); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_StartElementHandler)(void *userData, - const XML_Char *name, - const XML_Char **atts); -</pre> -<p>Set handler for start (and empty) tags. Attributes are passed to the start -handler as a pointer to a vector of char pointers. Each attribute seen in -a start (or empty) tag occupies 2 consecutive places in this vector: the -attribute name followed by the attribute value. These pairs are terminated -by a null pointer.</p> -<p>Note that an empty tag generates a call to both start and end handlers -(in that order).</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetEndElementHandler"> -void XMLCALL -XML_SetEndElementHandler(XML_Parser p, - XML_EndElementHandler); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_EndElementHandler)(void *userData, - const XML_Char *name); -</pre> -<p>Set handler for end (and empty) tags. As noted above, an empty tag -generates a call to both start and end handlers.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetElementHandler"> -void XMLCALL -XML_SetElementHandler(XML_Parser p, - XML_StartElementHandler start, - XML_EndElementHandler end); -</pre> -<p>Set handlers for start and end tags with one call.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetCharacterDataHandler"> -void XMLCALL -XML_SetCharacterDataHandler(XML_Parser p, - XML_CharacterDataHandler charhndl) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_CharacterDataHandler)(void *userData, - const XML_Char *s, - int len); -</pre> -<p>Set a text handler. The string your handler receives -is <em>NOT nul-terminated</em>. You have to use the length argument -to deal with the end of the string. A single block of contiguous text -free of markup may still result in a sequence of calls to this handler. -In other words, if you're searching for a pattern in the text, it may -be split across calls to this handler. Note: Setting this handler to NULL -may <em>NOT immediately</em> terminate call-backs if the parser is currently -processing such a single block of contiguous markup-free text, as the parser -will continue calling back until the end of the block is reached.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetProcessingInstructionHandler"> -void XMLCALL -XML_SetProcessingInstructionHandler(XML_Parser p, - XML_ProcessingInstructionHandler proc) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, - const XML_Char *target, - const XML_Char *data); - -</pre> -<p>Set a handler for processing instructions. The target is the first word -in the processing instruction. The data is the rest of the characters in -it after skipping all whitespace after the initial word.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetCommentHandler"> -void XMLCALL -XML_SetCommentHandler(XML_Parser p, - XML_CommentHandler cmnt) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_CommentHandler)(void *userData, - const XML_Char *data); -</pre> -<p>Set a handler for comments. The data is all text inside the comment -delimiters.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetStartCdataSectionHandler"> -void XMLCALL -XML_SetStartCdataSectionHandler(XML_Parser p, - XML_StartCdataSectionHandler start); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_StartCdataSectionHandler)(void *userData); -</pre> -<p>Set a handler that gets called at the beginning of a CDATA section.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetEndCdataSectionHandler"> -void XMLCALL -XML_SetEndCdataSectionHandler(XML_Parser p, - XML_EndCdataSectionHandler end); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_EndCdataSectionHandler)(void *userData); -</pre> -<p>Set a handler that gets called at the end of a CDATA section.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetCdataSectionHandler"> -void XMLCALL -XML_SetCdataSectionHandler(XML_Parser p, - XML_StartCdataSectionHandler start, - XML_EndCdataSectionHandler end) -</pre> -<p>Sets both CDATA section handlers with one call.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetDefaultHandler"> -void XMLCALL -XML_SetDefaultHandler(XML_Parser p, - XML_DefaultHandler hndl) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_DefaultHandler)(void *userData, - const XML_Char *s, - int len); -</pre> - -<p>Sets a handler for any characters in the document which wouldn't -otherwise be handled. This includes both data for which no handlers -can be set (like some kinds of DTD declarations) and data which could -be reported but which currently has no handler set. The characters -are passed exactly as they were present in the XML document except -that they will be encoded in UTF-8 or UTF-16. Line boundaries are not -normalized. Note that a byte order mark character is not passed to the -default handler. There are no guarantees about how characters are -divided between calls to the default handler: for example, a comment -might be split between multiple calls. Setting the handler with -this call has the side effect of turning off expansion of references -to internally defined general entities. Instead these references are -passed to the default handler.</p> - -<p>See also <code><a -href="#XML_DefaultCurrent">XML_DefaultCurrent</a></code>.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetDefaultHandlerExpand"> -void XMLCALL -XML_SetDefaultHandlerExpand(XML_Parser p, - XML_DefaultHandler hndl) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_DefaultHandler)(void *userData, - const XML_Char *s, - int len); -</pre> -<p>This sets a default handler, but doesn't inhibit the expansion of -internal entity references. The entity reference will not be passed -to the default handler.</p> - -<p>See also <code><a -href="#XML_DefaultCurrent">XML_DefaultCurrent</a></code>.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetExternalEntityRefHandler"> -void XMLCALL -XML_SetExternalEntityRefHandler(XML_Parser p, - XML_ExternalEntityRefHandler hndl) -</pre> -<pre class="signature"> -typedef int -(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser p, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); -</pre> -<p>Set an external entity reference handler. This handler is also -called for processing an external DTD subset if parameter entity parsing -is in effect. (See <a href="#XML_SetParamEntityParsing"> -<code>XML_SetParamEntityParsing</code></a>.)</p> - -<p>The <code>context</code> parameter specifies the parsing context in -the format expected by the <code>context</code> argument to <code><a -href="#XML_ExternalEntityParserCreate" ->XML_ExternalEntityParserCreate</a></code>. <code>code</code> is -valid only until the handler returns, so if the referenced entity is -to be parsed later, it must be copied. <code>context</code> is NULL -only when the entity is a parameter entity, which is how one can -differentiate between general and parameter entities.</p> - -<p>The <code>base</code> parameter is the base to use for relative -system identifiers. It is set by <code><a -href="#XML_SetBase">XML_SetBase</a></code> and may be NULL. The -<code>publicId</code> parameter is the public id given in the entity -declaration and may be NULL. <code>systemId</code> is the system -identifier specified in the entity declaration and is never NULL.</p> - -<p>There are a couple of ways in which this handler differs from -others. First, this handler returns a status indicator (an -integer). <code>XML_STATUS_OK</code> should be returned for successful -handling of the external entity reference. Returning -<code>XML_STATUS_ERROR</code> indicates failure, and causes the -calling parser to return an -<code>XML_ERROR_EXTERNAL_ENTITY_HANDLING</code> error.</p> - -<p>Second, instead of having the user data as its first argument, it -receives the parser that encountered the entity reference. This, along -with the context parameter, may be used as arguments to a call to -<code><a href= "#XML_ExternalEntityParserCreate" ->XML_ExternalEntityParserCreate</a></code>. Using the returned -parser, the body of the external entity can be recursively parsed.</p> - -<p>Since this handler may be called recursively, it should not be saving -information into global or static variables.</p> -</div> - -<pre class="fcndec" id="XML_SetExternalEntityRefHandlerArg"> -void XMLCALL -XML_SetExternalEntityRefHandlerArg(XML_Parser p, - void *arg) -</pre> -<div class="fcndef"> -<p>Set the argument passed to the ExternalEntityRefHandler. If -<code>arg</code> is not NULL, it is the new value passed to the -handler set using <code><a href="#XML_SetExternalEntityRefHandler" ->XML_SetExternalEntityRefHandler</a></code>; if <code>arg</code> is -NULL, the argument passed to the handler function will be the parser -object itself.</p> - -<p><strong>Note:</strong> -The type of <code>arg</code> and the type of the first argument to the -ExternalEntityRefHandler do not match. This function takes a -<code>void *</code> to be passed to the handler, while the handler -accepts an <code>XML_Parser</code>. This is a historical accident, -but will not be corrected before Expat 2.0 (at the earliest) to avoid -causing compiler warnings for code that's known to work with this -API. It is the responsibility of the application code to know the -actual type of the argument passed to the handler and to manage it -properly.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetSkippedEntityHandler"> -void XMLCALL -XML_SetSkippedEntityHandler(XML_Parser p, - XML_SkippedEntityHandler handler) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_SkippedEntityHandler)(void *userData, - const XML_Char *entityName, - int is_parameter_entity); -</pre> -<p>Set a skipped entity handler. This is called in two situations:</p> -<ol> - <li>An entity reference is encountered for which no declaration - has been read <em>and</em> this is not an error.</li> - <li>An internal entity reference is read, but not expanded, because - <a href="#XML_SetDefaultHandler"><code>XML_SetDefaultHandler</code></a> - has been called.</li> -</ol> -<p>The <code>is_parameter_entity</code> argument will be non-zero for -a parameter entity and zero for a general entity.</p> <p>Note: skipped -parameter entities in declarations and skipped general entities in -attribute values cannot be reported, because the event would be out of -sync with the reporting of the declarations or attribute values</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetUnknownEncodingHandler"> -void XMLCALL -XML_SetUnknownEncodingHandler(XML_Parser p, - XML_UnknownEncodingHandler enchandler, - void *encodingHandlerData) -</pre> -<pre class="signature"> -typedef int -(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, - const XML_Char *name, - XML_Encoding *info); - -typedef struct { - int map[256]; - void *data; - int (XMLCALL *convert)(void *data, const char *s); - void (XMLCALL *release)(void *data); -} XML_Encoding; -</pre> -<p>Set a handler to deal with encodings other than the <a -href="#builtin_encodings">built in set</a>. This should be done before -<code><a href= "#XML_Parse" >XML_Parse</a></code> or <code><a href= -"#XML_ParseBuffer" >XML_ParseBuffer</a></code> have been called on the -given parser.</p> <p>If the handler knows how to deal with an encoding -with the given name, it should fill in the <code>info</code> data -structure and return <code>XML_STATUS_OK</code>. Otherwise it -should return <code>XML_STATUS_ERROR</code>. The handler will be called -at most once per parsed (external) entity. The optional application -data pointer <code>encodingHandlerData</code> will be passed back to -the handler.</p> - -<p>The map array contains information for every possible possible leading -byte in a byte sequence. If the corresponding value is >= 0, then it's -a single byte sequence and the byte encodes that Unicode value. If the -value is -1, then that byte is invalid as the initial byte in a sequence. -If the value is -n, where n is an integer > 1, then n is the number of -bytes in the sequence and the actual conversion is accomplished by a -call to the function pointed at by convert. This function may return -1 -if the sequence itself is invalid. The convert pointer may be null if -there are only single byte codes. The data parameter passed to the convert -function is the data pointer from <code>XML_Encoding</code>. The -string s is <em>NOT</em> nul-terminated and points at the sequence of -bytes to be converted.</p> - -<p>The function pointed at by <code>release</code> is called by the -parser when it is finished with the encoding. It may be NULL.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetStartNamespaceDeclHandler"> -void XMLCALL -XML_SetStartNamespaceDeclHandler(XML_Parser p, - XML_StartNamespaceDeclHandler start); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, - const XML_Char *prefix, - const XML_Char *uri); -</pre> -<p>Set a handler to be called when a namespace is declared. Namespace -declarations occur inside start tags. But the namespace declaration start -handler is called before the start tag handler for each namespace declared -in that start tag.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetEndNamespaceDeclHandler"> -void XMLCALL -XML_SetEndNamespaceDeclHandler(XML_Parser p, - XML_EndNamespaceDeclHandler end); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, - const XML_Char *prefix); -</pre> -<p>Set a handler to be called when leaving the scope of a namespace -declaration. This will be called, for each namespace declaration, -after the handler for the end tag of the element in which the -namespace was declared.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetNamespaceDeclHandler"> -void XMLCALL -XML_SetNamespaceDeclHandler(XML_Parser p, - XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end) -</pre> -<p>Sets both namespace declaration handlers with a single call.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetXmlDeclHandler"> -void XMLCALL -XML_SetXmlDeclHandler(XML_Parser p, - XML_XmlDeclHandler xmldecl); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_XmlDeclHandler)(void *userData, - const XML_Char *version, - const XML_Char *encoding, - int standalone); -</pre> -<p>Sets a handler that is called for XML declarations and also for -text declarations discovered in external entities. The way to -distinguish is that the <code>version</code> parameter will be NULL -for text declarations. The <code>encoding</code> parameter may be NULL -for an XML declaration. The <code>standalone</code> argument will -contain -1, 0, or 1 indicating respectively that there was no -standalone parameter in the declaration, that it was given as no, or -that it was given as yes.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetStartDoctypeDeclHandler"> -void XMLCALL -XML_SetStartDoctypeDeclHandler(XML_Parser p, - XML_StartDoctypeDeclHandler start); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, - const XML_Char *doctypeName, - const XML_Char *sysid, - const XML_Char *pubid, - int has_internal_subset); -</pre> -<p>Set a handler that is called at the start of a DOCTYPE declaration, -before any external or internal subset is parsed. Both <code>sysid</code> -and <code>pubid</code> may be NULL. The <code>has_internal_subset</code> -will be non-zero if the DOCTYPE declaration has an internal subset.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetEndDoctypeDeclHandler"> -void XMLCALL -XML_SetEndDoctypeDeclHandler(XML_Parser p, - XML_EndDoctypeDeclHandler end); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); -</pre> -<p>Set a handler that is called at the end of a DOCTYPE declaration, -after parsing any external subset.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetDoctypeDeclHandler"> -void XMLCALL -XML_SetDoctypeDeclHandler(XML_Parser p, - XML_StartDoctypeDeclHandler start, - XML_EndDoctypeDeclHandler end); -</pre> -<p>Set both doctype handlers with one call.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetElementDeclHandler"> -void XMLCALL -XML_SetElementDeclHandler(XML_Parser p, - XML_ElementDeclHandler eldecl); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_ElementDeclHandler)(void *userData, - const XML_Char *name, - XML_Content *model); -</pre> -<pre class="signature"> -enum XML_Content_Type { - XML_CTYPE_EMPTY = 1, - XML_CTYPE_ANY, - XML_CTYPE_MIXED, - XML_CTYPE_NAME, - XML_CTYPE_CHOICE, - XML_CTYPE_SEQ -}; - -enum XML_Content_Quant { - XML_CQUANT_NONE, - XML_CQUANT_OPT, - XML_CQUANT_REP, - XML_CQUANT_PLUS -}; - -typedef struct XML_cp XML_Content; - -struct XML_cp { - enum XML_Content_Type type; - enum XML_Content_Quant quant; - const XML_Char * name; - unsigned int numchildren; - XML_Content * children; -}; -</pre> -<p>Sets a handler for element declarations in a DTD. The handler gets -called with the name of the element in the declaration and a pointer -to a structure that contains the element model. It is the -application's responsibility to free this data structure using -<code><a href="#XML_FreeContentModel" ->XML_FreeContentModel</a></code>.</p> - -<p>The <code>model</code> argument is the root of a tree of -<code>XML_Content</code> nodes. If <code>type</code> equals -<code>XML_CTYPE_EMPTY</code> or <code>XML_CTYPE_ANY</code>, then -<code>quant</code> will be <code>XML_CQUANT_NONE</code>, and the other -fields will be zero or NULL. If <code>type</code> is -<code>XML_CTYPE_MIXED</code>, then <code>quant</code> will be -<code>XML_CQUANT_NONE</code> or <code>XML_CQUANT_REP</code> and -<code>numchildren</code> will contain the number of elements that are -allowed to be mixed in and <code>children</code> points to an array of -<code>XML_Content</code> structures that will all have type -XML_CTYPE_NAME with no quantification. Only the root node can be type -<code>XML_CTYPE_EMPTY</code>, <code>XML_CTYPE_ANY</code>, or -<code>XML_CTYPE_MIXED</code>.</p> - -<p>For type <code>XML_CTYPE_NAME</code>, the <code>name</code> field -points to the name and the <code>numchildren</code> and -<code>children</code> fields will be zero and NULL. The -<code>quant</code> field will indicate any quantifiers placed on the -name.</p> - -<p>Types <code>XML_CTYPE_CHOICE</code> and <code>XML_CTYPE_SEQ</code> -indicate a choice or sequence respectively. The -<code>numchildren</code> field indicates how many nodes in the choice -or sequence and <code>children</code> points to the nodes.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetAttlistDeclHandler"> -void XMLCALL -XML_SetAttlistDeclHandler(XML_Parser p, - XML_AttlistDeclHandler attdecl); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_AttlistDeclHandler)(void *userData, - const XML_Char *elname, - const XML_Char *attname, - const XML_Char *att_type, - const XML_Char *dflt, - int isrequired); -</pre> -<p>Set a handler for attlist declarations in the DTD. This handler is -called for <em>each</em> attribute. So a single attlist declaration -with multiple attributes declared will generate multiple calls to this -handler. The <code>elname</code> parameter returns the name of the -element for which the attribute is being declared. The attribute name -is in the <code>attname</code> parameter. The attribute type is in the -<code>att_type</code> parameter. It is the string representing the -type in the declaration with whitespace removed.</p> - -<p>The <code>dflt</code> parameter holds the default value. It will be -NULL in the case of "#IMPLIED" or "#REQUIRED" attributes. You can -distinguish these two cases by checking the <code>isrequired</code> -parameter, which will be true in the case of "#REQUIRED" attributes. -Attributes which are "#FIXED" will have also have a true -<code>isrequired</code>, but they will have the non-NULL fixed value -in the <code>dflt</code> parameter.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetEntityDeclHandler"> -void XMLCALL -XML_SetEntityDeclHandler(XML_Parser p, - XML_EntityDeclHandler handler); -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_EntityDeclHandler)(void *userData, - const XML_Char *entityName, - int is_parameter_entity, - const XML_Char *value, - int value_length, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); -</pre> -<p>Sets a handler that will be called for all entity declarations. -The <code>is_parameter_entity</code> argument will be non-zero in the -case of parameter entities and zero otherwise.</p> - -<p>For internal entities (<code><!ENTITY foo "bar"></code>), -<code>value</code> will be non-NULL and <code>systemId</code>, -<code>publicId</code>, and <code>notationName</code> will all be NULL. -The value string is <em>not</em> NULL terminated; the length is -provided in the <code>value_length</code> parameter. Do not use -<code>value_length</code> to test for internal entities, since it is -legal to have zero-length values. Instead check for whether or not -<code>value</code> is NULL.</p> <p>The <code>notationName</code> -argument will have a non-NULL value only for unparsed entity -declarations.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetUnparsedEntityDeclHandler"> -void XMLCALL -XML_SetUnparsedEntityDeclHandler(XML_Parser p, - XML_UnparsedEntityDeclHandler h) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_UnparsedEntityDeclHandler)(void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); -</pre> -<p>Set a handler that receives declarations of unparsed entities. These -are entity declarations that have a notation (NDATA) field:</p> - -<div id="eg"><pre> -<!ENTITY logo SYSTEM "images/logo.gif" NDATA gif> -</pre></div> -<p>This handler is obsolete and is provided for backwards -compatibility. Use instead <a href= "#XML_SetEntityDeclHandler" ->XML_SetEntityDeclHandler</a>.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetNotationDeclHandler"> -void XMLCALL -XML_SetNotationDeclHandler(XML_Parser p, - XML_NotationDeclHandler h) -</pre> -<pre class="signature"> -typedef void -(XMLCALL *XML_NotationDeclHandler)(void *userData, - const XML_Char *notationName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); -</pre> -<p>Set a handler that receives notation declarations.</p> -</div> - -<div class="handler"> -<pre class="setter" id="XML_SetNotStandaloneHandler"> -void XMLCALL -XML_SetNotStandaloneHandler(XML_Parser p, - XML_NotStandaloneHandler h) -</pre> -<pre class="signature"> -typedef int -(XMLCALL *XML_NotStandaloneHandler)(void *userData); -</pre> -<p>Set a handler that is called if the document is not "standalone". -This happens when there is an external subset or a reference to a -parameter entity, but does not have standalone set to "yes" in an XML -declaration. If this handler returns <code>XML_STATUS_ERROR</code>, -then the parser will throw an <code>XML_ERROR_NOT_STANDALONE</code> -error.</p> -</div> - -<h3><a name="position">Parse position and error reporting functions</a></h3> - -<p>These are the functions you'll want to call when the parse -functions return <code>XML_STATUS_ERROR</code> (a parse error has -occurred), although the position reporting functions are useful outside -of errors. The position reported is the byte position (in the original -document or entity encoding) of the first of the sequence of -characters that generated the current event (or the error that caused -the parse functions to return <code>XML_STATUS_ERROR</code>.) The -exceptions are callbacks trigged by declarations in the document -prologue, in which case they exact position reported is somewhere in the -relevant markup, but not necessarily as meaningful as for other -events.</p> - -<p>The position reporting functions are accurate only outside of the -DTD. In other words, they usually return bogus information when -called from within a DTD declaration handler.</p> - -<pre class="fcndec" id="XML_GetErrorCode"> -enum XML_Error XMLCALL -XML_GetErrorCode(XML_Parser p); -</pre> -<div class="fcndef"> -Return what type of error has occurred. -</div> - -<pre class="fcndec" id="XML_ErrorString"> -const XML_LChar * XMLCALL -XML_ErrorString(enum XML_Error code); -</pre> -<div class="fcndef"> -Return a string describing the error corresponding to code. -The code should be one of the enums that can be returned from -<code><a href= "#XML_GetErrorCode" >XML_GetErrorCode</a></code>. -</div> - -<pre class="fcndec" id="XML_GetCurrentByteIndex"> -XML_Index XMLCALL -XML_GetCurrentByteIndex(XML_Parser p); -</pre> -<div class="fcndef"> -Return the byte offset of the position. This always corresponds to -the values returned by <code><a href= "#XML_GetCurrentLineNumber" ->XML_GetCurrentLineNumber</a></code> and <code><a href= -"#XML_GetCurrentColumnNumber" >XML_GetCurrentColumnNumber</a></code>. -</div> - -<pre class="fcndec" id="XML_GetCurrentLineNumber"> -XML_Size XMLCALL -XML_GetCurrentLineNumber(XML_Parser p); -</pre> -<div class="fcndef"> -Return the line number of the position. The first line is reported as -<code>1</code>. -</div> - -<pre class="fcndec" id="XML_GetCurrentColumnNumber"> -XML_Size XMLCALL -XML_GetCurrentColumnNumber(XML_Parser p); -</pre> -<div class="fcndef"> -Return the offset, from the beginning of the current line, of -the position. -</div> - -<pre class="fcndec" id="XML_GetCurrentByteCount"> -int XMLCALL -XML_GetCurrentByteCount(XML_Parser p); -</pre> -<div class="fcndef"> -Return the number of bytes in the current event. Returns -<code>0</code> if the event is inside a reference to an internal -entity and for the end-tag event for empty element tags (the later can -be used to distinguish empty-element tags from empty elements using -separate start and end tags). -</div> - -<pre class="fcndec" id="XML_GetInputContext"> -const char * XMLCALL -XML_GetInputContext(XML_Parser p, - int *offset, - int *size); -</pre> -<div class="fcndef"> - -<p>Returns the parser's input buffer, sets the integer pointed at by -<code>offset</code> to the offset within this buffer of the current -parse position, and set the integer pointed at by <code>size</code> to -the size of the returned buffer.</p> - -<p>This should only be called from within a handler during an active -parse and the returned buffer should only be referred to from within -the handler that made the call. This input buffer contains the -untranslated bytes of the input.</p> - -<p>Only a limited amount of context is kept, so if the event -triggering a call spans over a very large amount of input, the actual -parse position may be before the beginning of the buffer.</p> - -<p>If <code>XML_CONTEXT_BYTES</code> is not defined, this will always -return NULL.</p> -</div> - -<h3><a name="miscellaneous">Miscellaneous functions</a></h3> - -<p>The functions in this section either obtain state information from -the parser or can be used to dynamicly set parser options.</p> - -<pre class="fcndec" id="XML_SetUserData"> -void XMLCALL -XML_SetUserData(XML_Parser p, - void *userData); -</pre> -<div class="fcndef"> -This sets the user data pointer that gets passed to handlers. It -overwrites any previous value for this pointer. Note that the -application is responsible for freeing the memory associated with -<code>userData</code> when it is finished with the parser. So if you -call this when there's already a pointer there, and you haven't freed -the memory associated with it, then you've probably just leaked -memory. -</div> - -<pre class="fcndec" id="XML_GetUserData"> -void * XMLCALL -XML_GetUserData(XML_Parser p); -</pre> -<div class="fcndef"> -This returns the user data pointer that gets passed to handlers. -It is actually implemented as a macro. -</div> - -<pre class="fcndec" id="XML_UseParserAsHandlerArg"> -void XMLCALL -XML_UseParserAsHandlerArg(XML_Parser p); -</pre> -<div class="fcndef"> -After this is called, handlers receive the parser in their -<code>userData</code> arguments. The user data can still be obtained -using the <code><a href= "#XML_GetUserData" ->XML_GetUserData</a></code> function. -</div> - -<pre class="fcndec" id="XML_SetBase"> -enum XML_Status XMLCALL -XML_SetBase(XML_Parser p, - const XML_Char *base); -</pre> -<div class="fcndef"> -Set the base to be used for resolving relative URIs in system -identifiers. The return value is <code>XML_STATUS_ERROR</code> if -there's no memory to store base, otherwise it's -<code>XML_STATUS_OK</code>. -</div> - -<pre class="fcndec" id="XML_GetBase"> -const XML_Char * XMLCALL -XML_GetBase(XML_Parser p); -</pre> -<div class="fcndef"> -Return the base for resolving relative URIs. -</div> - -<pre class="fcndec" id="XML_GetSpecifiedAttributeCount"> -int XMLCALL -XML_GetSpecifiedAttributeCount(XML_Parser p); -</pre> -<div class="fcndef"> -When attributes are reported to the start handler in the atts vector, -attributes that were explicitly set in the element occur before any -attributes that receive their value from default information in an -ATTLIST declaration. This function returns the number of attributes -that were explicitly set times two, thus giving the offset in the -<code>atts</code> array passed to the start tag handler of the first -attribute set due to defaults. It supplies information for the last -call to a start handler. If called inside a start handler, then that -means the current call. -</div> - -<pre class="fcndec" id="XML_GetIdAttributeIndex"> -int XMLCALL -XML_GetIdAttributeIndex(XML_Parser p); -</pre> -<div class="fcndef"> -Returns the index of the ID attribute passed in the atts array in the -last call to <code><a href= "#XML_StartElementHandler" ->XML_StartElementHandler</a></code>, or -1 if there is no ID -attribute. If called inside a start handler, then that means the -current call. -</div> - -<pre class="fcndec" id="XML_SetEncoding"> -enum XML_Status XMLCALL -XML_SetEncoding(XML_Parser p, - const XML_Char *encoding); -</pre> -<div class="fcndef"> -Set the encoding to be used by the parser. It is equivalent to -passing a non-null encoding argument to the parser creation functions. -It must not be called after <code><a href= "#XML_Parse" ->XML_Parse</a></code> or <code><a href= "#XML_ParseBuffer" ->XML_ParseBuffer</a></code> have been called on the given parser. -Returns <code>XML_STATUS_OK</code> on success or -<code>XML_STATUS_ERROR</code> on error. -</div> - -<pre class="fcndec" id="XML_SetParamEntityParsing"> -int XMLCALL -XML_SetParamEntityParsing(XML_Parser p, - enum XML_ParamEntityParsing code); -</pre> -<div class="fcndef"> -This enables parsing of parameter entities, including the external -parameter entity that is the external DTD subset, according to -<code>code</code>. -The choices for <code>code</code> are: -<ul> -<li><code>XML_PARAM_ENTITY_PARSING_NEVER</code></li> -<li><code>XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE</code></li> -<li><code>XML_PARAM_ENTITY_PARSING_ALWAYS</code></li> -</ul> -</div> - -<pre class="fcndec" id="XML_UseForeignDTD"> -enum XML_Error XMLCALL -XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); -</pre> -<div class="fcndef"> -<p>This function allows an application to provide an external subset -for the document type declaration for documents which do not specify -an external subset of their own. For documents which specify an -external subset in their DOCTYPE declaration, the application-provided -subset will be ignored. If the document does not contain a DOCTYPE -declaration at all and <code>useDTD</code> is true, the -application-provided subset will be parsed, but the -<code>startDoctypeDeclHandler</code> and -<code>endDoctypeDeclHandler</code> functions, if set, will not be -called. The setting of parameter entity parsing, controlled using -<code><a href= "#XML_SetParamEntityParsing" ->XML_SetParamEntityParsing</a></code>, will be honored.</p> - -<p>The application-provided external subset is read by calling the -external entity reference handler set via <code><a href= -"#XML_SetExternalEntityRefHandler" ->XML_SetExternalEntityRefHandler</a></code> with both -<code>publicId</code> and <code>systemId</code> set to NULL.</p> - -<p>If this function is called after parsing has begun, it returns -<code>XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING</code> and ignores -<code>useDTD</code>. If called when Expat has been compiled without -DTD support, it returns -<code>XML_ERROR_FEATURE_REQUIRES_XML_DTD</code>. Otherwise, it -returns <code>XML_ERROR_NONE</code>.</p> - -<p><b>Note:</b> For the purpose of checking WFC: Entity Declared, passing -<code>useDTD == XML_TRUE</code> will make the parser behave as if -the document had a DTD with an external subset. This holds true even if -the external entity reference handler returns without action.</p> -</div> - -<pre class="fcndec" id="XML_SetReturnNSTriplet"> -void XMLCALL -XML_SetReturnNSTriplet(XML_Parser parser, - int do_nst); -</pre> -<div class="fcndef"> -<p> -This function only has an effect when using a parser created with -<code><a href= "#XML_ParserCreateNS" >XML_ParserCreateNS</a></code>, -i.e. when namespace processing is in effect. The <code>do_nst</code> -sets whether or not prefixes are returned with names qualified with a -namespace prefix. If this function is called with <code>do_nst</code> -non-zero, then afterwards namespace qualified names (that is qualified -with a prefix as opposed to belonging to a default namespace) are -returned as a triplet with the three parts separated by the namespace -separator specified when the parser was created. The order of -returned parts is URI, local name, and prefix.</p> <p>If -<code>do_nst</code> is zero, then namespaces are reported in the -default manner, URI then local_name separated by the namespace -separator.</p> -</div> - -<pre class="fcndec" id="XML_DefaultCurrent"> -void XMLCALL -XML_DefaultCurrent(XML_Parser parser); -</pre> -<div class="fcndef"> -This can be called within a handler for a start element, end element, -processing instruction or character data. It causes the corresponding -markup to be passed to the default handler set by <code><a -href="#XML_SetDefaultHandler" >XML_SetDefaultHandler</a></code> or -<code><a href="#XML_SetDefaultHandlerExpand" ->XML_SetDefaultHandlerExpand</a></code>. It does nothing if there is -not a default handler. -</div> - -<pre class="fcndec" id="XML_ExpatVersion"> -XML_LChar * XMLCALL -XML_ExpatVersion(); -</pre> -<div class="fcndef"> -Return the library version as a string (e.g. <code>"expat_1.95.1"</code>). -</div> - -<pre class="fcndec" id="XML_ExpatVersionInfo"> -struct XML_Expat_Version XMLCALL -XML_ExpatVersionInfo(); -</pre> -<pre class="signature"> -typedef struct { - int major; - int minor; - int micro; -} XML_Expat_Version; -</pre> -<div class="fcndef"> -Return the library version information as a structure. -Some macros are also defined that support compile-time tests of the -library version: -<ul> -<li><code>XML_MAJOR_VERSION</code></li> -<li><code>XML_MINOR_VERSION</code></li> -<li><code>XML_MICRO_VERSION</code></li> -</ul> -Testing these constants is currently the best way to determine if -particular parts of the Expat API are available. -</div> - -<pre class="fcndec" id="XML_GetFeatureList"> -const XML_Feature * XMLCALL -XML_GetFeatureList(); -</pre> -<pre class="signature"> -enum XML_FeatureEnum { - XML_FEATURE_END = 0, - XML_FEATURE_UNICODE, - XML_FEATURE_UNICODE_WCHAR_T, - XML_FEATURE_DTD, - XML_FEATURE_CONTEXT_BYTES, - XML_FEATURE_MIN_SIZE, - XML_FEATURE_SIZEOF_XML_CHAR, - XML_FEATURE_SIZEOF_XML_LCHAR, - XML_FEATURE_NS, - XML_FEATURE_LARGE_SIZE -}; - -typedef struct { - enum XML_FeatureEnum feature; - XML_LChar *name; - long int value; -} XML_Feature; -</pre> -<div class="fcndef"> -<p>Returns a list of "feature" records, providing details on how -Expat was configured at compile time. Most applications should not -need to worry about this, but this information is otherwise not -available from Expat. This function allows code that does need to -check these features to do so at runtime.</p> - -<p>The return value is an array of <code>XML_Feature</code>, -terminated by a record with a <code>feature</code> of -<code>XML_FEATURE_END</code> and <code>name</code> of NULL, -identifying the feature-test macros Expat was compiled with. Since an -application that requires this kind of information needs to determine -the type of character the <code>name</code> points to, records for the -<code>XML_FEATURE_SIZEOF_XML_CHAR</code> and -<code>XML_FEATURE_SIZEOF_XML_LCHAR</code> will be located at the -beginning of the list, followed by <code>XML_FEATURE_UNICODE</code> -and <code>XML_FEATURE_UNICODE_WCHAR_T</code>, if they are present at -all.</p> - -<p>Some features have an associated value. If there isn't an -associated value, the <code>value</code> field is set to 0. At this -time, the following features have been defined to have values:</p> - -<dl> - <dt><code>XML_FEATURE_SIZEOF_XML_CHAR</code></dt> - <dd>The number of bytes occupied by one <code>XML_Char</code> - character.</dd> - <dt><code>XML_FEATURE_SIZEOF_XML_LCHAR</code></dt> - <dd>The number of bytes occupied by one <code>XML_LChar</code> - character.</dd> - <dt><code>XML_FEATURE_CONTEXT_BYTES</code></dt> - <dd>The maximum number of characters of context which can be - reported by <code><a href= "#XML_GetInputContext" - >XML_GetInputContext</a></code>.</dd> -</dl> -</div> - -<pre class="fcndec" id="XML_FreeContentModel"> -void XMLCALL -XML_FreeContentModel(XML_Parser parser, XML_Content *model); -</pre> -<div class="fcndef"> -Function to deallocate the <code>model</code> argument passed to the -<code>XML_ElementDeclHandler</code> callback set using <code><a -href="#XML_SetElementDeclHandler" >XML_ElementDeclHandler</a></code>. -This function should not be used for any other purpose. -</div> - -<p>The following functions allow external code to share the memory -allocator an <code>XML_Parser</code> has been configured to use. This -is especially useful for third-party libraries that interact with a -parser object created by application code, or heavily layered -applications. This can be essential when using dynamically loaded -libraries which use different C standard libraries (this can happen on -Windows, at least).</p> - -<pre class="fcndec" id="XML_MemMalloc"> -void * XMLCALL -XML_MemMalloc(XML_Parser parser, size_t size); -</pre> -<div class="fcndef"> -Allocate <code>size</code> bytes of memory using the allocator the -<code>parser</code> object has been configured to use. Returns a -pointer to the memory or NULL on failure. Memory allocated in this -way must be freed using <code><a href="#XML_MemFree" ->XML_MemFree</a></code>. -</div> - -<pre class="fcndec" id="XML_MemRealloc"> -void * XMLCALL -XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); -</pre> -<div class="fcndef"> -Allocate <code>size</code> bytes of memory using the allocator the -<code>parser</code> object has been configured to use. -<code>ptr</code> must point to a block of memory allocated by <code><a -href="#XML_MemMalloc" >XML_MemMalloc</a></code> or -<code>XML_MemRealloc</code>, or be NULL. This function tries to -expand the block pointed to by <code>ptr</code> if possible. Returns -a pointer to the memory or NULL on failure. On success, the original -block has either been expanded or freed. On failure, the original -block has not been freed; the caller is responsible for freeing the -original block. Memory allocated in this way must be freed using -<code><a href="#XML_MemFree" ->XML_MemFree</a></code>. -</div> - -<pre class="fcndec" id="XML_MemFree"> -void XMLCALL -XML_MemFree(XML_Parser parser, void *ptr); -</pre> -<div class="fcndef"> -Free a block of memory pointed to by <code>ptr</code>. The block must -have been allocated by <code><a href="#XML_MemMalloc" ->XML_MemMalloc</a></code> or <code>XML_MemRealloc</code>, or be NULL. -</div> - -<hr /> -<p><a href="http://validator.w3.org/check/referer"><img - src="valid-xhtml10.png" alt="Valid XHTML 1.0!" - height="31" width="88" class="noborder" /></a></p> -</div> -</body> -</html> diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/style.css b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/style.css deleted file mode 100644 index 69df30b..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/style.css +++ /dev/null @@ -1,101 +0,0 @@ -body { - background-color: white; - border: 0px; - margin: 0px; - padding: 0px; -} - -.corner { - width: 200px; - height: 80px; - text-align: center; -} - -.banner { - background-color: rgb(110,139,61); - color: rgb(255,236,176); - padding-left: 2em; -} - -.banner h1 { - font-size: 200%; -} - -.content { - padding: 0em 2em 1em 2em; -} - -.releaseno { - background-color: rgb(110,139,61); - color: rgb(255,236,176); - padding-bottom: 0.3em; - padding-top: 0.5em; - text-align: center; - font-weight: bold; -} - -.noborder { - border-width: 0px; -} - -.eg { - padding-left: 1em; - padding-top: .5em; - padding-bottom: .5em; - border: solid thin; - margin: 1em 0; - background-color: tan; - margin-left: 2em; - margin-right: 10%; -} - -.pseudocode { - padding-left: 1em; - padding-top: .5em; - padding-bottom: .5em; - border: solid thin; - margin: 1em 0; - background-color: rgb(250,220,180); - margin-left: 2em; - margin-right: 10%; -} - -.handler { - width: 100%; - border-top-width: thin; - margin-bottom: 1em; -} - -.handler p { - margin-left: 2em; -} - -.setter { - font-weight: bold; -} - -.signature { - color: navy; -} - -.fcndec { - width: 100%; - border-top-width: thin; - font-weight: bold; -} - -.fcndef { - margin-left: 2em; - margin-bottom: 2em; -} - -dd { - margin-bottom: 2em; -} - -.cpp-symbols dt { - font-family: monospace; -} -.cpp-symbols dd { - margin-bottom: 1em; -} diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/valid-xhtml10.png b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/valid-xhtml10.png Binary files differdeleted file mode 100644 index 4c23f48..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Doc/valid-xhtml10.png +++ /dev/null diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/MANIFEST.txt b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/MANIFEST.txt deleted file mode 100644 index b7cd395..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/MANIFEST.txt +++ /dev/null @@ -1,27 +0,0 @@ - Overview of the Expat distribution - -The Expat distribution creates several subdirectories on your system. -Some of these directories contain components of interest to all Expat -users, and some contain material of interest to developers who wish to -use Expat in their applications. In the list below, <top> is the -directory you specified to the installer. - - Directory Contents - --------------------------------------------------------------------- - <top>\ Some general information files. - - <top>\Doc\ API documentation for developers. - - <top>\Bin\ Pre-compiled dynamic libraries for developers. - Pre-compiled static libraries for developers (*MT.lib). - The XML well-formedness checker xmlwf. - - <top>\Source\ Source code, which may interest some developers, - including a workspace for Microsft Visual C++. - The source code includes the parser, the well- - formedness checker, and a couple of small sample - applications. - - <top>\Source\bcb5\ Project files for Borland C++ Builder 5 and BCC 5.5. - - diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/README.google b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/README.google deleted file mode 100644 index b1359aa..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/README.google +++ /dev/null @@ -1,39 +0,0 @@ -URL: http://downloads.sourceforge.net/expat/expat-win32bin-2.0.1.exe -Version: 2.0.1 -License: MIT -License File: COPYING.txt - -Description: -This is Expat XML parser - very lightweight C library for -parsing XML, typically linked as a static lib. -File tree is expanded from the win32-specific download of Expat from: - http://downloads.sourceforge.net/expat/expat-win32bin-2.0.1.exe -Some directories are not checked in (bin, examples, tests) - -Local Modifications: -The only modifications from the downloaded version is a patch to an -internally discovered bug with the handling of utf-8 characters, -that leads to a crash (CL 6144603 etc.), and a change has been made to -winconfig.h to prevent a compiler warning when compiling with -WIN32_LEAN_AND_MEAN defined. - -The typical usage of the library is to compile it in or compile it -into a static lib and link in. - -The files you need to compile are: -lib\xmlparse.c -lib\xmltok.c -lib\xmlrole.c - -Following compile-time #define variables can be used: -XML_DTD - if you need to parse DTDs and validate -XML_UNICODE - if defined, all strings are 16-bit unicode, if not then UTF8. - defines XML_Char appropriately -XML_UNICODE_WCHAR_T - if XML_UNICODE is defined, controls whether XML_Char - is wchar_t or unsigned short -COMPILED_FROM_DSP - if defined, automatically defines XML_UNICODE - and includes windows headers -XML_STATIC - should be defined to produce statically-linked DLL -XML_MIN_SIZE - if defined, produces smaller but slower code - - diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/README.txt b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/README.txt deleted file mode 100644 index fda282a..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/README.txt +++ /dev/null @@ -1,137 +0,0 @@ - - Expat, Release 2.0.1 - -This is Expat, a C library for parsing XML, written by James Clark. -Expat is a stream-oriented XML parser. This means that you register -handlers with the parser before starting the parse. These handlers -are called when the parser discovers the associated structures in the -document being parsed. A start tag is an example of the kind of -structures for which you may register handlers. - -Windows users should use the expat_win32bin package, which includes -both precompiled libraries and executables, and source code for -developers. - -Expat is free software. You may copy, distribute, and modify it under -the terms of the License contained in the file COPYING distributed -with this package. This license is the same as the MIT/X Consortium -license. - -Versions of Expat that have an odd minor version (the middle number in -the release above), are development releases and should be considered -as beta software. Releases with even minor version numbers are -intended to be production grade software. - -If you are building Expat from a check-out from the CVS repository, -you need to run a script that generates the configure script using the -GNU autoconf and libtool tools. To do this, you need to have -autoconf 2.52 or newer and libtool 1.4 or newer (1.5 or newer preferred). -Run the script like this: - - ./buildconf.sh - -Once this has been done, follow the same instructions as for building -from a source distribution. - -To build Expat from a source distribution, you first run the -configuration shell script in the top level distribution directory: - - ./configure - -There are many options which you may provide to configure (which you -can discover by running configure with the --help option). But the -one of most interest is the one that sets the installation directory. -By default, the configure script will set things up to install -libexpat into /usr/local/lib, expat.h into /usr/local/include, and -xmlwf into /usr/local/bin. If, for example, you'd prefer to install -into /home/me/mystuff/lib, /home/me/mystuff/include, and -/home/me/mystuff/bin, you can tell configure about that with: - - ./configure --prefix=/home/me/mystuff - -Another interesting option is to enable 64-bit integer support for -line and column numbers and the over-all byte index: - - ./configure CPPFLAGS=-DXML_LARGE_SIZE - -However, such a modification would be a breaking change to the ABI -and is therefore not recommended for general use - e.g. as part of -a Linux distribution - but rather for builds with special requirements. - -After running the configure script, the "make" command will build -things and "make install" will install things into their proper -location. Have a look at the "Makefile" to learn about additional -"make" options. Note that you need to have write permission into -the directories into which things will be installed. - -If you are interested in building Expat to provide document -information in UTF-16 rather than the default UTF-8, follow these -instructions (after having run "make distclean"): - - 1. For UTF-16 output as unsigned short (and version/error - strings as char), run: - - ./configure CPPFLAGS=-DXML_UNICODE - - For UTF-16 output as wchar_t (incl. version/error strings), - run: - - ./configure CFLAGS="-g -O2 -fshort-wchar" \ - CPPFLAGS=-DXML_UNICODE_WCHAR_T - - 2. Edit the MakeFile, changing: - - LIBRARY = libexpat.la - - to: - - LIBRARY = libexpatw.la - - (Note the additional "w" in the library name.) - - 3. Run "make buildlib" (which builds the library only). - Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la". - - 4. Run "make installlib" (which installs the library only). - Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la". - -Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default -value for DESTDIR, and the rest of the make file using only DESTDIR. -It works as follows: - $ make install DESTDIR=/path/to/image -overrides the in-makefile set DESTDIR, while both - $ INSTALL_ROOT=/path/to/image make install - $ make install INSTALL_ROOT=/path/to/image -use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the -environment, because variable-setting priority is -1) commandline -2) in-makefile -3) environment - -Note for Solaris users: The "ar" command is usually located in -"/usr/ccs/bin", which is not in the default PATH. You will need to -add this to your path for the "make" command, and probably also switch -to GNU make (the "make" found in /usr/ccs/bin does not seem to work -properly -- appearantly it does not understand .PHONY directives). If -you're using ksh or bash, use this command to build: - - PATH=/usr/ccs/bin:$PATH make - -When using Expat with a project using autoconf for configuration, you -can use the probing macro in conftools/expat.m4 to determine how to -include Expat. See the comments at the top of that file for more -information. - -A reference manual is available in the file doc/reference.html in this -distribution. - -The homepage for this project is http://www.libexpat.org/. There -are links there to connect you to the bug reports page. If you need -to report a bug when you don't have access to a browser, you may also -send a bug report by email to expat-bugs@mail.libexpat.org. - -Discussion related to the direction of future expat development takes -place on expat-discuss@mail.libexpat.org. Archives of this list and -other Expat-related lists may be found at: - - http://mail.libexpat.org/mailman/listinfo/ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/README.txt b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/README.txt deleted file mode 100644 index 77a94bc..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/README.txt +++ /dev/null @@ -1,80 +0,0 @@ - -Expat can be built on Windows in three ways: - using MS Visual C++ (6.0 or .NET), Borland C++ Builder 5 or Cygwin. - -* Cygwin: - This follows the Unix build procedures. - -* C++ Builder 5: - Possible with make files in the BCB5 subdirectory. - Details can be found in the ReadMe file located there. - -* MS Visual C++ 6: - Based on the workspace file expat.dsw. The related project - files (.dsp) are located in the lib subdirectory. - -* MS Visual Studio .NET 2002, 2003, 2005: - The VC++ 6 workspace file (expat.dsw) and project files (.dsp) - can be opened and imported in VS.NET without problems. - -* All MS C/C++ compilers: - The output for all projects will be generated in the win32\bin - directory, intermediate files will be located in project-specific - subdirectories of win32\tmp. - -* Creating MinGW dynamic libraries from MS VC++ DLLs: - - On the command line, execute these steps: - pexports libexpat.dll > expat.def - pexports libexpatw.dll > expatw.def - dlltool -d expat.def -l libexpat.a - dlltool -d expatw.def -l libexpatw.a - - The *.a files are mingw libraries. - -* Special note about MS VC++ and runtime libraries: - - There are three possible configurations: using the - single threaded or multithreaded run-time library, - or using the multi-threaded run-time Dll. That is, - one can build three different Expat libraries depending - on the needs of the application. - - Dynamic Linking: - - By default the Expat Dlls are built to link statically - with the multi-threaded run-time library. - The libraries are named - - libexpat(w).dll - - libexpat(w).lib (import library) - The "w" indicates the UTF-16 version of the library. - - One rarely uses other versions of the Dll, but they can - be built easily by specifying a different RTL linkage in - the IDE on the C/C++ tab under the category Code Generation. - - Static Linking: - - The libraries should be named like this: - Single-theaded: libexpat(w)ML.lib - Multi-threaded: libexpat(w)MT.lib - Multi-threaded Dll: libexpat(w)MD.lib - The suffixes conform to the compiler switch settings - /ML, /MT and /MD for MS VC++. - - Note: In Visual Studio 2005 (Visual C++ 8.0) and later, the - single-threaded runtime library is not supported anymore. - - By default, the expat-static and expatw-static projects are set up - to link statically against the multithreaded run-time library, - so they will build libexpatMT.lib or libexpatwMT.lib files. - - To build the other versions of the static library, - go to Project - Settings: - - specify a different RTL linkage on the C/C++ tab - under the category Code Generation. - - then, on the Library tab, change the output file name - accordingly, as described above - - An application linking to the static libraries must - have the global macro XML_STATIC defined. diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/amigaconfig.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/amigaconfig.h deleted file mode 100644 index 86c6115..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/amigaconfig.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef AMIGACONFIG_H -#define AMIGACONFIG_H - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 4321 - -/* Define to 1 if you have the `bcopy' function. */ -#define HAVE_BCOPY 1 - -/* Define to 1 if you have the <check.h> header file. */ -#undef HAVE_CHECK_H - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* whether byteorder is bigendian */ -#define WORDS_BIGENDIAN - -/* Define to specify how much context to retain around the current parse - point. */ -#define XML_CONTEXT_BYTES 1024 - -/* Define to make parameter entity parsing functionality available. */ -#define XML_DTD - -/* Define to make XML Namespaces functionality available. */ -#define XML_NS - -#endif /* AMIGACONFIG_H */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/ascii.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/ascii.h deleted file mode 100644 index d10530b..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/ascii.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#define ASCII_A 0x41 -#define ASCII_B 0x42 -#define ASCII_C 0x43 -#define ASCII_D 0x44 -#define ASCII_E 0x45 -#define ASCII_F 0x46 -#define ASCII_G 0x47 -#define ASCII_H 0x48 -#define ASCII_I 0x49 -#define ASCII_J 0x4A -#define ASCII_K 0x4B -#define ASCII_L 0x4C -#define ASCII_M 0x4D -#define ASCII_N 0x4E -#define ASCII_O 0x4F -#define ASCII_P 0x50 -#define ASCII_Q 0x51 -#define ASCII_R 0x52 -#define ASCII_S 0x53 -#define ASCII_T 0x54 -#define ASCII_U 0x55 -#define ASCII_V 0x56 -#define ASCII_W 0x57 -#define ASCII_X 0x58 -#define ASCII_Y 0x59 -#define ASCII_Z 0x5A - -#define ASCII_a 0x61 -#define ASCII_b 0x62 -#define ASCII_c 0x63 -#define ASCII_d 0x64 -#define ASCII_e 0x65 -#define ASCII_f 0x66 -#define ASCII_g 0x67 -#define ASCII_h 0x68 -#define ASCII_i 0x69 -#define ASCII_j 0x6A -#define ASCII_k 0x6B -#define ASCII_l 0x6C -#define ASCII_m 0x6D -#define ASCII_n 0x6E -#define ASCII_o 0x6F -#define ASCII_p 0x70 -#define ASCII_q 0x71 -#define ASCII_r 0x72 -#define ASCII_s 0x73 -#define ASCII_t 0x74 -#define ASCII_u 0x75 -#define ASCII_v 0x76 -#define ASCII_w 0x77 -#define ASCII_x 0x78 -#define ASCII_y 0x79 -#define ASCII_z 0x7A - -#define ASCII_0 0x30 -#define ASCII_1 0x31 -#define ASCII_2 0x32 -#define ASCII_3 0x33 -#define ASCII_4 0x34 -#define ASCII_5 0x35 -#define ASCII_6 0x36 -#define ASCII_7 0x37 -#define ASCII_8 0x38 -#define ASCII_9 0x39 - -#define ASCII_TAB 0x09 -#define ASCII_SPACE 0x20 -#define ASCII_EXCL 0x21 -#define ASCII_QUOT 0x22 -#define ASCII_AMP 0x26 -#define ASCII_APOS 0x27 -#define ASCII_MINUS 0x2D -#define ASCII_PERIOD 0x2E -#define ASCII_COLON 0x3A -#define ASCII_SEMI 0x3B -#define ASCII_LT 0x3C -#define ASCII_EQUALS 0x3D -#define ASCII_GT 0x3E -#define ASCII_LSQB 0x5B -#define ASCII_RSQB 0x5D -#define ASCII_UNDERSCORE 0x5F -#define ASCII_LPAREN 0x28 -#define ASCII_RPAREN 0x29 -#define ASCII_FF 0x0C -#define ASCII_SLASH 0x2F -#define ASCII_HASH 0x23 -#define ASCII_PIPE 0x7C -#define ASCII_COMMA 0x2C diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/asciitab.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/asciitab.h deleted file mode 100644 index 79a15c2..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/asciitab.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, -/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, -/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, -/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, -/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, -/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, -/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, -/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, -/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, -/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, -/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat.dsp b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat.dsp deleted file mode 100644 index 1fc17d4..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat.dsp +++ /dev/null @@ -1,185 +0,0 @@ -# Microsoft Developer Studio Project File - Name="expat" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=expat - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "expat.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "expat.mak" CFG="expat - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "expat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "expat - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "expat - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\win32\bin\Release" -# PROP Intermediate_Dir "..\win32\tmp\Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPAT_EXPORTS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILED_FROM_DSP" /FD /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none /machine:I386 /out:"..\win32\bin\Release/libexpat.dll" - -!ELSEIF "$(CFG)" == "expat - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\win32\bin\Debug" -# PROP Intermediate_Dir "..\win32\tmp\Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPAT_EXPORTS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /D "_DEBUG" /D "COMPILED_FROM_DSP" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none /debug /machine:I386 /out:"..\win32\bin\Debug/libexpat.dll" - -!ENDIF - -# Begin Target - -# Name "expat - Win32 Release" -# Name "expat - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\libexpat.def -# End Source File -# Begin Source File - -SOURCE=.\xmlparse.c - -!IF "$(CFG)" == "expat - Win32 Release" - -!ELSEIF "$(CFG)" == "expat - Win32 Debug" - -# ADD CPP /GX- /Od - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_ns.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\ascii.h -# End Source File -# Begin Source File - -SOURCE=.\asciitab.h -# End Source File -# Begin Source File - -SOURCE=.\expat.h -# End Source File -# Begin Source File - -SOURCE=.\expat_external.h -# End Source File -# Begin Source File - -SOURCE=.\iasciitab.h -# End Source File -# Begin Source File - -SOURCE=.\internal.h -# End Source File -# Begin Source File - -SOURCE=.\latin1tab.h -# End Source File -# Begin Source File - -SOURCE=.\nametab.h -# End Source File -# Begin Source File - -SOURCE=.\utf8tab.h -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat.h deleted file mode 100644 index 20a8278..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat.h +++ /dev/null @@ -1,1014 +0,0 @@ -/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#ifndef Expat_INCLUDED -#define Expat_INCLUDED 1 - -#ifdef __VMS -/* 0 1 2 3 0 1 2 3 - 1234567890123456789012345678901 1234567890123456789012345678901 */ -#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler -#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler -#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler -#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg -#endif - -#include <stdlib.h> -#include "expat_external.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct XML_ParserStruct; -typedef struct XML_ParserStruct *XML_Parser; - -/* Should this be defined using stdbool.h when C99 is available? */ -typedef unsigned char XML_Bool; -#define XML_TRUE ((XML_Bool) 1) -#define XML_FALSE ((XML_Bool) 0) - -/* The XML_Status enum gives the possible return values for several - API functions. The preprocessor #defines are included so this - stanza can be added to code that still needs to support older - versions of Expat 1.95.x: - - #ifndef XML_STATUS_OK - #define XML_STATUS_OK 1 - #define XML_STATUS_ERROR 0 - #endif - - Otherwise, the #define hackery is quite ugly and would have been - dropped. -*/ -enum XML_Status { - XML_STATUS_ERROR = 0, -#define XML_STATUS_ERROR XML_STATUS_ERROR - XML_STATUS_OK = 1, -#define XML_STATUS_OK XML_STATUS_OK - XML_STATUS_SUSPENDED = 2 -#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED -}; - -enum XML_Error { - XML_ERROR_NONE, - XML_ERROR_NO_MEMORY, - XML_ERROR_SYNTAX, - XML_ERROR_NO_ELEMENTS, - XML_ERROR_INVALID_TOKEN, - XML_ERROR_UNCLOSED_TOKEN, - XML_ERROR_PARTIAL_CHAR, - XML_ERROR_TAG_MISMATCH, - XML_ERROR_DUPLICATE_ATTRIBUTE, - XML_ERROR_JUNK_AFTER_DOC_ELEMENT, - XML_ERROR_PARAM_ENTITY_REF, - XML_ERROR_UNDEFINED_ENTITY, - XML_ERROR_RECURSIVE_ENTITY_REF, - XML_ERROR_ASYNC_ENTITY, - XML_ERROR_BAD_CHAR_REF, - XML_ERROR_BINARY_ENTITY_REF, - XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, - XML_ERROR_MISPLACED_XML_PI, - XML_ERROR_UNKNOWN_ENCODING, - XML_ERROR_INCORRECT_ENCODING, - XML_ERROR_UNCLOSED_CDATA_SECTION, - XML_ERROR_EXTERNAL_ENTITY_HANDLING, - XML_ERROR_NOT_STANDALONE, - XML_ERROR_UNEXPECTED_STATE, - XML_ERROR_ENTITY_DECLARED_IN_PE, - XML_ERROR_FEATURE_REQUIRES_XML_DTD, - XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, - /* Added in 1.95.7. */ - XML_ERROR_UNBOUND_PREFIX, - /* Added in 1.95.8. */ - XML_ERROR_UNDECLARING_PREFIX, - XML_ERROR_INCOMPLETE_PE, - XML_ERROR_XML_DECL, - XML_ERROR_TEXT_DECL, - XML_ERROR_PUBLICID, - XML_ERROR_SUSPENDED, - XML_ERROR_NOT_SUSPENDED, - XML_ERROR_ABORTED, - XML_ERROR_FINISHED, - XML_ERROR_SUSPEND_PE, - /* Added in 2.0. */ - XML_ERROR_RESERVED_PREFIX_XML, - XML_ERROR_RESERVED_PREFIX_XMLNS, - XML_ERROR_RESERVED_NAMESPACE_URI -}; - -enum XML_Content_Type { - XML_CTYPE_EMPTY = 1, - XML_CTYPE_ANY, - XML_CTYPE_MIXED, - XML_CTYPE_NAME, - XML_CTYPE_CHOICE, - XML_CTYPE_SEQ -}; - -enum XML_Content_Quant { - XML_CQUANT_NONE, - XML_CQUANT_OPT, - XML_CQUANT_REP, - XML_CQUANT_PLUS -}; - -/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be - XML_CQUANT_NONE, and the other fields will be zero or NULL. - If type == XML_CTYPE_MIXED, then quant will be NONE or REP and - numchildren will contain number of elements that may be mixed in - and children point to an array of XML_Content cells that will be - all of XML_CTYPE_NAME type with no quantification. - - If type == XML_CTYPE_NAME, then the name points to the name, and - the numchildren field will be zero and children will be NULL. The - quant fields indicates any quantifiers placed on the name. - - CHOICE and SEQ will have name NULL, the number of children in - numchildren and children will point, recursively, to an array - of XML_Content cells. - - The EMPTY, ANY, and MIXED types will only occur at top level. -*/ - -typedef struct XML_cp XML_Content; - -struct XML_cp { - enum XML_Content_Type type; - enum XML_Content_Quant quant; - XML_Char * name; - unsigned int numchildren; - XML_Content * children; -}; - - -/* This is called for an element declaration. See above for - description of the model argument. It's the caller's responsibility - to free model when finished with it. -*/ -typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, - const XML_Char *name, - XML_Content *model); - -XMLPARSEAPI(void) -XML_SetElementDeclHandler(XML_Parser parser, - XML_ElementDeclHandler eldecl); - -/* The Attlist declaration handler is called for *each* attribute. So - a single Attlist declaration with multiple attributes declared will - generate multiple calls to this handler. The "default" parameter - may be NULL in the case of the "#IMPLIED" or "#REQUIRED" - keyword. The "isrequired" parameter will be true and the default - value will be NULL in the case of "#REQUIRED". If "isrequired" is - true and default is non-NULL, then this is a "#FIXED" default. -*/ -typedef void (XMLCALL *XML_AttlistDeclHandler) ( - void *userData, - const XML_Char *elname, - const XML_Char *attname, - const XML_Char *att_type, - const XML_Char *dflt, - int isrequired); - -XMLPARSEAPI(void) -XML_SetAttlistDeclHandler(XML_Parser parser, - XML_AttlistDeclHandler attdecl); - -/* The XML declaration handler is called for *both* XML declarations - and text declarations. The way to distinguish is that the version - parameter will be NULL for text declarations. The encoding - parameter may be NULL for XML declarations. The standalone - parameter will be -1, 0, or 1 indicating respectively that there - was no standalone parameter in the declaration, that it was given - as no, or that it was given as yes. -*/ -typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, - const XML_Char *version, - const XML_Char *encoding, - int standalone); - -XMLPARSEAPI(void) -XML_SetXmlDeclHandler(XML_Parser parser, - XML_XmlDeclHandler xmldecl); - - -typedef struct { - void *(*malloc_fcn)(size_t size); - void *(*realloc_fcn)(void *ptr, size_t size); - void (*free_fcn)(void *ptr); -} XML_Memory_Handling_Suite; - -/* Constructs a new parser; encoding is the encoding specified by the - external protocol or NULL if there is none specified. -*/ -XMLPARSEAPI(XML_Parser) -XML_ParserCreate(const XML_Char *encoding); - -/* Constructs a new parser and namespace processor. Element type - names and attribute names that belong to a namespace will be - expanded; unprefixed attribute names are never expanded; unprefixed - element type names are expanded only if there is a default - namespace. The expanded name is the concatenation of the namespace - URI, the namespace separator character, and the local part of the - name. If the namespace separator is '\0' then the namespace URI - and the local part will be concatenated without any separator. - It is a programming error to use the separator '\0' with namespace - triplets (see XML_SetReturnNSTriplet). -*/ -XMLPARSEAPI(XML_Parser) -XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); - - -/* Constructs a new parser using the memory management suite referred to - by memsuite. If memsuite is NULL, then use the standard library memory - suite. If namespaceSeparator is non-NULL it creates a parser with - namespace processing as described above. The character pointed at - will serve as the namespace separator. - - All further memory operations used for the created parser will come from - the given suite. -*/ -XMLPARSEAPI(XML_Parser) -XML_ParserCreate_MM(const XML_Char *encoding, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *namespaceSeparator); - -/* Prepare a parser object to be re-used. This is particularly - valuable when memory allocation overhead is disproportionatly high, - such as when a large number of small documnents need to be parsed. - All handlers are cleared from the parser, except for the - unknownEncodingHandler. The parser's external state is re-initialized - except for the values of ns and ns_triplets. - - Added in Expat 1.95.3. -*/ -XMLPARSEAPI(XML_Bool) -XML_ParserReset(XML_Parser parser, const XML_Char *encoding); - -/* atts is array of name/value pairs, terminated by 0; - names and values are 0 terminated. -*/ -typedef void (XMLCALL *XML_StartElementHandler) (void *userData, - const XML_Char *name, - const XML_Char **atts); - -typedef void (XMLCALL *XML_EndElementHandler) (void *userData, - const XML_Char *name); - - -/* s is not 0 terminated. */ -typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, - const XML_Char *s, - int len); - -/* target and data are 0 terminated */ -typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( - void *userData, - const XML_Char *target, - const XML_Char *data); - -/* data is 0 terminated */ -typedef void (XMLCALL *XML_CommentHandler) (void *userData, - const XML_Char *data); - -typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); -typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); - -/* This is called for any characters in the XML document for which - there is no applicable handler. This includes both characters that - are part of markup which is of a kind that is not reported - (comments, markup declarations), or characters that are part of a - construct which could be reported but for which no handler has been - supplied. The characters are passed exactly as they were in the XML - document except that they will be encoded in UTF-8 or UTF-16. - Line boundaries are not normalized. Note that a byte order mark - character is not passed to the default handler. There are no - guarantees about how characters are divided between calls to the - default handler: for example, a comment might be split between - multiple calls. -*/ -typedef void (XMLCALL *XML_DefaultHandler) (void *userData, - const XML_Char *s, - int len); - -/* This is called for the start of the DOCTYPE declaration, before - any DTD or internal subset is parsed. -*/ -typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( - void *userData, - const XML_Char *doctypeName, - const XML_Char *sysid, - const XML_Char *pubid, - int has_internal_subset); - -/* This is called for the start of the DOCTYPE declaration when the - closing > is encountered, but after processing any external - subset. -*/ -typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); - -/* This is called for entity declarations. The is_parameter_entity - argument will be non-zero if the entity is a parameter entity, zero - otherwise. - - For internal entities (<!ENTITY foo "bar">), value will - be non-NULL and systemId, publicID, and notationName will be NULL. - The value string is NOT nul-terminated; the length is provided in - the value_length argument. Since it is legal to have zero-length - values, do not use this argument to test for internal entities. - - For external entities, value will be NULL and systemId will be - non-NULL. The publicId argument will be NULL unless a public - identifier was provided. The notationName argument will have a - non-NULL value only for unparsed entity declarations. - - Note that is_parameter_entity can't be changed to XML_Bool, since - that would break binary compatibility. -*/ -typedef void (XMLCALL *XML_EntityDeclHandler) ( - void *userData, - const XML_Char *entityName, - int is_parameter_entity, - const XML_Char *value, - int value_length, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); - -XMLPARSEAPI(void) -XML_SetEntityDeclHandler(XML_Parser parser, - XML_EntityDeclHandler handler); - -/* OBSOLETE -- OBSOLETE -- OBSOLETE - This handler has been superceded by the EntityDeclHandler above. - It is provided here for backward compatibility. - - This is called for a declaration of an unparsed (NDATA) entity. - The base argument is whatever was set by XML_SetBase. The - entityName, systemId and notationName arguments will never be - NULL. The other arguments may be. -*/ -typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( - void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); - -/* This is called for a declaration of notation. The base argument is - whatever was set by XML_SetBase. The notationName will never be - NULL. The other arguments can be. -*/ -typedef void (XMLCALL *XML_NotationDeclHandler) ( - void *userData, - const XML_Char *notationName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); - -/* When namespace processing is enabled, these are called once for - each namespace declaration. The call to the start and end element - handlers occur between the calls to the start and end namespace - declaration handlers. For an xmlns attribute, prefix will be - NULL. For an xmlns="" attribute, uri will be NULL. -*/ -typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( - void *userData, - const XML_Char *prefix, - const XML_Char *uri); - -typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( - void *userData, - const XML_Char *prefix); - -/* This is called if the document is not standalone, that is, it has an - external subset or a reference to a parameter entity, but does not - have standalone="yes". If this handler returns XML_STATUS_ERROR, - then processing will not continue, and the parser will return a - XML_ERROR_NOT_STANDALONE error. - If parameter entity parsing is enabled, then in addition to the - conditions above this handler will only be called if the referenced - entity was actually read. -*/ -typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); - -/* This is called for a reference to an external parsed general - entity. The referenced entity is not automatically parsed. The - application can parse it immediately or later using - XML_ExternalEntityParserCreate. - - The parser argument is the parser parsing the entity containing the - reference; it can be passed as the parser argument to - XML_ExternalEntityParserCreate. The systemId argument is the - system identifier as specified in the entity declaration; it will - not be NULL. - - The base argument is the system identifier that should be used as - the base for resolving systemId if systemId was relative; this is - set by XML_SetBase; it may be NULL. - - The publicId argument is the public identifier as specified in the - entity declaration, or NULL if none was specified; the whitespace - in the public identifier will have been normalized as required by - the XML spec. - - The context argument specifies the parsing context in the format - expected by the context argument to XML_ExternalEntityParserCreate; - context is valid only until the handler returns, so if the - referenced entity is to be parsed later, it must be copied. - context is NULL only when the entity is a parameter entity. - - The handler should return XML_STATUS_ERROR if processing should not - continue because of a fatal error in the handling of the external - entity. In this case the calling parser will return an - XML_ERROR_EXTERNAL_ENTITY_HANDLING error. - - Note that unlike other handlers the first argument is the parser, - not userData. -*/ -typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( - XML_Parser parser, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); - -/* This is called in two situations: - 1) An entity reference is encountered for which no declaration - has been read *and* this is not an error. - 2) An internal entity reference is read, but not expanded, because - XML_SetDefaultHandler has been called. - Note: skipped parameter entities in declarations and skipped general - entities in attribute values cannot be reported, because - the event would be out of sync with the reporting of the - declarations or attribute values -*/ -typedef void (XMLCALL *XML_SkippedEntityHandler) ( - void *userData, - const XML_Char *entityName, - int is_parameter_entity); - -/* This structure is filled in by the XML_UnknownEncodingHandler to - provide information to the parser about encodings that are unknown - to the parser. - - The map[b] member gives information about byte sequences whose - first byte is b. - - If map[b] is c where c is >= 0, then b by itself encodes the - Unicode scalar value c. - - If map[b] is -1, then the byte sequence is malformed. - - If map[b] is -n, where n >= 2, then b is the first byte of an - n-byte sequence that encodes a single Unicode scalar value. - - The data member will be passed as the first argument to the convert - function. - - The convert function is used to convert multibyte sequences; s will - point to a n-byte sequence where map[(unsigned char)*s] == -n. The - convert function must return the Unicode scalar value represented - by this byte sequence or -1 if the byte sequence is malformed. - - The convert function may be NULL if the encoding is a single-byte - encoding, that is if map[b] >= -1 for all bytes b. - - When the parser is finished with the encoding, then if release is - not NULL, it will call release passing it the data member; once - release has been called, the convert function will not be called - again. - - Expat places certain restrictions on the encodings that are supported - using this mechanism. - - 1. Every ASCII character that can appear in a well-formed XML document, - other than the characters - - $@\^`{}~ - - must be represented by a single byte, and that byte must be the - same byte that represents that character in ASCII. - - 2. No character may require more than 4 bytes to encode. - - 3. All characters encoded must have Unicode scalar values <= - 0xFFFF, (i.e., characters that would be encoded by surrogates in - UTF-16 are not allowed). Note that this restriction doesn't - apply to the built-in support for UTF-8 and UTF-16. - - 4. No Unicode character may be encoded by more than one distinct - sequence of bytes. -*/ -typedef struct { - int map[256]; - void *data; - int (XMLCALL *convert)(void *data, const char *s); - void (XMLCALL *release)(void *data); -} XML_Encoding; - -/* This is called for an encoding that is unknown to the parser. - - The encodingHandlerData argument is that which was passed as the - second argument to XML_SetUnknownEncodingHandler. - - The name argument gives the name of the encoding as specified in - the encoding declaration. - - If the callback can provide information about the encoding, it must - fill in the XML_Encoding structure, and return XML_STATUS_OK. - Otherwise it must return XML_STATUS_ERROR. - - If info does not describe a suitable encoding, then the parser will - return an XML_UNKNOWN_ENCODING error. -*/ -typedef int (XMLCALL *XML_UnknownEncodingHandler) ( - void *encodingHandlerData, - const XML_Char *name, - XML_Encoding *info); - -XMLPARSEAPI(void) -XML_SetElementHandler(XML_Parser parser, - XML_StartElementHandler start, - XML_EndElementHandler end); - -XMLPARSEAPI(void) -XML_SetStartElementHandler(XML_Parser parser, - XML_StartElementHandler handler); - -XMLPARSEAPI(void) -XML_SetEndElementHandler(XML_Parser parser, - XML_EndElementHandler handler); - -XMLPARSEAPI(void) -XML_SetCharacterDataHandler(XML_Parser parser, - XML_CharacterDataHandler handler); - -XMLPARSEAPI(void) -XML_SetProcessingInstructionHandler(XML_Parser parser, - XML_ProcessingInstructionHandler handler); -XMLPARSEAPI(void) -XML_SetCommentHandler(XML_Parser parser, - XML_CommentHandler handler); - -XMLPARSEAPI(void) -XML_SetCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start, - XML_EndCdataSectionHandler end); - -XMLPARSEAPI(void) -XML_SetStartCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start); - -XMLPARSEAPI(void) -XML_SetEndCdataSectionHandler(XML_Parser parser, - XML_EndCdataSectionHandler end); - -/* This sets the default handler and also inhibits expansion of - internal entities. These entity references will be passed to the - default handler, or to the skipped entity handler, if one is set. -*/ -XMLPARSEAPI(void) -XML_SetDefaultHandler(XML_Parser parser, - XML_DefaultHandler handler); - -/* This sets the default handler but does not inhibit expansion of - internal entities. The entity reference will not be passed to the - default handler. -*/ -XMLPARSEAPI(void) -XML_SetDefaultHandlerExpand(XML_Parser parser, - XML_DefaultHandler handler); - -XMLPARSEAPI(void) -XML_SetDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start, - XML_EndDoctypeDeclHandler end); - -XMLPARSEAPI(void) -XML_SetStartDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start); - -XMLPARSEAPI(void) -XML_SetEndDoctypeDeclHandler(XML_Parser parser, - XML_EndDoctypeDeclHandler end); - -XMLPARSEAPI(void) -XML_SetUnparsedEntityDeclHandler(XML_Parser parser, - XML_UnparsedEntityDeclHandler handler); - -XMLPARSEAPI(void) -XML_SetNotationDeclHandler(XML_Parser parser, - XML_NotationDeclHandler handler); - -XMLPARSEAPI(void) -XML_SetNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end); - -XMLPARSEAPI(void) -XML_SetStartNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start); - -XMLPARSEAPI(void) -XML_SetEndNamespaceDeclHandler(XML_Parser parser, - XML_EndNamespaceDeclHandler end); - -XMLPARSEAPI(void) -XML_SetNotStandaloneHandler(XML_Parser parser, - XML_NotStandaloneHandler handler); - -XMLPARSEAPI(void) -XML_SetExternalEntityRefHandler(XML_Parser parser, - XML_ExternalEntityRefHandler handler); - -/* If a non-NULL value for arg is specified here, then it will be - passed as the first argument to the external entity ref handler - instead of the parser object. -*/ -XMLPARSEAPI(void) -XML_SetExternalEntityRefHandlerArg(XML_Parser parser, - void *arg); - -XMLPARSEAPI(void) -XML_SetSkippedEntityHandler(XML_Parser parser, - XML_SkippedEntityHandler handler); - -XMLPARSEAPI(void) -XML_SetUnknownEncodingHandler(XML_Parser parser, - XML_UnknownEncodingHandler handler, - void *encodingHandlerData); - -/* This can be called within a handler for a start element, end - element, processing instruction or character data. It causes the - corresponding markup to be passed to the default handler. -*/ -XMLPARSEAPI(void) -XML_DefaultCurrent(XML_Parser parser); - -/* If do_nst is non-zero, and namespace processing is in effect, and - a name has a prefix (i.e. an explicit namespace qualifier) then - that name is returned as a triplet in a single string separated by - the separator character specified when the parser was created: URI - + sep + local_name + sep + prefix. - - If do_nst is zero, then namespace information is returned in the - default manner (URI + sep + local_name) whether or not the name - has a prefix. - - Note: Calling XML_SetReturnNSTriplet after XML_Parse or - XML_ParseBuffer has no effect. -*/ - -XMLPARSEAPI(void) -XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); - -/* This value is passed as the userData argument to callbacks. */ -XMLPARSEAPI(void) -XML_SetUserData(XML_Parser parser, void *userData); - -/* Returns the last value set by XML_SetUserData or NULL. */ -#define XML_GetUserData(parser) (*(void **)(parser)) - -/* This is equivalent to supplying an encoding argument to - XML_ParserCreate. On success XML_SetEncoding returns non-zero, - zero otherwise. - Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer - has no effect and returns XML_STATUS_ERROR. -*/ -XMLPARSEAPI(enum XML_Status) -XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); - -/* If this function is called, then the parser will be passed as the - first argument to callbacks instead of userData. The userData will - still be accessible using XML_GetUserData. -*/ -XMLPARSEAPI(void) -XML_UseParserAsHandlerArg(XML_Parser parser); - -/* If useDTD == XML_TRUE is passed to this function, then the parser - will assume that there is an external subset, even if none is - specified in the document. In such a case the parser will call the - externalEntityRefHandler with a value of NULL for the systemId - argument (the publicId and context arguments will be NULL as well). - Note: For the purpose of checking WFC: Entity Declared, passing - useDTD == XML_TRUE will make the parser behave as if the document - had a DTD with an external subset. - Note: If this function is called, then this must be done before - the first call to XML_Parse or XML_ParseBuffer, since it will - have no effect after that. Returns - XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. - Note: If the document does not have a DOCTYPE declaration at all, - then startDoctypeDeclHandler and endDoctypeDeclHandler will not - be called, despite an external subset being parsed. - Note: If XML_DTD is not defined when Expat is compiled, returns - XML_ERROR_FEATURE_REQUIRES_XML_DTD. -*/ -XMLPARSEAPI(enum XML_Error) -XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); - - -/* Sets the base to be used for resolving relative URIs in system - identifiers in declarations. Resolving relative identifiers is - left to the application: this value will be passed through as the - base argument to the XML_ExternalEntityRefHandler, - XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base - argument will be copied. Returns XML_STATUS_ERROR if out of memory, - XML_STATUS_OK otherwise. -*/ -XMLPARSEAPI(enum XML_Status) -XML_SetBase(XML_Parser parser, const XML_Char *base); - -XMLPARSEAPI(const XML_Char *) -XML_GetBase(XML_Parser parser); - -/* Returns the number of the attribute/value pairs passed in last call - to the XML_StartElementHandler that were specified in the start-tag - rather than defaulted. Each attribute/value pair counts as 2; thus - this correspondds to an index into the atts array passed to the - XML_StartElementHandler. -*/ -XMLPARSEAPI(int) -XML_GetSpecifiedAttributeCount(XML_Parser parser); - -/* Returns the index of the ID attribute passed in the last call to - XML_StartElementHandler, or -1 if there is no ID attribute. Each - attribute/value pair counts as 2; thus this correspondds to an - index into the atts array passed to the XML_StartElementHandler. -*/ -XMLPARSEAPI(int) -XML_GetIdAttributeIndex(XML_Parser parser); - -/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is - detected. The last call to XML_Parse must have isFinal true; len - may be zero for this call (or any other). - - Though the return values for these functions has always been - described as a Boolean value, the implementation, at least for the - 1.95.x series, has always returned exactly one of the XML_Status - values. -*/ -XMLPARSEAPI(enum XML_Status) -XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); - -XMLPARSEAPI(void *) -XML_GetBuffer(XML_Parser parser, int len); - -XMLPARSEAPI(enum XML_Status) -XML_ParseBuffer(XML_Parser parser, int len, int isFinal); - -/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. - Must be called from within a call-back handler, except when aborting - (resumable = 0) an already suspended parser. Some call-backs may - still follow because they would otherwise get lost. Examples: - - endElementHandler() for empty elements when stopped in - startElementHandler(), - - endNameSpaceDeclHandler() when stopped in endElementHandler(), - and possibly others. - - Can be called from most handlers, including DTD related call-backs, - except when parsing an external parameter entity and resumable != 0. - Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. - Possible error codes: - - XML_ERROR_SUSPENDED: when suspending an already suspended parser. - - XML_ERROR_FINISHED: when the parser has already finished. - - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. - - When resumable != 0 (true) then parsing is suspended, that is, - XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. - Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() - return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. - - *Note*: - This will be applied to the current parser instance only, that is, if - there is a parent parser then it will continue parsing when the - externalEntityRefHandler() returns. It is up to the implementation of - the externalEntityRefHandler() to call XML_StopParser() on the parent - parser (recursively), if one wants to stop parsing altogether. - - When suspended, parsing can be resumed by calling XML_ResumeParser(). -*/ -XMLPARSEAPI(enum XML_Status) -XML_StopParser(XML_Parser parser, XML_Bool resumable); - -/* Resumes parsing after it has been suspended with XML_StopParser(). - Must not be called from within a handler call-back. Returns same - status codes as XML_Parse() or XML_ParseBuffer(). - Additional error code XML_ERROR_NOT_SUSPENDED possible. - - *Note*: - This must be called on the most deeply nested child parser instance - first, and on its parent parser only after the child parser has finished, - to be applied recursively until the document entity's parser is restarted. - That is, the parent parser will not resume by itself and it is up to the - application to call XML_ResumeParser() on it at the appropriate moment. -*/ -XMLPARSEAPI(enum XML_Status) -XML_ResumeParser(XML_Parser parser); - -enum XML_Parsing { - XML_INITIALIZED, - XML_PARSING, - XML_FINISHED, - XML_SUSPENDED -}; - -typedef struct { - enum XML_Parsing parsing; - XML_Bool finalBuffer; -} XML_ParsingStatus; - -/* Returns status of parser with respect to being initialized, parsing, - finished, or suspended and processing the final buffer. - XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, - XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED -*/ -XMLPARSEAPI(void) -XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); - -/* Creates an XML_Parser object that can parse an external general - entity; context is a '\0'-terminated string specifying the parse - context; encoding is a '\0'-terminated string giving the name of - the externally specified encoding, or NULL if there is no - externally specified encoding. The context string consists of a - sequence of tokens separated by formfeeds (\f); a token consisting - of a name specifies that the general entity of the name is open; a - token of the form prefix=uri specifies the namespace for a - particular prefix; a token of the form =uri specifies the default - namespace. This can be called at any point after the first call to - an ExternalEntityRefHandler so longer as the parser has not yet - been freed. The new parser is completely independent and may - safely be used in a separate thread. The handlers and userData are - initialized from the parser argument. Returns NULL if out of memory. - Otherwise returns a new XML_Parser object. -*/ -XMLPARSEAPI(XML_Parser) -XML_ExternalEntityParserCreate(XML_Parser parser, - const XML_Char *context, - const XML_Char *encoding); - -enum XML_ParamEntityParsing { - XML_PARAM_ENTITY_PARSING_NEVER, - XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, - XML_PARAM_ENTITY_PARSING_ALWAYS -}; - -/* Controls parsing of parameter entities (including the external DTD - subset). If parsing of parameter entities is enabled, then - references to external parameter entities (including the external - DTD subset) will be passed to the handler set with - XML_SetExternalEntityRefHandler. The context passed will be 0. - - Unlike external general entities, external parameter entities can - only be parsed synchronously. If the external parameter entity is - to be parsed, it must be parsed during the call to the external - entity ref handler: the complete sequence of - XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and - XML_ParserFree calls must be made during this call. After - XML_ExternalEntityParserCreate has been called to create the parser - for the external parameter entity (context must be 0 for this - call), it is illegal to make any calls on the old parser until - XML_ParserFree has been called on the newly created parser. - If the library has been compiled without support for parameter - entity parsing (ie without XML_DTD being defined), then - XML_SetParamEntityParsing will return 0 if parsing of parameter - entities is requested; otherwise it will return non-zero. - Note: If XML_SetParamEntityParsing is called after XML_Parse or - XML_ParseBuffer, then it has no effect and will always return 0. -*/ -XMLPARSEAPI(int) -XML_SetParamEntityParsing(XML_Parser parser, - enum XML_ParamEntityParsing parsing); - -/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then - XML_GetErrorCode returns information about the error. -*/ -XMLPARSEAPI(enum XML_Error) -XML_GetErrorCode(XML_Parser parser); - -/* These functions return information about the current parse - location. They may be called from any callback called to report - some parse event; in this case the location is the location of the - first of the sequence of characters that generated the event. When - called from callbacks generated by declarations in the document - prologue, the location identified isn't as neatly defined, but will - be within the relevant markup. When called outside of the callback - functions, the position indicated will be just past the last parse - event (regardless of whether there was an associated callback). - - They may also be called after returning from a call to XML_Parse - or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then - the location is the location of the character at which the error - was detected; otherwise the location is the location of the last - parse event, as described above. -*/ -XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); -XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); -XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); - -/* Return the number of bytes in the current event. - Returns 0 if the event is in an internal entity. -*/ -XMLPARSEAPI(int) -XML_GetCurrentByteCount(XML_Parser parser); - -/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets - the integer pointed to by offset to the offset within this buffer - of the current parse position, and sets the integer pointed to by size - to the size of this buffer (the number of input bytes). Otherwise - returns a NULL pointer. Also returns a NULL pointer if a parse isn't - active. - - NOTE: The character pointer returned should not be used outside - the handler that makes the call. -*/ -XMLPARSEAPI(const char *) -XML_GetInputContext(XML_Parser parser, - int *offset, - int *size); - -/* For backwards compatibility with previous versions. */ -#define XML_GetErrorLineNumber XML_GetCurrentLineNumber -#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber -#define XML_GetErrorByteIndex XML_GetCurrentByteIndex - -/* Frees the content model passed to the element declaration handler */ -XMLPARSEAPI(void) -XML_FreeContentModel(XML_Parser parser, XML_Content *model); - -/* Exposing the memory handling functions used in Expat */ -XMLPARSEAPI(void *) -XML_MemMalloc(XML_Parser parser, size_t size); - -XMLPARSEAPI(void *) -XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); - -XMLPARSEAPI(void) -XML_MemFree(XML_Parser parser, void *ptr); - -/* Frees memory used by the parser. */ -XMLPARSEAPI(void) -XML_ParserFree(XML_Parser parser); - -/* Returns a string describing the error. */ -XMLPARSEAPI(const XML_LChar *) -XML_ErrorString(enum XML_Error code); - -/* Return a string containing the version number of this expat */ -XMLPARSEAPI(const XML_LChar *) -XML_ExpatVersion(void); - -typedef struct { - int major; - int minor; - int micro; -} XML_Expat_Version; - -/* Return an XML_Expat_Version structure containing numeric version - number information for this version of expat. -*/ -XMLPARSEAPI(XML_Expat_Version) -XML_ExpatVersionInfo(void); - -/* Added in Expat 1.95.5. */ -enum XML_FeatureEnum { - XML_FEATURE_END = 0, - XML_FEATURE_UNICODE, - XML_FEATURE_UNICODE_WCHAR_T, - XML_FEATURE_DTD, - XML_FEATURE_CONTEXT_BYTES, - XML_FEATURE_MIN_SIZE, - XML_FEATURE_SIZEOF_XML_CHAR, - XML_FEATURE_SIZEOF_XML_LCHAR, - XML_FEATURE_NS, - XML_FEATURE_LARGE_SIZE - /* Additional features must be added to the end of this enum. */ -}; - -typedef struct { - enum XML_FeatureEnum feature; - const XML_LChar *name; - long int value; -} XML_Feature; - -XMLPARSEAPI(const XML_Feature *) -XML_GetFeatureList(void); - - -/* Expat follows the GNU/Linux convention of odd number minor version for - beta/development releases and even number minor version for stable - releases. Micro is bumped with each release, and set to 0 with each - change to major or minor version. -*/ -#define XML_MAJOR_VERSION 2 -#define XML_MINOR_VERSION 0 -#define XML_MICRO_VERSION 1 - -#ifdef __cplusplus -} -#endif - -#endif /* not Expat_INCLUDED */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_config.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_config.h deleted file mode 100644 index 72bdec2..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_config.h +++ /dev/null @@ -1,104 +0,0 @@ -// No copyright notice; this file based on autogenerated header - -#ifndef THIRD_PARTY_EXPAT_V2_0_1_SOURCE_LIB_EXPAT_CONFIG_H__ -#define THIRD_PARTY_EXPAT_V2_0_1_SOURCE_LIB_EXPAT_CONFIG_H__ - -/* expat_config.h. Generated by configure. */ -/* expat_config.h.in. Generated from configure.in by autoheader. */ - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#if defined __BIG_ENDIAN__ // OSX and PPC => big endian; predefined gcc macro -#define BYTEORDER 4321 -#else -#define BYTEORDER 1234 -#endif - -/* Define to 1 if you have the `bcopy' function. */ -#define HAVE_BCOPY 1 - -/* Define to 1 if you have the <check.h> header file. */ -/* #undef HAVE_CHECK_H */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `getpagesize' function. */ -#define HAVE_GETPAGESIZE 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have a working `mmap' system call. */ -#define HAVE_MMAP 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "expat-bugs@mail.libexpat.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "expat" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "expat 1.95.8" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "expat" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.95.8" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* whether byteorder is bigendian */ -/* #undef WORDS_BIGENDIAN */ - -/* Define to specify how much context to retain around the current parse - point. */ -#define XML_CONTEXT_BYTES 1024 - -/* Define to make parameter entity parsing functionality available. */ -#define XML_DTD 1 - -/* Define to make XML Namespaces functionality available. */ -#define XML_NS 1 - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `long' if <sys/types.h> does not define. */ -/* #undef off_t */ - -/* Define to `unsigned' if <sys/types.h> does not define. */ -/* #undef size_t */ - -#endif // THIRD_PARTY_EXPAT_V2_0_1_SOURCE_LIB_EXPAT_CONFIG_H__ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_external.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_external.h deleted file mode 100644 index 2c03284..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_external.h +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#ifndef Expat_External_INCLUDED -#define Expat_External_INCLUDED 1 - -/* External API definitions */ - -#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) -#define XML_USE_MSC_EXTENSIONS 1 -#endif - -/* Expat tries very hard to make the API boundary very specifically - defined. There are two macros defined to control this boundary; - each of these can be defined before including this header to - achieve some different behavior, but doing so it not recommended or - tested frequently. - - XMLCALL - The calling convention to use for all calls across the - "library boundary." This will default to cdecl, and - try really hard to tell the compiler that's what we - want. - - XMLIMPORT - Whatever magic is needed to note that a function is - to be imported from a dynamically loaded library - (.dll, .so, or .sl, depending on your platform). - - The XMLCALL macro was added in Expat 1.95.7. The only one which is - expected to be directly useful in client code is XMLCALL. - - Note that on at least some Unix versions, the Expat library must be - compiled with the cdecl calling convention as the default since - system headers may assume the cdecl convention. -*/ -#ifndef XMLCALL -#if defined(_MSC_VER) -#define XMLCALL __cdecl -#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) -#define XMLCALL __attribute__((cdecl)) -#else -/* For any platform which uses this definition and supports more than - one calling convention, we need to extend this definition to - declare the convention used on that platform, if it's possible to - do so. - - If this is the case for your platform, please file a bug report - with information on how to identify your platform via the C - pre-processor and how to specify the same calling convention as the - platform's malloc() implementation. -*/ -#define XMLCALL -#endif -#endif /* not defined XMLCALL */ - - -#if !defined(XML_STATIC) && !defined(XMLIMPORT) -#ifndef XML_BUILDING_EXPAT -/* using Expat from an application */ - -#ifdef XML_USE_MSC_EXTENSIONS -#define XMLIMPORT __declspec(dllimport) -#endif - -#endif -#endif /* not defined XML_STATIC */ - - -/* If we didn't define it above, define it away: */ -#ifndef XMLIMPORT -#define XMLIMPORT -#endif - - -#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef XML_UNICODE_WCHAR_T -#define XML_UNICODE -#endif - -#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ -#ifdef XML_UNICODE_WCHAR_T -typedef wchar_t XML_Char; -typedef wchar_t XML_LChar; -#else -typedef unsigned short XML_Char; -typedef char XML_LChar; -#endif /* XML_UNICODE_WCHAR_T */ -#else /* Information is UTF-8 encoded. */ -typedef char XML_Char; -typedef char XML_LChar; -#endif /* XML_UNICODE */ - -#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ -#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 -typedef __int64 XML_Index; -typedef unsigned __int64 XML_Size; -#else -typedef long long XML_Index; -typedef unsigned long long XML_Size; -#endif -#else -typedef long XML_Index; -typedef unsigned long XML_Size; -#endif /* XML_LARGE_SIZE */ - -#ifdef __cplusplus -} -#endif - -#endif /* not Expat_External_INCLUDED */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_static.dsp b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_static.dsp deleted file mode 100644 index a67897b..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expat_static.dsp +++ /dev/null @@ -1,162 +0,0 @@ -# Microsoft Developer Studio Project File - Name="expat_static" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=expat_static - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "expat_static.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "expat_static.mak" CFG="expat_static - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "expat_static - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "expat_static - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "expat_static - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "expat_static___Win32_Release" -# PROP BASE Intermediate_Dir "expat_static___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\win32\bin\Release" -# PROP Intermediate_Dir "..\win32\tmp\Release_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "COMPILED_FROM_DSP" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x1009 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\win32\bin\Release/libexpatMT.lib" - -!ELSEIF "$(CFG)" == "expat_static - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "expat_static___Win32_Debug" -# PROP BASE Intermediate_Dir "expat_static___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\win32\bin\Debug" -# PROP Intermediate_Dir "..\win32\tmp\Debug_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "COMPILED_FROM_DSP" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x1009 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\win32\bin\Debug\libexpatMT.lib" - -!ENDIF - -# Begin Target - -# Name "expat_static - Win32 Release" -# Name "expat_static - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\xmlparse.c -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_ns.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\ascii.h -# End Source File -# Begin Source File - -SOURCE=.\asciitab.h -# End Source File -# Begin Source File - -SOURCE=.\expat.h -# End Source File -# Begin Source File - -SOURCE=.\expat_external.h -# End Source File -# Begin Source File - -SOURCE=.\iasciitab.h -# End Source File -# Begin Source File - -SOURCE=.\internal.h -# End Source File -# Begin Source File - -SOURCE=.\latin1tab.h -# End Source File -# Begin Source File - -SOURCE=.\nametab.h -# End Source File -# Begin Source File - -SOURCE=.\utf8tab.h -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.h -# End Source File -# End Group -# End Target -# End Project diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expatw.dsp b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expatw.dsp deleted file mode 100644 index 46db7d6..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expatw.dsp +++ /dev/null @@ -1,185 +0,0 @@ -# Microsoft Developer Studio Project File - Name="expatw" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=expatw - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "expatw.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "expatw.mak" CFG="expatw - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "expatw - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "expatw - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "expatw - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\win32\bin\Release" -# PROP Intermediate_Dir "..\win32\tmp\Release-w" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPAT_EXPORTS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "COMPILED_FROM_DSP" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XML_UNICODE_WCHAR_T" /FD /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none /machine:I386 /out:"..\win32\bin\Release/libexpatw.dll" - -!ELSEIF "$(CFG)" == "expatw - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\win32\bin\Debug" -# PROP Intermediate_Dir "..\win32\tmp\Debug-w" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPAT_EXPORTS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /D "_DEBUG" /D "COMPILED_FROM_DSP" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XML_UNICODE_WCHAR_T" /FR /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none /debug /machine:I386 /out:"..\win32\bin\Debug/libexpatw.dll" - -!ENDIF - -# Begin Target - -# Name "expatw - Win32 Release" -# Name "expatw - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\libexpatw.def -# End Source File -# Begin Source File - -SOURCE=.\xmlparse.c - -!IF "$(CFG)" == "expatw - Win32 Release" - -!ELSEIF "$(CFG)" == "expatw - Win32 Debug" - -# ADD CPP /GX- /Od - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_ns.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\ascii.h -# End Source File -# Begin Source File - -SOURCE=.\asciitab.h -# End Source File -# Begin Source File - -SOURCE=.\expat.h -# End Source File -# Begin Source File - -SOURCE=.\expat_external.h -# End Source File -# Begin Source File - -SOURCE=.\iasciitab.h -# End Source File -# Begin Source File - -SOURCE=.\internal.h -# End Source File -# Begin Source File - -SOURCE=.\latin1tab.h -# End Source File -# Begin Source File - -SOURCE=.\nametab.h -# End Source File -# Begin Source File - -SOURCE=.\utf8tab.h -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expatw_static.dsp b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expatw_static.dsp deleted file mode 100644 index d28632c..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/expatw_static.dsp +++ /dev/null @@ -1,162 +0,0 @@ -# Microsoft Developer Studio Project File - Name="expatw_static" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=expatw_static - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "expatw_static.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "expatw_static.mak" CFG="expatw_static - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "expatw_static - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "expatw_static - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "expatw_static - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "expatw_static___Win32_Release" -# PROP BASE Intermediate_Dir "expatw_static___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\win32\bin\Release" -# PROP Intermediate_Dir "..\win32\tmp\Release-w_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "COMPILED_FROM_DSP" /D "XML_UNICODE_WCHAR_T" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x1009 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\win32\bin\Release\libexpatwMT.lib" - -!ELSEIF "$(CFG)" == "expatw_static - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "expatw_static___Win32_Debug" -# PROP BASE Intermediate_Dir "expatw_static___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\win32\bin\Debug" -# PROP Intermediate_Dir "..\win32\tmp\Debug-w_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /D "COMPILED_FROM_DSP" /D "XML_UNICODE_WCHAR_T" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x1009 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\win32\bin\Debug\libexpatwMT.lib" - -!ENDIF - -# Begin Target - -# Name "expatw_static - Win32 Release" -# Name "expatw_static - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\xmlparse.c -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.c -# End Source File -# Begin Source File - -SOURCE=.\xmltok_ns.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\ascii.h -# End Source File -# Begin Source File - -SOURCE=.\asciitab.h -# End Source File -# Begin Source File - -SOURCE=.\expat.h -# End Source File -# Begin Source File - -SOURCE=.\expat_external.h -# End Source File -# Begin Source File - -SOURCE=.\iasciitab.h -# End Source File -# Begin Source File - -SOURCE=.\internal.h -# End Source File -# Begin Source File - -SOURCE=.\latin1tab.h -# End Source File -# Begin Source File - -SOURCE=.\nametab.h -# End Source File -# Begin Source File - -SOURCE=.\utf8tab.h -# End Source File -# Begin Source File - -SOURCE=.\xmlrole.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok.h -# End Source File -# Begin Source File - -SOURCE=.\xmltok_impl.h -# End Source File -# End Group -# End Target -# End Project diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/iasciitab.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/iasciitab.h deleted file mode 100644 index 24a1d5c..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/iasciitab.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ -/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, -/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, -/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, -/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, -/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, -/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, -/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, -/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, -/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, -/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, -/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/internal.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/internal.h deleted file mode 100644 index dd54548..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/internal.h +++ /dev/null @@ -1,73 +0,0 @@ -/* internal.h - - Internal definitions used by Expat. This is not needed to compile - client code. - - The following calling convention macros are defined for frequently - called functions: - - FASTCALL - Used for those internal functions that have a simple - body and a low number of arguments and local variables. - - PTRCALL - Used for functions called though function pointers. - - PTRFASTCALL - Like PTRCALL, but for low number of arguments. - - inline - Used for selected internal functions for which inlining - may improve performance on some platforms. - - Note: Use of these macros is based on judgement, not hard rules, - and therefore subject to change. -*/ - -#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__) -/* We'll use this version by default only where we know it helps. - - regparm() generates warnings on Solaris boxes. See SF bug #692878. - - Instability reported with egcs on a RedHat Linux 7.3. - Let's comment out: - #define FASTCALL __attribute__((stdcall, regparm(3))) - and let's try this: -*/ -#define FASTCALL __attribute__((regparm(3))) -#define PTRFASTCALL __attribute__((regparm(3))) -#endif - -/* Using __fastcall seems to have an unexpected negative effect under - MS VC++, especially for function pointers, so we won't use it for - now on that platform. It may be reconsidered for a future release - if it can be made more effective. - Likely reason: __fastcall on Windows is like stdcall, therefore - the compiler cannot perform stack optimizations for call clusters. -*/ - -/* Make sure all of these are defined if they aren't already. */ - -#ifndef FASTCALL -#define FASTCALL -#endif - -#ifndef PTRCALL -#define PTRCALL -#endif - -#ifndef PTRFASTCALL -#define PTRFASTCALL -#endif - -#ifndef XML_MIN_SIZE -#if !defined(__cplusplus) && !defined(inline) -#ifdef __GNUC__ -#define inline __inline -#endif /* __GNUC__ */ -#endif -#endif /* XML_MIN_SIZE */ - -#ifdef __cplusplus -#define inline inline -#else -#ifndef inline -#define inline -#endif -#endif diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/latin1tab.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/latin1tab.h deleted file mode 100644 index 53c25d7..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/latin1tab.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, -/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, -/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, -/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/libexpat.def b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/libexpat.def deleted file mode 100644 index 3920bbc..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/libexpat.def +++ /dev/null @@ -1,73 +0,0 @@ -; DEF file for MS VC++ - -LIBRARY -EXPORTS - XML_DefaultCurrent @1 - XML_ErrorString @2 - XML_ExpatVersion @3 - XML_ExpatVersionInfo @4 - XML_ExternalEntityParserCreate @5 - XML_GetBase @6 - XML_GetBuffer @7 - XML_GetCurrentByteCount @8 - XML_GetCurrentByteIndex @9 - XML_GetCurrentColumnNumber @10 - XML_GetCurrentLineNumber @11 - XML_GetErrorCode @12 - XML_GetIdAttributeIndex @13 - XML_GetInputContext @14 - XML_GetSpecifiedAttributeCount @15 - XML_Parse @16 - XML_ParseBuffer @17 - XML_ParserCreate @18 - XML_ParserCreateNS @19 - XML_ParserCreate_MM @20 - XML_ParserFree @21 - XML_SetAttlistDeclHandler @22 - XML_SetBase @23 - XML_SetCdataSectionHandler @24 - XML_SetCharacterDataHandler @25 - XML_SetCommentHandler @26 - XML_SetDefaultHandler @27 - XML_SetDefaultHandlerExpand @28 - XML_SetDoctypeDeclHandler @29 - XML_SetElementDeclHandler @30 - XML_SetElementHandler @31 - XML_SetEncoding @32 - XML_SetEndCdataSectionHandler @33 - XML_SetEndDoctypeDeclHandler @34 - XML_SetEndElementHandler @35 - XML_SetEndNamespaceDeclHandler @36 - XML_SetEntityDeclHandler @37 - XML_SetExternalEntityRefHandler @38 - XML_SetExternalEntityRefHandlerArg @39 - XML_SetNamespaceDeclHandler @40 - XML_SetNotStandaloneHandler @41 - XML_SetNotationDeclHandler @42 - XML_SetParamEntityParsing @43 - XML_SetProcessingInstructionHandler @44 - XML_SetReturnNSTriplet @45 - XML_SetStartCdataSectionHandler @46 - XML_SetStartDoctypeDeclHandler @47 - XML_SetStartElementHandler @48 - XML_SetStartNamespaceDeclHandler @49 - XML_SetUnknownEncodingHandler @50 - XML_SetUnparsedEntityDeclHandler @51 - XML_SetUserData @52 - XML_SetXmlDeclHandler @53 - XML_UseParserAsHandlerArg @54 -; added with version 1.95.3 - XML_ParserReset @55 - XML_SetSkippedEntityHandler @56 -; added with version 1.95.5 - XML_GetFeatureList @57 - XML_UseForeignDTD @58 -; added with version 1.95.6 - XML_FreeContentModel @59 - XML_MemMalloc @60 - XML_MemRealloc @61 - XML_MemFree @62 -; added with version 1.95.8 - XML_StopParser @63 - XML_ResumeParser @64 - XML_GetParsingStatus @65 diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/libexpatw.def b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/libexpatw.def deleted file mode 100644 index 3920bbc..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/libexpatw.def +++ /dev/null @@ -1,73 +0,0 @@ -; DEF file for MS VC++ - -LIBRARY -EXPORTS - XML_DefaultCurrent @1 - XML_ErrorString @2 - XML_ExpatVersion @3 - XML_ExpatVersionInfo @4 - XML_ExternalEntityParserCreate @5 - XML_GetBase @6 - XML_GetBuffer @7 - XML_GetCurrentByteCount @8 - XML_GetCurrentByteIndex @9 - XML_GetCurrentColumnNumber @10 - XML_GetCurrentLineNumber @11 - XML_GetErrorCode @12 - XML_GetIdAttributeIndex @13 - XML_GetInputContext @14 - XML_GetSpecifiedAttributeCount @15 - XML_Parse @16 - XML_ParseBuffer @17 - XML_ParserCreate @18 - XML_ParserCreateNS @19 - XML_ParserCreate_MM @20 - XML_ParserFree @21 - XML_SetAttlistDeclHandler @22 - XML_SetBase @23 - XML_SetCdataSectionHandler @24 - XML_SetCharacterDataHandler @25 - XML_SetCommentHandler @26 - XML_SetDefaultHandler @27 - XML_SetDefaultHandlerExpand @28 - XML_SetDoctypeDeclHandler @29 - XML_SetElementDeclHandler @30 - XML_SetElementHandler @31 - XML_SetEncoding @32 - XML_SetEndCdataSectionHandler @33 - XML_SetEndDoctypeDeclHandler @34 - XML_SetEndElementHandler @35 - XML_SetEndNamespaceDeclHandler @36 - XML_SetEntityDeclHandler @37 - XML_SetExternalEntityRefHandler @38 - XML_SetExternalEntityRefHandlerArg @39 - XML_SetNamespaceDeclHandler @40 - XML_SetNotStandaloneHandler @41 - XML_SetNotationDeclHandler @42 - XML_SetParamEntityParsing @43 - XML_SetProcessingInstructionHandler @44 - XML_SetReturnNSTriplet @45 - XML_SetStartCdataSectionHandler @46 - XML_SetStartDoctypeDeclHandler @47 - XML_SetStartElementHandler @48 - XML_SetStartNamespaceDeclHandler @49 - XML_SetUnknownEncodingHandler @50 - XML_SetUnparsedEntityDeclHandler @51 - XML_SetUserData @52 - XML_SetXmlDeclHandler @53 - XML_UseParserAsHandlerArg @54 -; added with version 1.95.3 - XML_ParserReset @55 - XML_SetSkippedEntityHandler @56 -; added with version 1.95.5 - XML_GetFeatureList @57 - XML_UseForeignDTD @58 -; added with version 1.95.6 - XML_FreeContentModel @59 - XML_MemMalloc @60 - XML_MemRealloc @61 - XML_MemFree @62 -; added with version 1.95.8 - XML_StopParser @63 - XML_ResumeParser @64 - XML_GetParsingStatus @65 diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/macconfig.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/macconfig.h deleted file mode 100644 index 2725caa..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/macconfig.h +++ /dev/null @@ -1,53 +0,0 @@ -/*================================================================ -** Copyright 2000, Clark Cooper -** All rights reserved. -** -** This is free software. You are permitted to copy, distribute, or modify -** it under the terms of the MIT/X license (contained in the COPYING file -** with this distribution.) -** -*/ - -#ifndef MACCONFIG_H -#define MACCONFIG_H - - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 4321 - -/* Define to 1 if you have the `bcopy' function. */ -#undef HAVE_BCOPY - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE - -/* Define to 1 if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* whether byteorder is bigendian */ -#define WORDS_BIGENDIAN - -/* Define to specify how much context to retain around the current parse - point. */ -#undef XML_CONTEXT_BYTES - -/* Define to make parameter entity parsing functionality available. */ -#define XML_DTD - -/* Define to make XML Namespaces functionality available. */ -#define XML_NS - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `long' if <sys/types.h> does not define. */ -#define off_t long - -/* Define to `unsigned' if <sys/types.h> does not define. */ -#undef size_t - - -#endif /* ifndef MACCONFIG_H */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/nametab.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/nametab.h deleted file mode 100644 index b05e62c..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/nametab.h +++ /dev/null @@ -1,150 +0,0 @@ -static const unsigned namingBitmap[] = { -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, -0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, -0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, -0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, -0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, -0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, -0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, -0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, -0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, -0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, -0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, -0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, -0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, -0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, -0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, -0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, -0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, -0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, -0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, -0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, -0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, -0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, -0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, -0x40000000, 0xF580C900, 0x00000007, 0x02010800, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, -0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, -0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, -0x00000000, 0x00004C40, 0x00000000, 0x00000000, -0x00000007, 0x00000000, 0x00000000, 0x00000000, -0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, -0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, -0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, -0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, -0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, -0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, -0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, -0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, -0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, -0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, -0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, -0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, -0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, -0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, -0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, -0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, -0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, -0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, -0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, -0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, -0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, -0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, -0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, -0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, -0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, -0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, -0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, -0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, -0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, -}; -static const unsigned char nmstrtPages[] = { -0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, -0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, -0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, -0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static const unsigned char namePages[] = { -0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, -0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, -0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, -0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/utf8tab.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/utf8tab.h deleted file mode 100644 index 7bb3e77..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/utf8tab.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - - -/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, -/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/watcomconfig.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/watcomconfig.h deleted file mode 100644 index 2f05e3f..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/watcomconfig.h +++ /dev/null @@ -1,47 +0,0 @@ -/* expat_config.h for use with Open Watcom 1.5 and above. */ - -#ifndef WATCOMCONFIG_H -#define WATCOMCONFIG_H - -#ifdef __NT__ -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#endif - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 1234 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "expat-bugs@mail.libexpat.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "expat" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "expat 2.0.0" - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "2.0.0" - -/* Define to specify how much context to retain around the current parse - point. */ -#define XML_CONTEXT_BYTES 1024 - -/* Define to make parameter entity parsing functionality available. */ -#define XML_DTD 1 - -/* Define to make XML Namespaces functionality available. */ -#define XML_NS 1 - -#endif - diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/winconfig.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/winconfig.h deleted file mode 100644 index 0f16ba5..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/winconfig.h +++ /dev/null @@ -1,32 +0,0 @@ -/*================================================================ -** Copyright 2000, Clark Cooper -** All rights reserved. -** -** This is free software. You are permitted to copy, distribute, or modify -** it under the terms of the MIT/X license (contained in the COPYING file -** with this distribution.) -*/ - -#ifndef WINCONFIG_H -#define WINCONFIG_H - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN - -#include <memory.h> -#include <string.h> - -#define XML_NS 1 -#define XML_DTD 1 -#define XML_CONTEXT_BYTES 1024 - -/* we will assume all Windows platforms are little endian */ -#define BYTEORDER 1234 - -/* Windows has memmove() available. */ -#define HAVE_MEMMOVE - -#endif /* ndef WINCONFIG_H */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlparse.c b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlparse.c deleted file mode 100644 index 94e31de..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlparse.c +++ /dev/null @@ -1,6287 +0,0 @@ -/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#include <stddef.h> -#include <string.h> /* memset(), memcpy() */ -#include <assert.h> - -#define XML_BUILDING_EXPAT 1 - -#ifdef COMPILED_FROM_DSP -#include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos4__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" -#elif defined(HAVE_EXPAT_CONFIG_H) -#include <expat_config.h> -#endif /* ndef COMPILED_FROM_DSP */ - -#include "ascii.h" -#include "expat.h" - -#ifdef XML_UNICODE -#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX -#define XmlConvert XmlUtf16Convert -#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding -#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS -#define XmlEncode XmlUtf16Encode -/* Using pointer subtraction to convert to integer type. */ -#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) -typedef unsigned short ICHAR; -#else -#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX -#define XmlConvert XmlUtf8Convert -#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding -#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS -#define XmlEncode XmlUtf8Encode -#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) -typedef char ICHAR; -#endif - - -#ifndef XML_NS - -#define XmlInitEncodingNS XmlInitEncoding -#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding -#undef XmlGetInternalEncodingNS -#define XmlGetInternalEncodingNS XmlGetInternalEncoding -#define XmlParseXmlDeclNS XmlParseXmlDecl - -#endif - -#ifdef XML_UNICODE - -#ifdef XML_UNICODE_WCHAR_T -#define XML_T(x) (const wchar_t)x -#define XML_L(x) L ## x -#else -#define XML_T(x) (const unsigned short)x -#define XML_L(x) x -#endif - -#else - -#define XML_T(x) x -#define XML_L(x) x - -#endif - -/* Round up n to be a multiple of sz, where sz is a power of 2. */ -#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) - -/* Handle the case where memmove() doesn't exist. */ -#ifndef HAVE_MEMMOVE -#ifdef HAVE_BCOPY -#define memmove(d,s,l) bcopy((s),(d),(l)) -#else -#error memmove does not exist on this platform, nor is a substitute available -#endif /* HAVE_BCOPY */ -#endif /* HAVE_MEMMOVE */ - -#include "internal.h" -#include "xmltok.h" -#include "xmlrole.h" - -typedef const XML_Char *KEY; - -typedef struct { - KEY name; -} NAMED; - -typedef struct { - NAMED **v; - unsigned char power; - size_t size; - size_t used; - const XML_Memory_Handling_Suite *mem; -} HASH_TABLE; - -/* Basic character hash algorithm, taken from Python's string hash: - h = h * 1000003 ^ character, the constant being a prime number. - -*/ -#ifdef XML_UNICODE -#define CHAR_HASH(h, c) \ - (((h) * 0xF4243) ^ (unsigned short)(c)) -#else -#define CHAR_HASH(h, c) \ - (((h) * 0xF4243) ^ (unsigned char)(c)) -#endif - -/* For probing (after a collision) we need a step size relative prime - to the hash table size, which is a power of 2. We use double-hashing, - since we can calculate a second hash value cheaply by taking those bits - of the first hash value that were discarded (masked out) when the table - index was calculated: index = hash & mask, where mask = table->size - 1. - We limit the maximum step size to table->size / 4 (mask >> 2) and make - it odd, since odd numbers are always relative prime to a power of 2. -*/ -#define SECOND_HASH(hash, mask, power) \ - ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) -#define PROBE_STEP(hash, mask, power) \ - ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) - -typedef struct { - NAMED **p; - NAMED **end; -} HASH_TABLE_ITER; - -#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ -#define INIT_DATA_BUF_SIZE 1024 -#define INIT_ATTS_SIZE 16 -#define INIT_ATTS_VERSION 0xFFFFFFFF -#define INIT_BLOCK_SIZE 1024 -#define INIT_BUFFER_SIZE 1024 - -#define EXPAND_SPARE 24 - -typedef struct binding { - struct prefix *prefix; - struct binding *nextTagBinding; - struct binding *prevPrefixBinding; - const struct attribute_id *attId; - XML_Char *uri; - int uriLen; - int uriAlloc; -} BINDING; - -typedef struct prefix { - const XML_Char *name; - BINDING *binding; -} PREFIX; - -typedef struct { - const XML_Char *str; - const XML_Char *localPart; - const XML_Char *prefix; - int strLen; - int uriLen; - int prefixLen; -} TAG_NAME; - -/* TAG represents an open element. - The name of the element is stored in both the document and API - encodings. The memory buffer 'buf' is a separately-allocated - memory area which stores the name. During the XML_Parse()/ - XMLParseBuffer() when the element is open, the memory for the 'raw' - version of the name (in the document encoding) is shared with the - document buffer. If the element is open across calls to - XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to - contain the 'raw' name as well. - - A parser re-uses these structures, maintaining a list of allocated - TAG objects in a free list. -*/ -typedef struct tag { - struct tag *parent; /* parent of this element */ - const char *rawName; /* tagName in the original encoding */ - int rawNameLength; - TAG_NAME name; /* tagName in the API encoding */ - char *buf; /* buffer for name components */ - char *bufEnd; /* end of the buffer */ - BINDING *bindings; -} TAG; - -typedef struct { - const XML_Char *name; - const XML_Char *textPtr; - int textLen; /* length in XML_Chars */ - int processed; /* # of processed bytes - when suspended */ - const XML_Char *systemId; - const XML_Char *base; - const XML_Char *publicId; - const XML_Char *notation; - XML_Bool open; - XML_Bool is_param; - XML_Bool is_internal; /* true if declared in internal subset outside PE */ -} ENTITY; - -typedef struct { - enum XML_Content_Type type; - enum XML_Content_Quant quant; - const XML_Char * name; - int firstchild; - int lastchild; - int childcnt; - int nextsib; -} CONTENT_SCAFFOLD; - -#define INIT_SCAFFOLD_ELEMENTS 32 - -typedef struct block { - struct block *next; - int size; - XML_Char s[1]; -} BLOCK; - -typedef struct { - BLOCK *blocks; - BLOCK *freeBlocks; - const XML_Char *end; - XML_Char *ptr; - XML_Char *start; - const XML_Memory_Handling_Suite *mem; -} STRING_POOL; - -/* The XML_Char before the name is used to determine whether - an attribute has been specified. */ -typedef struct attribute_id { - XML_Char *name; - PREFIX *prefix; - XML_Bool maybeTokenized; - XML_Bool xmlns; -} ATTRIBUTE_ID; - -typedef struct { - const ATTRIBUTE_ID *id; - XML_Bool isCdata; - const XML_Char *value; -} DEFAULT_ATTRIBUTE; - -typedef struct { - unsigned long version; - unsigned long hash; - const XML_Char *uriName; -} NS_ATT; - -typedef struct { - const XML_Char *name; - PREFIX *prefix; - const ATTRIBUTE_ID *idAtt; - int nDefaultAtts; - int allocDefaultAtts; - DEFAULT_ATTRIBUTE *defaultAtts; -} ELEMENT_TYPE; - -typedef struct { - HASH_TABLE generalEntities; - HASH_TABLE elementTypes; - HASH_TABLE attributeIds; - HASH_TABLE prefixes; - STRING_POOL pool; - STRING_POOL entityValuePool; - /* false once a parameter entity reference has been skipped */ - XML_Bool keepProcessing; - /* true once an internal or external PE reference has been encountered; - this includes the reference to an external subset */ - XML_Bool hasParamEntityRefs; - XML_Bool standalone; -#ifdef XML_DTD - /* indicates if external PE has been read */ - XML_Bool paramEntityRead; - HASH_TABLE paramEntities; -#endif /* XML_DTD */ - PREFIX defaultPrefix; - /* === scaffolding for building content model === */ - XML_Bool in_eldecl; - CONTENT_SCAFFOLD *scaffold; - unsigned contentStringLen; - unsigned scaffSize; - unsigned scaffCount; - int scaffLevel; - int *scaffIndex; -} DTD; - -typedef struct open_internal_entity { - const char *internalEventPtr; - const char *internalEventEndPtr; - struct open_internal_entity *next; - ENTITY *entity; - int startTagLevel; - XML_Bool betweenDecl; /* WFC: PE Between Declarations */ -} OPEN_INTERNAL_ENTITY; - -typedef enum XML_Error PTRCALL Processor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr); - -static Processor prologProcessor; -static Processor prologInitProcessor; -static Processor contentProcessor; -static Processor cdataSectionProcessor; -#ifdef XML_DTD -static Processor ignoreSectionProcessor; -static Processor externalParEntProcessor; -static Processor externalParEntInitProcessor; -static Processor entityValueProcessor; -static Processor entityValueInitProcessor; -#endif /* XML_DTD */ -static Processor epilogProcessor; -static Processor errorProcessor; -static Processor externalEntityInitProcessor; -static Processor externalEntityInitProcessor2; -static Processor externalEntityInitProcessor3; -static Processor externalEntityContentProcessor; -static Processor internalEntityProcessor; - -static enum XML_Error -handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); -static enum XML_Error -processXmlDecl(XML_Parser parser, int isGeneralTextEntity, - const char *s, const char *next); -static enum XML_Error -initializeEncoding(XML_Parser parser); -static enum XML_Error -doProlog(XML_Parser parser, const ENCODING *enc, const char *s, - const char *end, int tok, const char *next, const char **nextPtr, - XML_Bool haveMore); -static enum XML_Error -processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl); -static enum XML_Error -doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, - const char *start, const char *end, const char **endPtr, - XML_Bool haveMore); -static enum XML_Error -doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, - const char *end, const char **nextPtr, XML_Bool haveMore); -#ifdef XML_DTD -static enum XML_Error -doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, - const char *end, const char **nextPtr, XML_Bool haveMore); -#endif /* XML_DTD */ - -static enum XML_Error -storeAtts(XML_Parser parser, const ENCODING *, const char *s, - TAG_NAME *tagNamePtr, BINDING **bindingsPtr); -static enum XML_Error -addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, - const XML_Char *uri, BINDING **bindingsPtr); -static int -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, - XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser); -static enum XML_Error -storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, - const char *, const char *, STRING_POOL *); -static enum XML_Error -appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, - const char *, const char *, STRING_POOL *); -static ATTRIBUTE_ID * -getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static int -setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); -static enum XML_Error -storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static int -reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end); -static int -reportComment(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); -static void -reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, - const char *end); - -static const XML_Char * getContext(XML_Parser parser); -static XML_Bool -setContext(XML_Parser parser, const XML_Char *context); - -static void FASTCALL normalizePublicId(XML_Char *s); - -static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms); -/* do not call if parentParser != NULL */ -static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); -static void -dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); -static int -dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); -static int -copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); - -static NAMED * -lookup(HASH_TABLE *table, KEY name, size_t createSize); -static void FASTCALL -hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms); -static void FASTCALL hashTableClear(HASH_TABLE *); -static void FASTCALL hashTableDestroy(HASH_TABLE *); -static void FASTCALL -hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); -static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *); - -static void FASTCALL -poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms); -static void FASTCALL poolClear(STRING_POOL *); -static void FASTCALL poolDestroy(STRING_POOL *); -static XML_Char * -poolAppend(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end); -static XML_Char * -poolStoreString(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end); -static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); -static const XML_Char * FASTCALL -poolCopyString(STRING_POOL *pool, const XML_Char *s); -static const XML_Char * -poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); -static const XML_Char * FASTCALL -poolAppendString(STRING_POOL *pool, const XML_Char *s); - -static int FASTCALL nextScaffoldPart(XML_Parser parser); -static XML_Content * build_model(XML_Parser parser); -static ELEMENT_TYPE * -getElementType(XML_Parser parser, const ENCODING *enc, - const char *ptr, const char *end); - -static XML_Parser -parserCreate(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep, - DTD *dtd); -static void -parserInit(XML_Parser parser, const XML_Char *encodingName); - -#define poolStart(pool) ((pool)->start) -#define poolEnd(pool) ((pool)->ptr) -#define poolLength(pool) ((pool)->ptr - (pool)->start) -#define poolChop(pool) ((void)--(pool->ptr)) -#define poolLastChar(pool) (((pool)->ptr)[-1]) -#define poolDiscard(pool) ((pool)->ptr = (pool)->start) -#define poolFinish(pool) ((pool)->start = (pool)->ptr) -#define poolAppendChar(pool, c) \ - (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ - ? 0 \ - : ((*((pool)->ptr)++ = c), 1)) - -struct XML_ParserStruct { - /* The first member must be userData so that the XML_GetUserData - macro works. */ - void *m_userData; - void *m_handlerArg; - char *m_buffer; - const XML_Memory_Handling_Suite m_mem; - /* first character to be parsed */ - const char *m_bufferPtr; - /* past last character to be parsed */ - char *m_bufferEnd; - /* allocated end of buffer */ - const char *m_bufferLim; - XML_Index m_parseEndByteIndex; - const char *m_parseEndPtr; - XML_Char *m_dataBuf; - XML_Char *m_dataBufEnd; - XML_StartElementHandler m_startElementHandler; - XML_EndElementHandler m_endElementHandler; - XML_CharacterDataHandler m_characterDataHandler; - XML_ProcessingInstructionHandler m_processingInstructionHandler; - XML_CommentHandler m_commentHandler; - XML_StartCdataSectionHandler m_startCdataSectionHandler; - XML_EndCdataSectionHandler m_endCdataSectionHandler; - XML_DefaultHandler m_defaultHandler; - XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; - XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; - XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; - XML_NotationDeclHandler m_notationDeclHandler; - XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; - XML_NotStandaloneHandler m_notStandaloneHandler; - XML_ExternalEntityRefHandler m_externalEntityRefHandler; - XML_Parser m_externalEntityRefHandlerArg; - XML_SkippedEntityHandler m_skippedEntityHandler; - XML_UnknownEncodingHandler m_unknownEncodingHandler; - XML_ElementDeclHandler m_elementDeclHandler; - XML_AttlistDeclHandler m_attlistDeclHandler; - XML_EntityDeclHandler m_entityDeclHandler; - XML_XmlDeclHandler m_xmlDeclHandler; - const ENCODING *m_encoding; - INIT_ENCODING m_initEncoding; - const ENCODING *m_internalEncoding; - const XML_Char *m_protocolEncodingName; - XML_Bool m_ns; - XML_Bool m_ns_triplets; - void *m_unknownEncodingMem; - void *m_unknownEncodingData; - void *m_unknownEncodingHandlerData; - void (XMLCALL *m_unknownEncodingRelease)(void *); - PROLOG_STATE m_prologState; - Processor *m_processor; - enum XML_Error m_errorCode; - const char *m_eventPtr; - const char *m_eventEndPtr; - const char *m_positionPtr; - OPEN_INTERNAL_ENTITY *m_openInternalEntities; - OPEN_INTERNAL_ENTITY *m_freeInternalEntities; - XML_Bool m_defaultExpandInternalEntities; - int m_tagLevel; - ENTITY *m_declEntity; - const XML_Char *m_doctypeName; - const XML_Char *m_doctypeSysid; - const XML_Char *m_doctypePubid; - const XML_Char *m_declAttributeType; - const XML_Char *m_declNotationName; - const XML_Char *m_declNotationPublicId; - ELEMENT_TYPE *m_declElementType; - ATTRIBUTE_ID *m_declAttributeId; - XML_Bool m_declAttributeIsCdata; - XML_Bool m_declAttributeIsId; - DTD *m_dtd; - const XML_Char *m_curBase; - TAG *m_tagStack; - TAG *m_freeTagList; - BINDING *m_inheritedBindings; - BINDING *m_freeBindingList; - int m_attsSize; - int m_nSpecifiedAtts; - int m_idAttIndex; - ATTRIBUTE *m_atts; - NS_ATT *m_nsAtts; - unsigned long m_nsAttsVersion; - unsigned char m_nsAttsPower; - POSITION m_position; - STRING_POOL m_tempPool; - STRING_POOL m_temp2Pool; - char *m_groupConnector; - unsigned int m_groupSize; - XML_Char m_namespaceSeparator; - XML_Parser m_parentParser; - XML_ParsingStatus m_parsingStatus; -#ifdef XML_DTD - XML_Bool m_isParamEntity; - XML_Bool m_useForeignDTD; - enum XML_ParamEntityParsing m_paramEntityParsing; -#endif -}; - -#define MALLOC(s) (parser->m_mem.malloc_fcn((s))) -#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s))) -#define FREE(p) (parser->m_mem.free_fcn((p))) - -#define userData (parser->m_userData) -#define handlerArg (parser->m_handlerArg) -#define startElementHandler (parser->m_startElementHandler) -#define endElementHandler (parser->m_endElementHandler) -#define characterDataHandler (parser->m_characterDataHandler) -#define processingInstructionHandler \ - (parser->m_processingInstructionHandler) -#define commentHandler (parser->m_commentHandler) -#define startCdataSectionHandler \ - (parser->m_startCdataSectionHandler) -#define endCdataSectionHandler (parser->m_endCdataSectionHandler) -#define defaultHandler (parser->m_defaultHandler) -#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler) -#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler) -#define unparsedEntityDeclHandler \ - (parser->m_unparsedEntityDeclHandler) -#define notationDeclHandler (parser->m_notationDeclHandler) -#define startNamespaceDeclHandler \ - (parser->m_startNamespaceDeclHandler) -#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler) -#define notStandaloneHandler (parser->m_notStandaloneHandler) -#define externalEntityRefHandler \ - (parser->m_externalEntityRefHandler) -#define externalEntityRefHandlerArg \ - (parser->m_externalEntityRefHandlerArg) -#define internalEntityRefHandler \ - (parser->m_internalEntityRefHandler) -#define skippedEntityHandler (parser->m_skippedEntityHandler) -#define unknownEncodingHandler (parser->m_unknownEncodingHandler) -#define elementDeclHandler (parser->m_elementDeclHandler) -#define attlistDeclHandler (parser->m_attlistDeclHandler) -#define entityDeclHandler (parser->m_entityDeclHandler) -#define xmlDeclHandler (parser->m_xmlDeclHandler) -#define encoding (parser->m_encoding) -#define initEncoding (parser->m_initEncoding) -#define internalEncoding (parser->m_internalEncoding) -#define unknownEncodingMem (parser->m_unknownEncodingMem) -#define unknownEncodingData (parser->m_unknownEncodingData) -#define unknownEncodingHandlerData \ - (parser->m_unknownEncodingHandlerData) -#define unknownEncodingRelease (parser->m_unknownEncodingRelease) -#define protocolEncodingName (parser->m_protocolEncodingName) -#define ns (parser->m_ns) -#define ns_triplets (parser->m_ns_triplets) -#define prologState (parser->m_prologState) -#define processor (parser->m_processor) -#define errorCode (parser->m_errorCode) -#define eventPtr (parser->m_eventPtr) -#define eventEndPtr (parser->m_eventEndPtr) -#define positionPtr (parser->m_positionPtr) -#define position (parser->m_position) -#define openInternalEntities (parser->m_openInternalEntities) -#define freeInternalEntities (parser->m_freeInternalEntities) -#define defaultExpandInternalEntities \ - (parser->m_defaultExpandInternalEntities) -#define tagLevel (parser->m_tagLevel) -#define buffer (parser->m_buffer) -#define bufferPtr (parser->m_bufferPtr) -#define bufferEnd (parser->m_bufferEnd) -#define parseEndByteIndex (parser->m_parseEndByteIndex) -#define parseEndPtr (parser->m_parseEndPtr) -#define bufferLim (parser->m_bufferLim) -#define dataBuf (parser->m_dataBuf) -#define dataBufEnd (parser->m_dataBufEnd) -#define _dtd (parser->m_dtd) -#define curBase (parser->m_curBase) -#define declEntity (parser->m_declEntity) -#define doctypeName (parser->m_doctypeName) -#define doctypeSysid (parser->m_doctypeSysid) -#define doctypePubid (parser->m_doctypePubid) -#define declAttributeType (parser->m_declAttributeType) -#define declNotationName (parser->m_declNotationName) -#define declNotationPublicId (parser->m_declNotationPublicId) -#define declElementType (parser->m_declElementType) -#define declAttributeId (parser->m_declAttributeId) -#define declAttributeIsCdata (parser->m_declAttributeIsCdata) -#define declAttributeIsId (parser->m_declAttributeIsId) -#define freeTagList (parser->m_freeTagList) -#define freeBindingList (parser->m_freeBindingList) -#define inheritedBindings (parser->m_inheritedBindings) -#define tagStack (parser->m_tagStack) -#define atts (parser->m_atts) -#define attsSize (parser->m_attsSize) -#define nSpecifiedAtts (parser->m_nSpecifiedAtts) -#define idAttIndex (parser->m_idAttIndex) -#define nsAtts (parser->m_nsAtts) -#define nsAttsVersion (parser->m_nsAttsVersion) -#define nsAttsPower (parser->m_nsAttsPower) -#define tempPool (parser->m_tempPool) -#define temp2Pool (parser->m_temp2Pool) -#define groupConnector (parser->m_groupConnector) -#define groupSize (parser->m_groupSize) -#define namespaceSeparator (parser->m_namespaceSeparator) -#define parentParser (parser->m_parentParser) -#define ps_parsing (parser->m_parsingStatus.parsing) -#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer) -#ifdef XML_DTD -#define isParamEntity (parser->m_isParamEntity) -#define useForeignDTD (parser->m_useForeignDTD) -#define paramEntityParsing (parser->m_paramEntityParsing) -#endif /* XML_DTD */ - -XML_Parser XMLCALL -XML_ParserCreate(const XML_Char *encodingName) -{ - return XML_ParserCreate_MM(encodingName, NULL, NULL); -} - -XML_Parser XMLCALL -XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) -{ - XML_Char tmp[2]; - *tmp = nsSep; - return XML_ParserCreate_MM(encodingName, NULL, tmp); -} - -static const XML_Char implicitContext[] = { - ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, - ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, - ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, - ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, - ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, - ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0' -}; - -XML_Parser XMLCALL -XML_ParserCreate_MM(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep) -{ - XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL); - if (parser != NULL && ns) { - /* implicit context only set for root parser, since child - parsers (i.e. external entity parsers) will inherit it - */ - if (!setContext(parser, implicitContext)) { - XML_ParserFree(parser); - return NULL; - } - } - return parser; -} - -static XML_Parser -parserCreate(const XML_Char *encodingName, - const XML_Memory_Handling_Suite *memsuite, - const XML_Char *nameSep, - DTD *dtd) -{ - XML_Parser parser; - - if (memsuite) { - XML_Memory_Handling_Suite *mtemp; - parser = (XML_Parser) - memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); - if (parser != NULL) { - mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); - mtemp->malloc_fcn = memsuite->malloc_fcn; - mtemp->realloc_fcn = memsuite->realloc_fcn; - mtemp->free_fcn = memsuite->free_fcn; - } - } - else { - XML_Memory_Handling_Suite *mtemp; - parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); - if (parser != NULL) { - mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); - mtemp->malloc_fcn = malloc; - mtemp->realloc_fcn = realloc; - mtemp->free_fcn = free; - } - } - - if (!parser) - return parser; - - buffer = NULL; - bufferLim = NULL; - - attsSize = INIT_ATTS_SIZE; - atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE)); - if (atts == NULL) { - FREE(parser); - return NULL; - } - dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); - if (dataBuf == NULL) { - FREE(atts); - FREE(parser); - return NULL; - } - dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; - - if (dtd) - _dtd = dtd; - else { - _dtd = dtdCreate(&parser->m_mem); - if (_dtd == NULL) { - FREE(dataBuf); - FREE(atts); - FREE(parser); - return NULL; - } - } - - freeBindingList = NULL; - freeTagList = NULL; - freeInternalEntities = NULL; - - groupSize = 0; - groupConnector = NULL; - - unknownEncodingHandler = NULL; - unknownEncodingHandlerData = NULL; - - namespaceSeparator = ASCII_EXCL; - ns = XML_FALSE; - ns_triplets = XML_FALSE; - - nsAtts = NULL; - nsAttsVersion = 0; - nsAttsPower = 0; - - poolInit(&tempPool, &(parser->m_mem)); - poolInit(&temp2Pool, &(parser->m_mem)); - parserInit(parser, encodingName); - - if (encodingName && !protocolEncodingName) { - XML_ParserFree(parser); - return NULL; - } - - if (nameSep) { - ns = XML_TRUE; - internalEncoding = XmlGetInternalEncodingNS(); - namespaceSeparator = *nameSep; - } - else { - internalEncoding = XmlGetInternalEncoding(); - } - - return parser; -} - -static void -parserInit(XML_Parser parser, const XML_Char *encodingName) -{ - processor = prologInitProcessor; - XmlPrologStateInit(&prologState); - protocolEncodingName = (encodingName != NULL - ? poolCopyString(&tempPool, encodingName) - : NULL); - curBase = NULL; - XmlInitEncoding(&initEncoding, &encoding, 0); - userData = NULL; - handlerArg = NULL; - startElementHandler = NULL; - endElementHandler = NULL; - characterDataHandler = NULL; - processingInstructionHandler = NULL; - commentHandler = NULL; - startCdataSectionHandler = NULL; - endCdataSectionHandler = NULL; - defaultHandler = NULL; - startDoctypeDeclHandler = NULL; - endDoctypeDeclHandler = NULL; - unparsedEntityDeclHandler = NULL; - notationDeclHandler = NULL; - startNamespaceDeclHandler = NULL; - endNamespaceDeclHandler = NULL; - notStandaloneHandler = NULL; - externalEntityRefHandler = NULL; - externalEntityRefHandlerArg = parser; - skippedEntityHandler = NULL; - elementDeclHandler = NULL; - attlistDeclHandler = NULL; - entityDeclHandler = NULL; - xmlDeclHandler = NULL; - bufferPtr = buffer; - bufferEnd = buffer; - parseEndByteIndex = 0; - parseEndPtr = NULL; - declElementType = NULL; - declAttributeId = NULL; - declEntity = NULL; - doctypeName = NULL; - doctypeSysid = NULL; - doctypePubid = NULL; - declAttributeType = NULL; - declNotationName = NULL; - declNotationPublicId = NULL; - declAttributeIsCdata = XML_FALSE; - declAttributeIsId = XML_FALSE; - memset(&position, 0, sizeof(POSITION)); - errorCode = XML_ERROR_NONE; - eventPtr = NULL; - eventEndPtr = NULL; - positionPtr = NULL; - openInternalEntities = NULL; - defaultExpandInternalEntities = XML_TRUE; - tagLevel = 0; - tagStack = NULL; - inheritedBindings = NULL; - nSpecifiedAtts = 0; - unknownEncodingMem = NULL; - unknownEncodingRelease = NULL; - unknownEncodingData = NULL; - parentParser = NULL; - ps_parsing = XML_INITIALIZED; -#ifdef XML_DTD - isParamEntity = XML_FALSE; - useForeignDTD = XML_FALSE; - paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; -#endif -} - -/* moves list of bindings to freeBindingList */ -static void FASTCALL -moveToFreeBindingList(XML_Parser parser, BINDING *bindings) -{ - while (bindings) { - BINDING *b = bindings; - bindings = bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; - } -} - -XML_Bool XMLCALL -XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) -{ - TAG *tStk; - OPEN_INTERNAL_ENTITY *openEntityList; - if (parentParser) - return XML_FALSE; - /* move tagStack to freeTagList */ - tStk = tagStack; - while (tStk) { - TAG *tag = tStk; - tStk = tStk->parent; - tag->parent = freeTagList; - moveToFreeBindingList(parser, tag->bindings); - tag->bindings = NULL; - freeTagList = tag; - } - /* move openInternalEntities to freeInternalEntities */ - openEntityList = openInternalEntities; - while (openEntityList) { - OPEN_INTERNAL_ENTITY *openEntity = openEntityList; - openEntityList = openEntity->next; - openEntity->next = freeInternalEntities; - freeInternalEntities = openEntity; - } - moveToFreeBindingList(parser, inheritedBindings); - FREE(unknownEncodingMem); - if (unknownEncodingRelease) - unknownEncodingRelease(unknownEncodingData); - poolClear(&tempPool); - poolClear(&temp2Pool); - parserInit(parser, encodingName); - dtdReset(_dtd, &parser->m_mem); - return setContext(parser, implicitContext); -} - -enum XML_Status XMLCALL -XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) -{ - /* Block after XML_Parse()/XML_ParseBuffer() has been called. - XXX There's no way for the caller to determine which of the - XXX possible error cases caused the XML_STATUS_ERROR return. - */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) - return XML_STATUS_ERROR; - if (encodingName == NULL) - protocolEncodingName = NULL; - else { - protocolEncodingName = poolCopyString(&tempPool, encodingName); - if (!protocolEncodingName) - return XML_STATUS_ERROR; - } - return XML_STATUS_OK; -} - -XML_Parser XMLCALL -XML_ExternalEntityParserCreate(XML_Parser oldParser, - const XML_Char *context, - const XML_Char *encodingName) -{ - XML_Parser parser = oldParser; - DTD *newDtd = NULL; - DTD *oldDtd = _dtd; - XML_StartElementHandler oldStartElementHandler = startElementHandler; - XML_EndElementHandler oldEndElementHandler = endElementHandler; - XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; - XML_ProcessingInstructionHandler oldProcessingInstructionHandler - = processingInstructionHandler; - XML_CommentHandler oldCommentHandler = commentHandler; - XML_StartCdataSectionHandler oldStartCdataSectionHandler - = startCdataSectionHandler; - XML_EndCdataSectionHandler oldEndCdataSectionHandler - = endCdataSectionHandler; - XML_DefaultHandler oldDefaultHandler = defaultHandler; - XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler - = unparsedEntityDeclHandler; - XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; - XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler - = startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler - = endNamespaceDeclHandler; - XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; - XML_ExternalEntityRefHandler oldExternalEntityRefHandler - = externalEntityRefHandler; - XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; - XML_UnknownEncodingHandler oldUnknownEncodingHandler - = unknownEncodingHandler; - XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; - XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; - XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; - XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; - ELEMENT_TYPE * oldDeclElementType = declElementType; - - void *oldUserData = userData; - void *oldHandlerArg = handlerArg; - XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; - XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; -#ifdef XML_DTD - enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; - int oldInEntityValue = prologState.inEntityValue; -#endif - XML_Bool oldns_triplets = ns_triplets; - -#ifdef XML_DTD - if (!context) - newDtd = oldDtd; -#endif /* XML_DTD */ - - /* Note that the magical uses of the pre-processor to make field - access look more like C++ require that `parser' be overwritten - here. This makes this function more painful to follow than it - would be otherwise. - */ - if (ns) { - XML_Char tmp[2]; - *tmp = namespaceSeparator; - parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); - } - else { - parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); - } - - if (!parser) - return NULL; - - startElementHandler = oldStartElementHandler; - endElementHandler = oldEndElementHandler; - characterDataHandler = oldCharacterDataHandler; - processingInstructionHandler = oldProcessingInstructionHandler; - commentHandler = oldCommentHandler; - startCdataSectionHandler = oldStartCdataSectionHandler; - endCdataSectionHandler = oldEndCdataSectionHandler; - defaultHandler = oldDefaultHandler; - unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; - notationDeclHandler = oldNotationDeclHandler; - startNamespaceDeclHandler = oldStartNamespaceDeclHandler; - endNamespaceDeclHandler = oldEndNamespaceDeclHandler; - notStandaloneHandler = oldNotStandaloneHandler; - externalEntityRefHandler = oldExternalEntityRefHandler; - skippedEntityHandler = oldSkippedEntityHandler; - unknownEncodingHandler = oldUnknownEncodingHandler; - elementDeclHandler = oldElementDeclHandler; - attlistDeclHandler = oldAttlistDeclHandler; - entityDeclHandler = oldEntityDeclHandler; - xmlDeclHandler = oldXmlDeclHandler; - declElementType = oldDeclElementType; - userData = oldUserData; - if (oldUserData == oldHandlerArg) - handlerArg = userData; - else - handlerArg = parser; - if (oldExternalEntityRefHandlerArg != oldParser) - externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; - defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - ns_triplets = oldns_triplets; - parentParser = oldParser; -#ifdef XML_DTD - paramEntityParsing = oldParamEntityParsing; - prologState.inEntityValue = oldInEntityValue; - if (context) { -#endif /* XML_DTD */ - if (!dtdCopy(_dtd, oldDtd, &parser->m_mem) - || !setContext(parser, context)) { - XML_ParserFree(parser); - return NULL; - } - processor = externalEntityInitProcessor; -#ifdef XML_DTD - } - else { - /* The DTD instance referenced by _dtd is shared between the document's - root parser and external PE parsers, therefore one does not need to - call setContext. In addition, one also *must* not call setContext, - because this would overwrite existing prefix->binding pointers in - _dtd with ones that get destroyed with the external PE parser. - This would leave those prefixes with dangling pointers. - */ - isParamEntity = XML_TRUE; - XmlPrologStateInitExternalEntity(&prologState); - processor = externalParEntInitProcessor; - } -#endif /* XML_DTD */ - return parser; -} - -static void FASTCALL -destroyBindings(BINDING *bindings, XML_Parser parser) -{ - for (;;) { - BINDING *b = bindings; - if (!b) - break; - bindings = b->nextTagBinding; - FREE(b->uri); - FREE(b); - } -} - -void XMLCALL -XML_ParserFree(XML_Parser parser) -{ - TAG *tagList; - OPEN_INTERNAL_ENTITY *entityList; - if (parser == NULL) - return; - /* free tagStack and freeTagList */ - tagList = tagStack; - for (;;) { - TAG *p; - if (tagList == NULL) { - if (freeTagList == NULL) - break; - tagList = freeTagList; - freeTagList = NULL; - } - p = tagList; - tagList = tagList->parent; - FREE(p->buf); - destroyBindings(p->bindings, parser); - FREE(p); - } - /* free openInternalEntities and freeInternalEntities */ - entityList = openInternalEntities; - for (;;) { - OPEN_INTERNAL_ENTITY *openEntity; - if (entityList == NULL) { - if (freeInternalEntities == NULL) - break; - entityList = freeInternalEntities; - freeInternalEntities = NULL; - } - openEntity = entityList; - entityList = entityList->next; - FREE(openEntity); - } - - destroyBindings(freeBindingList, parser); - destroyBindings(inheritedBindings, parser); - poolDestroy(&tempPool); - poolDestroy(&temp2Pool); -#ifdef XML_DTD - /* external parameter entity parsers share the DTD structure - parser->m_dtd with the root parser, so we must not destroy it - */ - if (!isParamEntity && _dtd) -#else - if (_dtd) -#endif /* XML_DTD */ - dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem); - FREE((void *)atts); - FREE(groupConnector); - FREE(buffer); - FREE(dataBuf); - FREE(nsAtts); - FREE(unknownEncodingMem); - if (unknownEncodingRelease) - unknownEncodingRelease(unknownEncodingData); - FREE(parser); -} - -void XMLCALL -XML_UseParserAsHandlerArg(XML_Parser parser) -{ - handlerArg = parser; -} - -enum XML_Error XMLCALL -XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) -{ -#ifdef XML_DTD - /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) - return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; - useForeignDTD = useDTD; - return XML_ERROR_NONE; -#else - return XML_ERROR_FEATURE_REQUIRES_XML_DTD; -#endif -} - -void XMLCALL -XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) -{ - /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) - return; - ns_triplets = do_nst ? XML_TRUE : XML_FALSE; -} - -void XMLCALL -XML_SetUserData(XML_Parser parser, void *p) -{ - if (handlerArg == userData) - handlerArg = userData = p; - else - userData = p; -} - -enum XML_Status XMLCALL -XML_SetBase(XML_Parser parser, const XML_Char *p) -{ - if (p) { - p = poolCopyString(&_dtd->pool, p); - if (!p) - return XML_STATUS_ERROR; - curBase = p; - } - else - curBase = NULL; - return XML_STATUS_OK; -} - -const XML_Char * XMLCALL -XML_GetBase(XML_Parser parser) -{ - return curBase; -} - -int XMLCALL -XML_GetSpecifiedAttributeCount(XML_Parser parser) -{ - return nSpecifiedAtts; -} - -int XMLCALL -XML_GetIdAttributeIndex(XML_Parser parser) -{ - return idAttIndex; -} - -void XMLCALL -XML_SetElementHandler(XML_Parser parser, - XML_StartElementHandler start, - XML_EndElementHandler end) -{ - startElementHandler = start; - endElementHandler = end; -} - -void XMLCALL -XML_SetStartElementHandler(XML_Parser parser, - XML_StartElementHandler start) { - startElementHandler = start; -} - -void XMLCALL -XML_SetEndElementHandler(XML_Parser parser, - XML_EndElementHandler end) { - endElementHandler = end; -} - -void XMLCALL -XML_SetCharacterDataHandler(XML_Parser parser, - XML_CharacterDataHandler handler) -{ - characterDataHandler = handler; -} - -void XMLCALL -XML_SetProcessingInstructionHandler(XML_Parser parser, - XML_ProcessingInstructionHandler handler) -{ - processingInstructionHandler = handler; -} - -void XMLCALL -XML_SetCommentHandler(XML_Parser parser, - XML_CommentHandler handler) -{ - commentHandler = handler; -} - -void XMLCALL -XML_SetCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start, - XML_EndCdataSectionHandler end) -{ - startCdataSectionHandler = start; - endCdataSectionHandler = end; -} - -void XMLCALL -XML_SetStartCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start) { - startCdataSectionHandler = start; -} - -void XMLCALL -XML_SetEndCdataSectionHandler(XML_Parser parser, - XML_EndCdataSectionHandler end) { - endCdataSectionHandler = end; -} - -void XMLCALL -XML_SetDefaultHandler(XML_Parser parser, - XML_DefaultHandler handler) -{ - defaultHandler = handler; - defaultExpandInternalEntities = XML_FALSE; -} - -void XMLCALL -XML_SetDefaultHandlerExpand(XML_Parser parser, - XML_DefaultHandler handler) -{ - defaultHandler = handler; - defaultExpandInternalEntities = XML_TRUE; -} - -void XMLCALL -XML_SetDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start, - XML_EndDoctypeDeclHandler end) -{ - startDoctypeDeclHandler = start; - endDoctypeDeclHandler = end; -} - -void XMLCALL -XML_SetStartDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start) { - startDoctypeDeclHandler = start; -} - -void XMLCALL -XML_SetEndDoctypeDeclHandler(XML_Parser parser, - XML_EndDoctypeDeclHandler end) { - endDoctypeDeclHandler = end; -} - -void XMLCALL -XML_SetUnparsedEntityDeclHandler(XML_Parser parser, - XML_UnparsedEntityDeclHandler handler) -{ - unparsedEntityDeclHandler = handler; -} - -void XMLCALL -XML_SetNotationDeclHandler(XML_Parser parser, - XML_NotationDeclHandler handler) -{ - notationDeclHandler = handler; -} - -void XMLCALL -XML_SetNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end) -{ - startNamespaceDeclHandler = start; - endNamespaceDeclHandler = end; -} - -void XMLCALL -XML_SetStartNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start) { - startNamespaceDeclHandler = start; -} - -void XMLCALL -XML_SetEndNamespaceDeclHandler(XML_Parser parser, - XML_EndNamespaceDeclHandler end) { - endNamespaceDeclHandler = end; -} - -void XMLCALL -XML_SetNotStandaloneHandler(XML_Parser parser, - XML_NotStandaloneHandler handler) -{ - notStandaloneHandler = handler; -} - -void XMLCALL -XML_SetExternalEntityRefHandler(XML_Parser parser, - XML_ExternalEntityRefHandler handler) -{ - externalEntityRefHandler = handler; -} - -void XMLCALL -XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) -{ - if (arg) - externalEntityRefHandlerArg = (XML_Parser)arg; - else - externalEntityRefHandlerArg = parser; -} - -void XMLCALL -XML_SetSkippedEntityHandler(XML_Parser parser, - XML_SkippedEntityHandler handler) -{ - skippedEntityHandler = handler; -} - -void XMLCALL -XML_SetUnknownEncodingHandler(XML_Parser parser, - XML_UnknownEncodingHandler handler, - void *data) -{ - unknownEncodingHandler = handler; - unknownEncodingHandlerData = data; -} - -void XMLCALL -XML_SetElementDeclHandler(XML_Parser parser, - XML_ElementDeclHandler eldecl) -{ - elementDeclHandler = eldecl; -} - -void XMLCALL -XML_SetAttlistDeclHandler(XML_Parser parser, - XML_AttlistDeclHandler attdecl) -{ - attlistDeclHandler = attdecl; -} - -void XMLCALL -XML_SetEntityDeclHandler(XML_Parser parser, - XML_EntityDeclHandler handler) -{ - entityDeclHandler = handler; -} - -void XMLCALL -XML_SetXmlDeclHandler(XML_Parser parser, - XML_XmlDeclHandler handler) { - xmlDeclHandler = handler; -} - -int XMLCALL -XML_SetParamEntityParsing(XML_Parser parser, - enum XML_ParamEntityParsing peParsing) -{ - /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) - return 0; -#ifdef XML_DTD - paramEntityParsing = peParsing; - return 1; -#else - return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; -#endif -} - -enum XML_Status XMLCALL -XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) -{ - switch (ps_parsing) { - case XML_SUSPENDED: - errorCode = XML_ERROR_SUSPENDED; - return XML_STATUS_ERROR; - case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; - return XML_STATUS_ERROR; - default: - ps_parsing = XML_PARSING; - } - - if (len == 0) { - ps_finalBuffer = (XML_Bool)isFinal; - if (!isFinal) - return XML_STATUS_OK; - positionPtr = bufferPtr; - parseEndPtr = bufferEnd; - - /* If data are left over from last buffer, and we now know that these - data are the final chunk of input, then we have to check them again - to detect errors based on that fact. - */ - errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); - - if (errorCode == XML_ERROR_NONE) { - switch (ps_parsing) { - case XML_SUSPENDED: - XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); - positionPtr = bufferPtr; - return XML_STATUS_SUSPENDED; - case XML_INITIALIZED: - case XML_PARSING: - ps_parsing = XML_FINISHED; - /* fall through */ - default: - return XML_STATUS_OK; - } - } - eventEndPtr = eventPtr; - processor = errorProcessor; - return XML_STATUS_ERROR; - } -#ifndef XML_CONTEXT_BYTES - else if (bufferPtr == bufferEnd) { - const char *end; - int nLeftOver; - enum XML_Error result; - parseEndByteIndex += len; - positionPtr = s; - ps_finalBuffer = (XML_Bool)isFinal; - - errorCode = processor(parser, s, parseEndPtr = s + len, &end); - - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; - processor = errorProcessor; - return XML_STATUS_ERROR; - } - else { - switch (ps_parsing) { - case XML_SUSPENDED: - result = XML_STATUS_SUSPENDED; - break; - case XML_INITIALIZED: - case XML_PARSING: - result = XML_STATUS_OK; - if (isFinal) { - ps_parsing = XML_FINISHED; - return result; - } - } - } - - XmlUpdatePosition(encoding, positionPtr, end, &position); - nLeftOver = s + len - end; - if (nLeftOver) { - if (buffer == NULL || nLeftOver > bufferLim - buffer) { - /* FIXME avoid integer overflow */ - char *temp; - temp = (buffer == NULL - ? (char *)MALLOC(len * 2) - : (char *)REALLOC(buffer, len * 2)); - if (temp == NULL) { - errorCode = XML_ERROR_NO_MEMORY; - return XML_STATUS_ERROR; - } - buffer = temp; - if (!buffer) { - errorCode = XML_ERROR_NO_MEMORY; - eventPtr = eventEndPtr = NULL; - processor = errorProcessor; - return XML_STATUS_ERROR; - } - bufferLim = buffer + len * 2; - } - memcpy(buffer, end, nLeftOver); - } - bufferPtr = buffer; - bufferEnd = buffer + nLeftOver; - positionPtr = bufferPtr; - parseEndPtr = bufferEnd; - eventPtr = bufferPtr; - eventEndPtr = bufferPtr; - return result; - } -#endif /* not defined XML_CONTEXT_BYTES */ - else { - void *buff = XML_GetBuffer(parser, len); - if (buff == NULL) - return XML_STATUS_ERROR; - else { - memcpy(buff, s, len); - return XML_ParseBuffer(parser, len, isFinal); - } - } -} - -enum XML_Status XMLCALL -XML_ParseBuffer(XML_Parser parser, int len, int isFinal) -{ - const char *start; - enum XML_Status result = XML_STATUS_OK; - - switch (ps_parsing) { - case XML_SUSPENDED: - errorCode = XML_ERROR_SUSPENDED; - return XML_STATUS_ERROR; - case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; - return XML_STATUS_ERROR; - default: - ps_parsing = XML_PARSING; - } - - start = bufferPtr; - positionPtr = start; - bufferEnd += len; - parseEndPtr = bufferEnd; - parseEndByteIndex += len; - ps_finalBuffer = (XML_Bool)isFinal; - - errorCode = processor(parser, start, parseEndPtr, &bufferPtr); - - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; - processor = errorProcessor; - return XML_STATUS_ERROR; - } - else { - switch (ps_parsing) { - case XML_SUSPENDED: - result = XML_STATUS_SUSPENDED; - break; - case XML_INITIALIZED: - case XML_PARSING: - if (isFinal) { - ps_parsing = XML_FINISHED; - return result; - } - default: ; /* should not happen */ - } - } - - XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); - positionPtr = bufferPtr; - return result; -} - -void * XMLCALL -XML_GetBuffer(XML_Parser parser, int len) -{ - switch (ps_parsing) { - case XML_SUSPENDED: - errorCode = XML_ERROR_SUSPENDED; - return NULL; - case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; - return NULL; - default: ; - } - - if (len > bufferLim - bufferEnd) { - /* FIXME avoid integer overflow */ - int neededSize = len + (int)(bufferEnd - bufferPtr); -#ifdef XML_CONTEXT_BYTES - int keep = (int)(bufferPtr - buffer); - - if (keep > XML_CONTEXT_BYTES) - keep = XML_CONTEXT_BYTES; - neededSize += keep; -#endif /* defined XML_CONTEXT_BYTES */ - if (neededSize <= bufferLim - buffer) { -#ifdef XML_CONTEXT_BYTES - if (keep < bufferPtr - buffer) { - int offset = (int)(bufferPtr - buffer) - keep; - memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep); - bufferEnd -= offset; - bufferPtr -= offset; - } -#else - memmove(buffer, bufferPtr, bufferEnd - bufferPtr); - bufferEnd = buffer + (bufferEnd - bufferPtr); - bufferPtr = buffer; -#endif /* not defined XML_CONTEXT_BYTES */ - } - else { - char *newBuf; - int bufferSize = (int)(bufferLim - bufferPtr); - if (bufferSize == 0) - bufferSize = INIT_BUFFER_SIZE; - do { - bufferSize *= 2; - } while (bufferSize < neededSize); - newBuf = (char *)MALLOC(bufferSize); - if (newBuf == 0) { - errorCode = XML_ERROR_NO_MEMORY; - return NULL; - } - bufferLim = newBuf + bufferSize; -#ifdef XML_CONTEXT_BYTES - if (bufferPtr) { - int keep = (int)(bufferPtr - buffer); - if (keep > XML_CONTEXT_BYTES) - keep = XML_CONTEXT_BYTES; - memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep); - FREE(buffer); - buffer = newBuf; - bufferEnd = buffer + (bufferEnd - bufferPtr) + keep; - bufferPtr = buffer + keep; - } - else { - bufferEnd = newBuf + (bufferEnd - bufferPtr); - bufferPtr = buffer = newBuf; - } -#else - if (bufferPtr) { - memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); - FREE(buffer); - } - bufferEnd = newBuf + (bufferEnd - bufferPtr); - bufferPtr = buffer = newBuf; -#endif /* not defined XML_CONTEXT_BYTES */ - } - } - return bufferEnd; -} - -enum XML_Status XMLCALL -XML_StopParser(XML_Parser parser, XML_Bool resumable) -{ - switch (ps_parsing) { - case XML_SUSPENDED: - if (resumable) { - errorCode = XML_ERROR_SUSPENDED; - return XML_STATUS_ERROR; - } - ps_parsing = XML_FINISHED; - break; - case XML_FINISHED: - errorCode = XML_ERROR_FINISHED; - return XML_STATUS_ERROR; - default: - if (resumable) { -#ifdef XML_DTD - if (isParamEntity) { - errorCode = XML_ERROR_SUSPEND_PE; - return XML_STATUS_ERROR; - } -#endif - ps_parsing = XML_SUSPENDED; - } - else - ps_parsing = XML_FINISHED; - } - return XML_STATUS_OK; -} - -enum XML_Status XMLCALL -XML_ResumeParser(XML_Parser parser) -{ - enum XML_Status result = XML_STATUS_OK; - - if (ps_parsing != XML_SUSPENDED) { - errorCode = XML_ERROR_NOT_SUSPENDED; - return XML_STATUS_ERROR; - } - ps_parsing = XML_PARSING; - - errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); - - if (errorCode != XML_ERROR_NONE) { - eventEndPtr = eventPtr; - processor = errorProcessor; - return XML_STATUS_ERROR; - } - else { - switch (ps_parsing) { - case XML_SUSPENDED: - result = XML_STATUS_SUSPENDED; - break; - case XML_INITIALIZED: - case XML_PARSING: - if (ps_finalBuffer) { - ps_parsing = XML_FINISHED; - return result; - } - default: ; - } - } - - XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); - positionPtr = bufferPtr; - return result; -} - -void XMLCALL -XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) -{ - assert(status != NULL); - *status = parser->m_parsingStatus; -} - -enum XML_Error XMLCALL -XML_GetErrorCode(XML_Parser parser) -{ - return errorCode; -} - -XML_Index XMLCALL -XML_GetCurrentByteIndex(XML_Parser parser) -{ - if (eventPtr) - return parseEndByteIndex - (parseEndPtr - eventPtr); - return -1; -} - -int XMLCALL -XML_GetCurrentByteCount(XML_Parser parser) -{ - if (eventEndPtr && eventPtr) - return (int)(eventEndPtr - eventPtr); - return 0; -} - -const char * XMLCALL -XML_GetInputContext(XML_Parser parser, int *offset, int *size) -{ -#ifdef XML_CONTEXT_BYTES - if (eventPtr && buffer) { - *offset = (int)(eventPtr - buffer); - *size = (int)(bufferEnd - buffer); - return buffer; - } -#endif /* defined XML_CONTEXT_BYTES */ - return (char *) 0; -} - -XML_Size XMLCALL -XML_GetCurrentLineNumber(XML_Parser parser) -{ - if (eventPtr && eventPtr >= positionPtr) { - XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); - positionPtr = eventPtr; - } - return position.lineNumber + 1; -} - -XML_Size XMLCALL -XML_GetCurrentColumnNumber(XML_Parser parser) -{ - if (eventPtr && eventPtr >= positionPtr) { - XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); - positionPtr = eventPtr; - } - return position.columnNumber; -} - -void XMLCALL -XML_FreeContentModel(XML_Parser parser, XML_Content *model) -{ - FREE(model); -} - -void * XMLCALL -XML_MemMalloc(XML_Parser parser, size_t size) -{ - return MALLOC(size); -} - -void * XMLCALL -XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) -{ - return REALLOC(ptr, size); -} - -void XMLCALL -XML_MemFree(XML_Parser parser, void *ptr) -{ - FREE(ptr); -} - -void XMLCALL -XML_DefaultCurrent(XML_Parser parser) -{ - if (defaultHandler) { - if (openInternalEntities) - reportDefault(parser, - internalEncoding, - openInternalEntities->internalEventPtr, - openInternalEntities->internalEventEndPtr); - else - reportDefault(parser, encoding, eventPtr, eventEndPtr); - } -} - -const XML_LChar * XMLCALL -XML_ErrorString(enum XML_Error code) -{ - static const XML_LChar* const message[] = { - 0, - XML_L("out of memory"), - XML_L("syntax error"), - XML_L("no element found"), - XML_L("not well-formed (invalid token)"), - XML_L("unclosed token"), - XML_L("partial character"), - XML_L("mismatched tag"), - XML_L("duplicate attribute"), - XML_L("junk after document element"), - XML_L("illegal parameter entity reference"), - XML_L("undefined entity"), - XML_L("recursive entity reference"), - XML_L("asynchronous entity"), - XML_L("reference to invalid character number"), - XML_L("reference to binary entity"), - XML_L("reference to external entity in attribute"), - XML_L("XML or text declaration not at start of entity"), - XML_L("unknown encoding"), - XML_L("encoding specified in XML declaration is incorrect"), - XML_L("unclosed CDATA section"), - XML_L("error in processing external entity reference"), - XML_L("document is not standalone"), - XML_L("unexpected parser state - please send a bug report"), - XML_L("entity declared in parameter entity"), - XML_L("requested feature requires XML_DTD support in Expat"), - XML_L("cannot change setting once parsing has begun"), - XML_L("unbound prefix"), - XML_L("must not undeclare prefix"), - XML_L("incomplete markup in parameter entity"), - XML_L("XML declaration not well-formed"), - XML_L("text declaration not well-formed"), - XML_L("illegal character(s) in public id"), - XML_L("parser suspended"), - XML_L("parser not suspended"), - XML_L("parsing aborted"), - XML_L("parsing finished"), - XML_L("cannot suspend in external parameter entity"), - XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"), - XML_L("reserved prefix (xmlns) must not be declared or undeclared"), - XML_L("prefix must not be bound to one of the reserved namespace names") - }; - if (code > 0 && code < sizeof(message)/sizeof(message[0])) - return message[code]; - return NULL; -} - -const XML_LChar * XMLCALL -XML_ExpatVersion(void) { - - /* V1 is used to string-ize the version number. However, it would - string-ize the actual version macro *names* unless we get them - substituted before being passed to V1. CPP is defined to expand - a macro, then rescan for more expansions. Thus, we use V2 to expand - the version macros, then CPP will expand the resulting V1() macro - with the correct numerals. */ - /* ### I'm assuming cpp is portable in this respect... */ - -#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) -#define V2(a,b,c) XML_L("expat_")V1(a,b,c) - - return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); - -#undef V1 -#undef V2 -} - -XML_Expat_Version XMLCALL -XML_ExpatVersionInfo(void) -{ - XML_Expat_Version version; - - version.major = XML_MAJOR_VERSION; - version.minor = XML_MINOR_VERSION; - version.micro = XML_MICRO_VERSION; - - return version; -} - -const XML_Feature * XMLCALL -XML_GetFeatureList(void) -{ - static const XML_Feature features[] = { - {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), - sizeof(XML_Char)}, - {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), - sizeof(XML_LChar)}, -#ifdef XML_UNICODE - {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, -#endif -#ifdef XML_UNICODE_WCHAR_T - {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, -#endif -#ifdef XML_DTD - {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, -#endif -#ifdef XML_CONTEXT_BYTES - {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), - XML_CONTEXT_BYTES}, -#endif -#ifdef XML_MIN_SIZE - {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, -#endif -#ifdef XML_NS - {XML_FEATURE_NS, XML_L("XML_NS"), 0}, -#endif -#ifdef XML_LARGE_SIZE - {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, -#endif - {XML_FEATURE_END, NULL, 0} - }; - - return features; -} - -/* Initially tag->rawName always points into the parse buffer; - for those TAG instances opened while the current parse buffer was - processed, and not yet closed, we need to store tag->rawName in a more - permanent location, since the parse buffer is about to be discarded. -*/ -static XML_Bool -storeRawNames(XML_Parser parser) -{ - TAG *tag = tagStack; - while (tag) { - int bufSize; - int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); - char *rawNameBuf = tag->buf + nameLen; - /* Stop if already stored. Since tagStack is a stack, we can stop - at the first entry that has already been copied; everything - below it in the stack is already been accounted for in a - previous call to this function. - */ - if (tag->rawName == rawNameBuf) - break; - /* For re-use purposes we need to ensure that the - size of tag->buf is a multiple of sizeof(XML_Char). - */ - bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); - if (bufSize > tag->bufEnd - tag->buf) { - char *temp = (char *)REALLOC(tag->buf, bufSize); - if (temp == NULL) - return XML_FALSE; - /* if tag->name.str points to tag->buf (only when namespace - processing is off) then we have to update it - */ - if (tag->name.str == (XML_Char *)tag->buf) - tag->name.str = (XML_Char *)temp; - /* if tag->name.localPart is set (when namespace processing is on) - then update it as well, since it will always point into tag->buf - */ - if (tag->name.localPart) - tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - - (XML_Char *)tag->buf); - tag->buf = temp; - tag->bufEnd = temp + bufSize; - rawNameBuf = temp + nameLen; - } - memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); - tag->rawName = rawNameBuf; - tag = tag->parent; - } - return XML_TRUE; -} - -static enum XML_Error PTRCALL -contentProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doContent(parser, 0, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer); - if (result == XML_ERROR_NONE) { - if (!storeRawNames(parser)) - return XML_ERROR_NO_MEMORY; - } - return result; -} - -static enum XML_Error PTRCALL -externalEntityInitProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = initializeEncoding(parser); - if (result != XML_ERROR_NONE) - return result; - processor = externalEntityInitProcessor2; - return externalEntityInitProcessor2(parser, start, end, endPtr); -} - -static enum XML_Error PTRCALL -externalEntityInitProcessor2(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - const char *next = start; /* XmlContentTok doesn't always set the last arg */ - int tok = XmlContentTok(encoding, start, end, &next); - switch (tok) { - case XML_TOK_BOM: - /* If we are at the end of the buffer, this would cause the next stage, - i.e. externalEntityInitProcessor3, to pass control directly to - doContent (by detecting XML_TOK_NONE) without processing any xml text - declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. - */ - if (next == end && !ps_finalBuffer) { - *endPtr = next; - return XML_ERROR_NONE; - } - start = next; - break; - case XML_TOK_PARTIAL: - if (!ps_finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - eventPtr = start; - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (!ps_finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - eventPtr = start; - return XML_ERROR_PARTIAL_CHAR; - } - processor = externalEntityInitProcessor3; - return externalEntityInitProcessor3(parser, start, end, endPtr); -} - -static enum XML_Error PTRCALL -externalEntityInitProcessor3(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - int tok; - const char *next = start; /* XmlContentTok doesn't always set the last arg */ - eventPtr = start; - tok = XmlContentTok(encoding, start, end, &next); - eventEndPtr = next; - - switch (tok) { - case XML_TOK_XML_DECL: - { - enum XML_Error result; - result = processXmlDecl(parser, 1, start, next); - if (result != XML_ERROR_NONE) - return result; - switch (ps_parsing) { - case XML_SUSPENDED: - *endPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: - start = next; - } - } - break; - case XML_TOK_PARTIAL: - if (!ps_finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (!ps_finalBuffer) { - *endPtr = start; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - } - processor = externalEntityContentProcessor; - tagLevel = 1; - return externalEntityContentProcessor(parser, start, end, endPtr); -} - -static enum XML_Error PTRCALL -externalEntityContentProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doContent(parser, 1, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer); - if (result == XML_ERROR_NONE) { - if (!storeRawNames(parser)) - return XML_ERROR_NO_MEMORY; - } - return result; -} - -static enum XML_Error -doContent(XML_Parser parser, - int startTagLevel, - const ENCODING *enc, - const char *s, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ - /* save one level of indirection */ - DTD * const dtd = _dtd; - - const char **eventPP; - const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; - eventEndPP = &eventEndPtr; - } - else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); - } - *eventPP = s; - - for (;;) { - const char *next = s; /* XmlContentTok doesn't always set the last arg */ - int tok = XmlContentTok(enc, s, end, &next); - *eventEndPP = next; - switch (tok) { - case XML_TOK_TRAILING_CR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - *eventEndPP = end; - if (characterDataHandler) { - XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); - } - else if (defaultHandler) - reportDefault(parser, enc, s, end); - /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */ - if (startTagLevel == 0) - return XML_ERROR_NO_ELEMENTS; - if (tagLevel != startTagLevel) - return XML_ERROR_ASYNC_ENTITY; - *nextPtr = end; - return XML_ERROR_NONE; - case XML_TOK_NONE: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - if (startTagLevel > 0) { - if (tagLevel != startTagLevel) - return XML_ERROR_ASYNC_ENTITY; - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_NO_ELEMENTS; - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_ENTITY_REF: - { - const XML_Char *name; - ENTITY *entity; - XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (ch) { - if (characterDataHandler) - characterDataHandler(handlerArg, &ch, 1); - else if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - name = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); - poolDiscard(&dtd->pool); - /* First, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal, - otherwise call the skipped entity or default handler. - */ - if (!dtd->hasParamEntityRefs || dtd->standalone) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) - return XML_ERROR_ENTITY_DECLARED_IN_PE; - } - else if (!entity) { - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, name, 0); - else if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - if (entity->open) - return XML_ERROR_RECURSIVE_ENTITY_REF; - if (entity->notation) - return XML_ERROR_BINARY_ENTITY_REF; - if (entity->textPtr) { - enum XML_Error result; - if (!defaultExpandInternalEntities) { - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, entity->name, 0); - else if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - result = processInternalEntity(parser, entity, XML_FALSE); - if (result != XML_ERROR_NONE) - return result; - } - else if (externalEntityRefHandler) { - const XML_Char *context; - entity->open = XML_TRUE; - context = getContext(parser); - entity->open = XML_FALSE; - if (!context) - return XML_ERROR_NO_MEMORY; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - context, - entity->base, - entity->systemId, - entity->publicId)) - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - poolDiscard(&tempPool); - } - else if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - case XML_TOK_START_TAG_NO_ATTS: - /* fall through */ - case XML_TOK_START_TAG_WITH_ATTS: - { - TAG *tag; - enum XML_Error result; - XML_Char *toPtr; - if (freeTagList) { - tag = freeTagList; - freeTagList = freeTagList->parent; - } - else { - tag = (TAG *)MALLOC(sizeof(TAG)); - if (!tag) - return XML_ERROR_NO_MEMORY; - tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE); - if (!tag->buf) { - FREE(tag); - return XML_ERROR_NO_MEMORY; - } - tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; - } - tag->bindings = NULL; - tag->parent = tagStack; - tagStack = tag; - tag->name.localPart = NULL; - tag->name.prefix = NULL; - tag->rawName = s + enc->minBytesPerChar; - tag->rawNameLength = XmlNameLength(enc, tag->rawName); - ++tagLevel; - { - const char *rawNameEnd = tag->rawName + tag->rawNameLength; - const char *fromPtr = tag->rawName; - toPtr = (XML_Char *)tag->buf; - for (;;) { - int bufSize; - int convLen; - XmlConvert(enc, - &fromPtr, rawNameEnd, - (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); - convLen = (int)(toPtr - (XML_Char *)tag->buf); - if (fromPtr == rawNameEnd) { - tag->name.strLen = convLen; - break; - } - bufSize = (int)(tag->bufEnd - tag->buf) << 1; - { - char *temp = (char *)REALLOC(tag->buf, bufSize); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - tag->buf = temp; - tag->bufEnd = temp + bufSize; - toPtr = (XML_Char *)temp + convLen; - } - } - } - tag->name.str = (XML_Char *)tag->buf; - *toPtr = XML_T('\0'); - result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); - if (result) - return result; - if (startElementHandler) - startElementHandler(handlerArg, tag->name.str, - (const XML_Char **)atts); - else if (defaultHandler) - reportDefault(parser, enc, s, next); - poolClear(&tempPool); - break; - } - case XML_TOK_EMPTY_ELEMENT_NO_ATTS: - /* fall through */ - case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: - { - const char *rawName = s + enc->minBytesPerChar; - enum XML_Error result; - BINDING *bindings = NULL; - XML_Bool noElmHandlers = XML_TRUE; - TAG_NAME name; - name.str = poolStoreString(&tempPool, enc, rawName, - rawName + XmlNameLength(enc, rawName)); - if (!name.str) - return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - result = storeAtts(parser, enc, s, &name, &bindings); - if (result) - return result; - poolFinish(&tempPool); - if (startElementHandler) { - startElementHandler(handlerArg, name.str, (const XML_Char **)atts); - noElmHandlers = XML_FALSE; - } - if (endElementHandler) { - if (startElementHandler) - *eventPP = *eventEndPP; - endElementHandler(handlerArg, name.str); - noElmHandlers = XML_FALSE; - } - if (noElmHandlers && defaultHandler) - reportDefault(parser, enc, s, next); - poolClear(&tempPool); - while (bindings) { - BINDING *b = bindings; - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); - bindings = bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } - } - if (tagLevel == 0) - return epilogProcessor(parser, next, end, nextPtr); - break; - case XML_TOK_END_TAG: - if (tagLevel == startTagLevel) - return XML_ERROR_ASYNC_ENTITY; - else { - int len; - const char *rawName; - TAG *tag = tagStack; - tagStack = tag->parent; - tag->parent = freeTagList; - freeTagList = tag; - rawName = s + enc->minBytesPerChar*2; - len = XmlNameLength(enc, rawName); - if (len != tag->rawNameLength - || memcmp(tag->rawName, rawName, len) != 0) { - *eventPP = rawName; - return XML_ERROR_TAG_MISMATCH; - } - --tagLevel; - if (endElementHandler) { - const XML_Char *localPart; - const XML_Char *prefix; - XML_Char *uri; - localPart = tag->name.localPart; - if (ns && localPart) { - /* localPart and prefix may have been overwritten in - tag->name.str, since this points to the binding->uri - buffer which gets re-used; so we have to add them again - */ - uri = (XML_Char *)tag->name.str + tag->name.uriLen; - /* don't need to check for space - already done in storeAtts() */ - while (*localPart) *uri++ = *localPart++; - prefix = (XML_Char *)tag->name.prefix; - if (ns_triplets && prefix) { - *uri++ = namespaceSeparator; - while (*prefix) *uri++ = *prefix++; - } - *uri = XML_T('\0'); - } - endElementHandler(handlerArg, tag->name.str); - } - else if (defaultHandler) - reportDefault(parser, enc, s, next); - while (tag->bindings) { - BINDING *b = tag->bindings; - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); - tag->bindings = tag->bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } - if (tagLevel == 0) - return epilogProcessor(parser, next, end, nextPtr); - } - break; - case XML_TOK_CHAR_REF: - { - int n = XmlCharRefNumber(enc, s); - if (n < 0) - return XML_ERROR_BAD_CHAR_REF; - if (characterDataHandler) { - XML_Char buf[XML_ENCODE_MAX]; - characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); - } - else if (defaultHandler) - reportDefault(parser, enc, s, next); - } - break; - case XML_TOK_XML_DECL: - return XML_ERROR_MISPLACED_XML_PI; - case XML_TOK_DATA_NEWLINE: - if (characterDataHandler) { - XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); - } - else if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - case XML_TOK_CDATA_SECT_OPEN: - { - enum XML_Error result; - if (startCdataSectionHandler) - startCdataSectionHandler(handlerArg); -#if 0 - /* Suppose you doing a transformation on a document that involves - changing only the character data. You set up a defaultHandler - and a characterDataHandler. The defaultHandler simply copies - characters through. The characterDataHandler does the - transformation and writes the characters out escaping them as - necessary. This case will fail to work if we leave out the - following two lines (because & and < inside CDATA sections will - be incorrectly escaped). - - However, now we have a start/endCdataSectionHandler, so it seems - easier to let the user deal with this. - */ - else if (characterDataHandler) - characterDataHandler(handlerArg, dataBuf, 0); -#endif - else if (defaultHandler) - reportDefault(parser, enc, s, next); - result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); - if (result != XML_ERROR_NONE) - return result; - else if (!next) { - processor = cdataSectionProcessor; - return result; - } - } - break; - case XML_TOK_TRAILING_RSQB: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - if (characterDataHandler) { - if (MUST_CONVERT(enc, s)) { - ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); - characterDataHandler(handlerArg, dataBuf, - (int)(dataPtr - (ICHAR *)dataBuf)); - } - else - characterDataHandler(handlerArg, - (XML_Char *)s, - (int)((XML_Char *)end - (XML_Char *)s)); - } - else if (defaultHandler) - reportDefault(parser, enc, s, end); - /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */ - if (startTagLevel == 0) { - *eventPP = end; - return XML_ERROR_NO_ELEMENTS; - } - if (tagLevel != startTagLevel) { - *eventPP = end; - return XML_ERROR_ASYNC_ENTITY; - } - *nextPtr = end; - return XML_ERROR_NONE; - case XML_TOK_DATA_CHARS: - { - XML_CharacterDataHandler charDataHandler = characterDataHandler; - if (charDataHandler) { - if (MUST_CONVERT(enc, s)) { - for (;;) { - ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); - *eventEndPP = s; - charDataHandler(handlerArg, dataBuf, - (int)(dataPtr - (ICHAR *)dataBuf)); - if (s == next) - break; - *eventPP = s; - } - } - else - charDataHandler(handlerArg, - (XML_Char *)s, - (int)((XML_Char *)next - (XML_Char *)s)); - } - else if (defaultHandler) - reportDefault(parser, enc, s, next); - } - break; - case XML_TOK_PI: - if (!reportProcessingInstruction(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_COMMENT: - if (!reportComment(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - break; - default: - if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - } - *eventPP = s = next; - switch (ps_parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: ; - } - } - /* not reached */ -} - -/* Precondition: all arguments must be non-NULL; - Purpose: - - normalize attributes - - check attributes for well-formedness - - generate namespace aware attribute names (URI, prefix) - - build list of attributes for startElementHandler - - default attributes - - process namespace declarations (check and report them) - - generate namespace aware element name (URI, prefix) -*/ -static enum XML_Error -storeAtts(XML_Parser parser, const ENCODING *enc, - const char *attStr, TAG_NAME *tagNamePtr, - BINDING **bindingsPtr) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - ELEMENT_TYPE *elementType; - int nDefaultAtts; - const XML_Char **appAtts; /* the attribute list for the application */ - int attIndex = 0; - int prefixLen; - int i; - int n; - XML_Char *uri; - int nPrefixes = 0; - BINDING *binding; - const XML_Char *localPart; - - /* lookup the element type name */ - elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0); - if (!elementType) { - const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); - if (!name) - return XML_ERROR_NO_MEMORY; - elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name, - sizeof(ELEMENT_TYPE)); - if (!elementType) - return XML_ERROR_NO_MEMORY; - if (ns && !setElementTypePrefix(parser, elementType)) - return XML_ERROR_NO_MEMORY; - } - nDefaultAtts = elementType->nDefaultAtts; - - /* get the attributes from the tokenizer */ - n = XmlGetAttributes(enc, attStr, attsSize, atts); - if (n + nDefaultAtts > attsSize) { - int oldAttsSize = attsSize; - ATTRIBUTE *temp; - attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; - temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - atts = temp; - if (n > oldAttsSize) - XmlGetAttributes(enc, attStr, n, atts); - } - - appAtts = (const XML_Char **)atts; - for (i = 0; i < n; i++) { - /* add the name and value to the attribute list */ - ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, - atts[i].name - + XmlNameLength(enc, atts[i].name)); - if (!attId) - return XML_ERROR_NO_MEMORY; - /* Detect duplicate attributes by their QNames. This does not work when - namespace processing is turned on and different prefixes for the same - namespace are used. For this case we have a check further down. - */ - if ((attId->name)[-1]) { - if (enc == encoding) - eventPtr = atts[i].name; - return XML_ERROR_DUPLICATE_ATTRIBUTE; - } - (attId->name)[-1] = 1; - appAtts[attIndex++] = attId->name; - if (!atts[i].normalized) { - enum XML_Error result; - XML_Bool isCdata = XML_TRUE; - - /* figure out whether declared as other than CDATA */ - if (attId->maybeTokenized) { - int j; - for (j = 0; j < nDefaultAtts; j++) { - if (attId == elementType->defaultAtts[j].id) { - isCdata = elementType->defaultAtts[j].isCdata; - break; - } - } - } - - /* normalize the attribute value */ - result = storeAttributeValue(parser, enc, isCdata, - atts[i].valuePtr, atts[i].valueEnd, - &tempPool); - if (result) - return result; - appAtts[attIndex] = poolStart(&tempPool); - poolFinish(&tempPool); - } - else { - /* the value did not need normalizing */ - appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, - atts[i].valueEnd); - if (appAtts[attIndex] == 0) - return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - } - /* handle prefixed attribute names */ - if (attId->prefix) { - if (attId->xmlns) { - /* deal with namespace declarations here */ - enum XML_Error result = addBinding(parser, attId->prefix, attId, - appAtts[attIndex], bindingsPtr); - if (result) - return result; - --attIndex; - } - else { - /* deal with other prefixed names later */ - attIndex++; - nPrefixes++; - (attId->name)[-1] = 2; - } - } - else - attIndex++; - } - - /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ - nSpecifiedAtts = attIndex; - if (elementType->idAtt && (elementType->idAtt->name)[-1]) { - for (i = 0; i < attIndex; i += 2) - if (appAtts[i] == elementType->idAtt->name) { - idAttIndex = i; - break; - } - } - else - idAttIndex = -1; - - /* do attribute defaulting */ - for (i = 0; i < nDefaultAtts; i++) { - const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; - if (!(da->id->name)[-1] && da->value) { - if (da->id->prefix) { - if (da->id->xmlns) { - enum XML_Error result = addBinding(parser, da->id->prefix, da->id, - da->value, bindingsPtr); - if (result) - return result; - } - else { - (da->id->name)[-1] = 2; - nPrefixes++; - appAtts[attIndex++] = da->id->name; - appAtts[attIndex++] = da->value; - } - } - else { - (da->id->name)[-1] = 1; - appAtts[attIndex++] = da->id->name; - appAtts[attIndex++] = da->value; - } - } - } - appAtts[attIndex] = 0; - - /* expand prefixed attribute names, check for duplicates, - and clear flags that say whether attributes were specified */ - i = 0; - if (nPrefixes) { - int j; /* hash table index */ - unsigned long version = nsAttsVersion; - int nsAttsSize = (int)1 << nsAttsPower; - /* size of hash table must be at least 2 * (# of prefixed attributes) */ - if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */ - NS_ATT *temp; - /* hash table size must also be a power of 2 and >= 8 */ - while (nPrefixes >> nsAttsPower++); - if (nsAttsPower < 3) - nsAttsPower = 3; - nsAttsSize = (int)1 << nsAttsPower; - temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT)); - if (!temp) - return XML_ERROR_NO_MEMORY; - nsAtts = temp; - version = 0; /* force re-initialization of nsAtts hash table */ - } - /* using a version flag saves us from initializing nsAtts every time */ - if (!version) { /* initialize version flags when version wraps around */ - version = INIT_ATTS_VERSION; - for (j = nsAttsSize; j != 0; ) - nsAtts[--j].version = version; - } - nsAttsVersion = --version; - - /* expand prefixed names and check for duplicates */ - for (; i < attIndex; i += 2) { - const XML_Char *s = appAtts[i]; - if (s[-1] == 2) { /* prefixed */ - ATTRIBUTE_ID *id; - const BINDING *b; - unsigned long uriHash = 0; - ((XML_Char *)s)[-1] = 0; /* clear flag */ - id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0); - b = id->prefix->binding; - if (!b) - return XML_ERROR_UNBOUND_PREFIX; - - /* as we expand the name we also calculate its hash value */ - for (j = 0; j < b->uriLen; j++) { - const XML_Char c = b->uri[j]; - if (!poolAppendChar(&tempPool, c)) - return XML_ERROR_NO_MEMORY; - uriHash = CHAR_HASH(uriHash, c); - } - while (*s++ != XML_T(ASCII_COLON)) - ; - do { /* copies null terminator */ - const XML_Char c = *s; - if (!poolAppendChar(&tempPool, *s)) - return XML_ERROR_NO_MEMORY; - uriHash = CHAR_HASH(uriHash, c); - } while (*s++); - - { /* Check hash table for duplicate of expanded name (uriName). - Derived from code in lookup(HASH_TABLE *table, ...). - */ - unsigned char step = 0; - unsigned long mask = nsAttsSize - 1; - j = uriHash & mask; /* index into hash table */ - while (nsAtts[j].version == version) { - /* for speed we compare stored hash values first */ - if (uriHash == nsAtts[j].hash) { - const XML_Char *s1 = poolStart(&tempPool); - const XML_Char *s2 = nsAtts[j].uriName; - /* s1 is null terminated, but not s2 */ - for (; *s1 == *s2 && *s1 != 0; s1++, s2++); - if (*s1 == 0) - return XML_ERROR_DUPLICATE_ATTRIBUTE; - } - if (!step) - step = PROBE_STEP(uriHash, mask, nsAttsPower); - j < step ? (j += nsAttsSize - step) : (j -= step); - } - } - - if (ns_triplets) { /* append namespace separator and prefix */ - tempPool.ptr[-1] = namespaceSeparator; - s = b->prefix->name; - do { - if (!poolAppendChar(&tempPool, *s)) - return XML_ERROR_NO_MEMORY; - } while (*s++); - } - - /* store expanded name in attribute list */ - s = poolStart(&tempPool); - poolFinish(&tempPool); - appAtts[i] = s; - - /* fill empty slot with new version, uriName and hash value */ - nsAtts[j].version = version; - nsAtts[j].hash = uriHash; - nsAtts[j].uriName = s; - - if (!--nPrefixes) { - i += 2; - break; - } - } - else /* not prefixed */ - ((XML_Char *)s)[-1] = 0; /* clear flag */ - } - } - /* clear flags for the remaining attributes */ - for (; i < attIndex; i += 2) - ((XML_Char *)(appAtts[i]))[-1] = 0; - for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) - binding->attId->name[-1] = 0; - - if (!ns) - return XML_ERROR_NONE; - - /* expand the element type name */ - if (elementType->prefix) { - binding = elementType->prefix->binding; - if (!binding) - return XML_ERROR_UNBOUND_PREFIX; - localPart = tagNamePtr->str; - while (*localPart++ != XML_T(ASCII_COLON)) - ; - } - else if (dtd->defaultPrefix.binding) { - binding = dtd->defaultPrefix.binding; - localPart = tagNamePtr->str; - } - else - return XML_ERROR_NONE; - prefixLen = 0; - if (ns_triplets && binding->prefix->name) { - for (; binding->prefix->name[prefixLen++];) - ; /* prefixLen includes null terminator */ - } - tagNamePtr->localPart = localPart; - tagNamePtr->uriLen = binding->uriLen; - tagNamePtr->prefix = binding->prefix->name; - tagNamePtr->prefixLen = prefixLen; - for (i = 0; localPart[i++];) - ; /* i includes null terminator */ - n = i + binding->uriLen + prefixLen; - if (n > binding->uriAlloc) { - TAG *p; - uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char)); - if (!uri) - return XML_ERROR_NO_MEMORY; - binding->uriAlloc = n + EXPAND_SPARE; - memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); - for (p = tagStack; p; p = p->parent) - if (p->name.str == binding->uri) - p->name.str = uri; - FREE(binding->uri); - binding->uri = uri; - } - /* if namespaceSeparator != '\0' then uri includes it already */ - uri = binding->uri + binding->uriLen; - memcpy(uri, localPart, i * sizeof(XML_Char)); - /* we always have a namespace separator between localPart and prefix */ - if (prefixLen) { - uri += i - 1; - *uri = namespaceSeparator; /* replace null terminator */ - memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); - } - tagNamePtr->str = binding->uri; - return XML_ERROR_NONE; -} - -/* addBinding() overwrites the value of prefix->binding without checking. - Therefore one must keep track of the old value outside of addBinding(). -*/ -static enum XML_Error -addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, - const XML_Char *uri, BINDING **bindingsPtr) -{ - static const XML_Char xmlNamespace[] = { - ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, - ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, - ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, - ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, - ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, - ASCII_e, '\0' - }; - static const int xmlLen = - (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1; - static const XML_Char xmlnsNamespace[] = { - ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, - ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, - ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, - ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, - ASCII_SLASH, '\0' - }; - static const int xmlnsLen = - (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1; - - XML_Bool mustBeXML = XML_FALSE; - XML_Bool isXML = XML_TRUE; - XML_Bool isXMLNS = XML_TRUE; - - BINDING *b; - int len; - - /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ - if (*uri == XML_T('\0') && prefix->name) - return XML_ERROR_UNDECLARING_PREFIX; - - if (prefix->name - && prefix->name[0] == XML_T(ASCII_x) - && prefix->name[1] == XML_T(ASCII_m) - && prefix->name[2] == XML_T(ASCII_l)) { - - /* Not allowed to bind xmlns */ - if (prefix->name[3] == XML_T(ASCII_n) - && prefix->name[4] == XML_T(ASCII_s) - && prefix->name[5] == XML_T('\0')) - return XML_ERROR_RESERVED_PREFIX_XMLNS; - - if (prefix->name[3] == XML_T('\0')) - mustBeXML = XML_TRUE; - } - - for (len = 0; uri[len]; len++) { - if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) - isXML = XML_FALSE; - - if (!mustBeXML && isXMLNS - && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) - isXMLNS = XML_FALSE; - } - isXML = isXML && len == xmlLen; - isXMLNS = isXMLNS && len == xmlnsLen; - - if (mustBeXML != isXML) - return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML - : XML_ERROR_RESERVED_NAMESPACE_URI; - - if (isXMLNS) - return XML_ERROR_RESERVED_NAMESPACE_URI; - - if (namespaceSeparator) - len++; - if (freeBindingList) { - b = freeBindingList; - if (len > b->uriAlloc) { - XML_Char *temp = (XML_Char *)REALLOC(b->uri, - sizeof(XML_Char) * (len + EXPAND_SPARE)); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - b->uri = temp; - b->uriAlloc = len + EXPAND_SPARE; - } - freeBindingList = b->nextTagBinding; - } - else { - b = (BINDING *)MALLOC(sizeof(BINDING)); - if (!b) - return XML_ERROR_NO_MEMORY; - b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE)); - if (!b->uri) { - FREE(b); - return XML_ERROR_NO_MEMORY; - } - b->uriAlloc = len + EXPAND_SPARE; - } - b->uriLen = len; - memcpy(b->uri, uri, len * sizeof(XML_Char)); - if (namespaceSeparator) - b->uri[len - 1] = namespaceSeparator; - b->prefix = prefix; - b->attId = attId; - b->prevPrefixBinding = prefix->binding; - /* NULL binding when default namespace undeclared */ - if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix) - prefix->binding = NULL; - else - prefix->binding = b; - b->nextTagBinding = *bindingsPtr; - *bindingsPtr = b; - /* if attId == NULL then we are not starting a namespace scope */ - if (attId && startNamespaceDeclHandler) - startNamespaceDeclHandler(handlerArg, prefix->name, - prefix->binding ? uri : 0); - return XML_ERROR_NONE; -} - -/* The idea here is to avoid using stack for each CDATA section when - the whole file is parsed with one call. -*/ -static enum XML_Error PTRCALL -cdataSectionProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doCdataSection(parser, encoding, &start, end, - endPtr, (XML_Bool)!ps_finalBuffer); - if (result != XML_ERROR_NONE) - return result; - if (start) { - if (parentParser) { /* we are parsing an external entity */ - processor = externalEntityContentProcessor; - return externalEntityContentProcessor(parser, start, end, endPtr); - } - else { - processor = contentProcessor; - return contentProcessor(parser, start, end, endPtr); - } - } - return result; -} - -/* startPtr gets set to non-null if the section is closed, and to null if - the section is not yet closed. -*/ -static enum XML_Error -doCdataSection(XML_Parser parser, - const ENCODING *enc, - const char **startPtr, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ - const char *s = *startPtr; - const char **eventPP; - const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; - *eventPP = s; - eventEndPP = &eventEndPtr; - } - else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); - } - *eventPP = s; - *startPtr = NULL; - - for (;;) { - const char *next; - int tok = XmlCdataSectionTok(enc, s, end, &next); - *eventEndPP = next; - switch (tok) { - case XML_TOK_CDATA_SECT_CLOSE: - if (endCdataSectionHandler) - endCdataSectionHandler(handlerArg); -#if 0 - /* see comment under XML_TOK_CDATA_SECT_OPEN */ - else if (characterDataHandler) - characterDataHandler(handlerArg, dataBuf, 0); -#endif - else if (defaultHandler) - reportDefault(parser, enc, s, next); - *startPtr = next; - *nextPtr = next; - if (ps_parsing == XML_FINISHED) - return XML_ERROR_ABORTED; - else - return XML_ERROR_NONE; - case XML_TOK_DATA_NEWLINE: - if (characterDataHandler) { - XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); - } - else if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - case XML_TOK_DATA_CHARS: - { - XML_CharacterDataHandler charDataHandler = characterDataHandler; - if (charDataHandler) { - if (MUST_CONVERT(enc, s)) { - for (;;) { - ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); - *eventEndPP = next; - charDataHandler(handlerArg, dataBuf, - (int)(dataPtr - (ICHAR *)dataBuf)); - if (s == next) - break; - *eventPP = s; - } - } - else - charDataHandler(handlerArg, - (XML_Char *)s, - (int)((XML_Char *)next - (XML_Char *)s)); - } - else if (defaultHandler) - reportDefault(parser, enc, s, next); - } - break; - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_PARTIAL: - case XML_TOK_NONE: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_CDATA_SECTION; - default: - *eventPP = next; - return XML_ERROR_UNEXPECTED_STATE; - } - - *eventPP = s = next; - switch (ps_parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: ; - } - } - /* not reached */ -} - -#ifdef XML_DTD - -/* The idea here is to avoid using stack for each IGNORE section when - the whole file is parsed with one call. -*/ -static enum XML_Error PTRCALL -ignoreSectionProcessor(XML_Parser parser, - const char *start, - const char *end, - const char **endPtr) -{ - enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, - endPtr, (XML_Bool)!ps_finalBuffer); - if (result != XML_ERROR_NONE) - return result; - if (start) { - processor = prologProcessor; - return prologProcessor(parser, start, end, endPtr); - } - return result; -} - -/* startPtr gets set to non-null is the section is closed, and to null - if the section is not yet closed. -*/ -static enum XML_Error -doIgnoreSection(XML_Parser parser, - const ENCODING *enc, - const char **startPtr, - const char *end, - const char **nextPtr, - XML_Bool haveMore) -{ - const char *next; - int tok; - const char *s = *startPtr; - const char **eventPP; - const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; - *eventPP = s; - eventEndPP = &eventEndPtr; - } - else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); - } - *eventPP = s; - *startPtr = NULL; - tok = XmlIgnoreSectionTok(enc, s, end, &next); - *eventEndPP = next; - switch (tok) { - case XML_TOK_IGNORE_SECT: - if (defaultHandler) - reportDefault(parser, enc, s, next); - *startPtr = next; - *nextPtr = next; - if (ps_parsing == XML_FINISHED) - return XML_ERROR_ABORTED; - else - return XML_ERROR_NONE; - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_PARTIAL: - case XML_TOK_NONE: - if (haveMore) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ - default: - *eventPP = next; - return XML_ERROR_UNEXPECTED_STATE; - } - /* not reached */ -} - -#endif /* XML_DTD */ - -static enum XML_Error -initializeEncoding(XML_Parser parser) -{ - const char *s; -#ifdef XML_UNICODE - char encodingBuf[128]; - if (!protocolEncodingName) - s = NULL; - else { - int i; - for (i = 0; protocolEncodingName[i]; i++) { - if (i == sizeof(encodingBuf) - 1 - || (protocolEncodingName[i] & ~0x7f) != 0) { - encodingBuf[0] = '\0'; - break; - } - encodingBuf[i] = (char)protocolEncodingName[i]; - } - encodingBuf[i] = '\0'; - s = encodingBuf; - } -#else - s = protocolEncodingName; -#endif - if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) - return XML_ERROR_NONE; - return handleUnknownEncoding(parser, protocolEncodingName); -} - -static enum XML_Error -processXmlDecl(XML_Parser parser, int isGeneralTextEntity, - const char *s, const char *next) -{ - const char *encodingName = NULL; - const XML_Char *storedEncName = NULL; - const ENCODING *newEncoding = NULL; - const char *version = NULL; - const char *versionend; - const XML_Char *storedversion = NULL; - int standalone = -1; - if (!(ns - ? XmlParseXmlDeclNS - : XmlParseXmlDecl)(isGeneralTextEntity, - encoding, - s, - next, - &eventPtr, - &version, - &versionend, - &encodingName, - &newEncoding, - &standalone)) { - if (isGeneralTextEntity) - return XML_ERROR_TEXT_DECL; - else - return XML_ERROR_XML_DECL; - } - if (!isGeneralTextEntity && standalone == 1) { - _dtd->standalone = XML_TRUE; -#ifdef XML_DTD - if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) - paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; -#endif /* XML_DTD */ - } - if (xmlDeclHandler) { - if (encodingName != NULL) { - storedEncName = poolStoreString(&temp2Pool, - encoding, - encodingName, - encodingName - + XmlNameLength(encoding, encodingName)); - if (!storedEncName) - return XML_ERROR_NO_MEMORY; - poolFinish(&temp2Pool); - } - if (version) { - storedversion = poolStoreString(&temp2Pool, - encoding, - version, - versionend - encoding->minBytesPerChar); - if (!storedversion) - return XML_ERROR_NO_MEMORY; - } - xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); - } - else if (defaultHandler) - reportDefault(parser, encoding, s, next); - if (protocolEncodingName == NULL) { - if (newEncoding) { - if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { - eventPtr = encodingName; - return XML_ERROR_INCORRECT_ENCODING; - } - encoding = newEncoding; - } - else if (encodingName) { - enum XML_Error result; - if (!storedEncName) { - storedEncName = poolStoreString( - &temp2Pool, encoding, encodingName, - encodingName + XmlNameLength(encoding, encodingName)); - if (!storedEncName) - return XML_ERROR_NO_MEMORY; - } - result = handleUnknownEncoding(parser, storedEncName); - poolClear(&temp2Pool); - if (result == XML_ERROR_UNKNOWN_ENCODING) - eventPtr = encodingName; - return result; - } - } - - if (storedEncName || storedversion) - poolClear(&temp2Pool); - - return XML_ERROR_NONE; -} - -static enum XML_Error -handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) -{ - if (unknownEncodingHandler) { - XML_Encoding info; - int i; - for (i = 0; i < 256; i++) - info.map[i] = -1; - info.convert = NULL; - info.data = NULL; - info.release = NULL; - if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, - &info)) { - ENCODING *enc; - unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); - if (!unknownEncodingMem) { - if (info.release) - info.release(info.data); - return XML_ERROR_NO_MEMORY; - } - enc = (ns - ? XmlInitUnknownEncodingNS - : XmlInitUnknownEncoding)(unknownEncodingMem, - info.map, - info.convert, - info.data); - if (enc) { - unknownEncodingData = info.data; - unknownEncodingRelease = info.release; - encoding = enc; - return XML_ERROR_NONE; - } - } - if (info.release != NULL) - info.release(info.data); - } - return XML_ERROR_UNKNOWN_ENCODING; -} - -static enum XML_Error PTRCALL -prologInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - enum XML_Error result = initializeEncoding(parser); - if (result != XML_ERROR_NONE) - return result; - processor = prologProcessor; - return prologProcessor(parser, s, end, nextPtr); -} - -#ifdef XML_DTD - -static enum XML_Error PTRCALL -externalParEntInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - enum XML_Error result = initializeEncoding(parser); - if (result != XML_ERROR_NONE) - return result; - - /* we know now that XML_Parse(Buffer) has been called, - so we consider the external parameter entity read */ - _dtd->paramEntityRead = XML_TRUE; - - if (prologState.inEntityValue) { - processor = entityValueInitProcessor; - return entityValueInitProcessor(parser, s, end, nextPtr); - } - else { - processor = externalParEntProcessor; - return externalParEntProcessor(parser, s, end, nextPtr); - } -} - -static enum XML_Error PTRCALL -entityValueInitProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - int tok; - const char *start = s; - const char *next = start; - eventPtr = start; - - for (;;) { - tok = XmlPrologTok(encoding, start, end, &next); - eventEndPtr = next; - if (tok <= 0) { - if (!ps_finalBuffer && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ - default: - break; - } - /* found end of entity value - can store it now */ - return storeEntityValue(parser, encoding, s, end); - } - else if (tok == XML_TOK_XML_DECL) { - enum XML_Error result; - result = processXmlDecl(parser, 0, start, next); - if (result != XML_ERROR_NONE) - return result; - switch (ps_parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: - *nextPtr = next; - } - /* stop scanning for text declaration - we found one */ - processor = entityValueProcessor; - return entityValueProcessor(parser, next, end, nextPtr); - } - /* If we are at the end of the buffer, this would cause XmlPrologTok to - return XML_TOK_NONE on the next call, which would then cause the - function to exit with *nextPtr set to s - that is what we want for other - tokens, but not for the BOM - we would rather like to skip it; - then, when this routine is entered the next time, XmlPrologTok will - return XML_TOK_INVALID, since the BOM is still in the buffer - */ - else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) { - *nextPtr = next; - return XML_ERROR_NONE; - } - start = next; - eventPtr = start; - } -} - -static enum XML_Error PTRCALL -externalParEntProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - const char *next = s; - int tok; - - tok = XmlPrologTok(encoding, s, end, &next); - if (tok <= 0) { - if (!ps_finalBuffer && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ - default: - break; - } - } - /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. - However, when parsing an external subset, doProlog will not accept a BOM - as valid, and report a syntax error, so we have to skip the BOM - */ - else if (tok == XML_TOK_BOM) { - s = next; - tok = XmlPrologTok(encoding, s, end, &next); - } - - processor = prologProcessor; - return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer); -} - -static enum XML_Error PTRCALL -entityValueProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - const char *start = s; - const char *next = s; - const ENCODING *enc = encoding; - int tok; - - for (;;) { - tok = XmlPrologTok(enc, start, end, &next); - if (tok <= 0) { - if (!ps_finalBuffer && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: /* start == end */ - default: - break; - } - /* found end of entity value - can store it now */ - return storeEntityValue(parser, enc, s, end); - } - start = next; - } -} - -#endif /* XML_DTD */ - -static enum XML_Error PTRCALL -prologProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - const char *next = s; - int tok = XmlPrologTok(encoding, s, end, &next); - return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer); -} - -static enum XML_Error -doProlog(XML_Parser parser, - const ENCODING *enc, - const char *s, - const char *end, - int tok, - const char *next, - const char **nextPtr, - XML_Bool haveMore) -{ -#ifdef XML_DTD - static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' }; -#endif /* XML_DTD */ - static const XML_Char atypeCDATA[] = - { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; - static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' }; - static const XML_Char atypeIDREF[] = - { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; - static const XML_Char atypeIDREFS[] = - { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; - static const XML_Char atypeENTITY[] = - { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; - static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N, - ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; - static const XML_Char atypeNMTOKEN[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; - static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, - ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; - static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T, - ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' }; - static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' }; - static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' }; - - /* save one level of indirection */ - DTD * const dtd = _dtd; - - const char **eventPP; - const char **eventEndPP; - enum XML_Content_Quant quant; - - if (enc == encoding) { - eventPP = &eventPtr; - eventEndPP = &eventEndPtr; - } - else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); - } - - for (;;) { - int role; - XML_Bool handleDefault = XML_TRUE; - *eventPP = s; - *eventEndPP = next; - if (tok <= 0) { - if (haveMore && tok != XML_TOK_INVALID) { - *nextPtr = s; - return XML_ERROR_NONE; - } - switch (tok) { - case XML_TOK_INVALID: - *eventPP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_NONE: -#ifdef XML_DTD - /* for internal PE NOT referenced between declarations */ - if (enc != encoding && !openInternalEntities->betweenDecl) { - *nextPtr = s; - return XML_ERROR_NONE; - } - /* WFC: PE Between Declarations - must check that PE contains - complete markup, not only for external PEs, but also for - internal PEs if the reference occurs between declarations. - */ - if (isParamEntity || enc != encoding) { - if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) - == XML_ROLE_ERROR) - return XML_ERROR_INCOMPLETE_PE; - *nextPtr = s; - return XML_ERROR_NONE; - } -#endif /* XML_DTD */ - return XML_ERROR_NO_ELEMENTS; - default: - tok = -tok; - next = end; - break; - } - } - role = XmlTokenRole(&prologState, tok, s, next, enc); - switch (role) { - case XML_ROLE_XML_DECL: - { - enum XML_Error result = processXmlDecl(parser, 0, s, next); - if (result != XML_ERROR_NONE) - return result; - enc = encoding; - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_DOCTYPE_NAME: - if (startDoctypeDeclHandler) { - doctypeName = poolStoreString(&tempPool, enc, s, next); - if (!doctypeName) - return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - doctypePubid = NULL; - handleDefault = XML_FALSE; - } - doctypeSysid = NULL; /* always initialize to NULL */ - break; - case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: - if (startDoctypeDeclHandler) { - startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, - doctypePubid, 1); - doctypeName = NULL; - poolClear(&tempPool); - handleDefault = XML_FALSE; - } - break; -#ifdef XML_DTD - case XML_ROLE_TEXT_DECL: - { - enum XML_Error result = processXmlDecl(parser, 1, s, next); - if (result != XML_ERROR_NONE) - return result; - enc = encoding; - handleDefault = XML_FALSE; - } - break; -#endif /* XML_DTD */ - case XML_ROLE_DOCTYPE_PUBLIC_ID: -#ifdef XML_DTD - useForeignDTD = XML_FALSE; - declEntity = (ENTITY *)lookup(&dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!declEntity) - return XML_ERROR_NO_MEMORY; -#endif /* XML_DTD */ - dtd->hasParamEntityRefs = XML_TRUE; - if (startDoctypeDeclHandler) { - if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_PUBLICID; - doctypePubid = poolStoreString(&tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!doctypePubid) - return XML_ERROR_NO_MEMORY; - normalizePublicId((XML_Char *)doctypePubid); - poolFinish(&tempPool); - handleDefault = XML_FALSE; - goto alreadyChecked; - } - /* fall through */ - case XML_ROLE_ENTITY_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_PUBLICID; - alreadyChecked: - if (dtd->keepProcessing && declEntity) { - XML_Char *tem = poolStoreString(&dtd->pool, - enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!tem) - return XML_ERROR_NO_MEMORY; - normalizePublicId(tem); - declEntity->publicId = tem; - poolFinish(&dtd->pool); - if (entityDeclHandler) - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_DOCTYPE_CLOSE: - if (doctypeName) { - startDoctypeDeclHandler(handlerArg, doctypeName, - doctypeSysid, doctypePubid, 0); - poolClear(&tempPool); - handleDefault = XML_FALSE; - } - /* doctypeSysid will be non-NULL in the case of a previous - XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler - was not set, indicating an external subset - */ -#ifdef XML_DTD - if (doctypeSysid || useForeignDTD) { - XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; - dtd->hasParamEntityRefs = XML_TRUE; - if (paramEntityParsing && externalEntityRefHandler) { - ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!entity) - return XML_ERROR_NO_MEMORY; - if (useForeignDTD) - entity->base = curBase; - dtd->paramEntityRead = XML_FALSE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - if (dtd->paramEntityRead) { - if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg)) - return XML_ERROR_NOT_STANDALONE; - } - /* if we didn't read the foreign DTD then this means that there - is no external subset and we must reset dtd->hasParamEntityRefs - */ - else if (!doctypeSysid) - dtd->hasParamEntityRefs = hadParamEntityRefs; - /* end of DTD - no need to update dtd->keepProcessing */ - } - useForeignDTD = XML_FALSE; - } -#endif /* XML_DTD */ - if (endDoctypeDeclHandler) { - endDoctypeDeclHandler(handlerArg); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_INSTANCE_START: -#ifdef XML_DTD - /* if there is no DOCTYPE declaration then now is the - last chance to read the foreign DTD - */ - if (useForeignDTD) { - XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; - dtd->hasParamEntityRefs = XML_TRUE; - if (paramEntityParsing && externalEntityRefHandler) { - ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!entity) - return XML_ERROR_NO_MEMORY; - entity->base = curBase; - dtd->paramEntityRead = XML_FALSE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - if (dtd->paramEntityRead) { - if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg)) - return XML_ERROR_NOT_STANDALONE; - } - /* if we didn't read the foreign DTD then this means that there - is no external subset and we must reset dtd->hasParamEntityRefs - */ - else - dtd->hasParamEntityRefs = hadParamEntityRefs; - /* end of DTD - no need to update dtd->keepProcessing */ - } - } -#endif /* XML_DTD */ - processor = contentProcessor; - return contentProcessor(parser, s, end, nextPtr); - case XML_ROLE_ATTLIST_ELEMENT_NAME: - declElementType = getElementType(parser, enc, s, next); - if (!declElementType) - return XML_ERROR_NO_MEMORY; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_NAME: - declAttributeId = getAttributeId(parser, enc, s, next); - if (!declAttributeId) - return XML_ERROR_NO_MEMORY; - declAttributeIsCdata = XML_FALSE; - declAttributeType = NULL; - declAttributeIsId = XML_FALSE; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_CDATA: - declAttributeIsCdata = XML_TRUE; - declAttributeType = atypeCDATA; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_ID: - declAttributeIsId = XML_TRUE; - declAttributeType = atypeID; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_IDREF: - declAttributeType = atypeIDREF; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: - declAttributeType = atypeIDREFS; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: - declAttributeType = atypeENTITY; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: - declAttributeType = atypeENTITIES; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: - declAttributeType = atypeNMTOKEN; - goto checkAttListDeclHandler; - case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: - declAttributeType = atypeNMTOKENS; - checkAttListDeclHandler: - if (dtd->keepProcessing && attlistDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ATTRIBUTE_ENUM_VALUE: - case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: - if (dtd->keepProcessing && attlistDeclHandler) { - const XML_Char *prefix; - if (declAttributeType) { - prefix = enumValueSep; - } - else { - prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE - ? notationPrefix - : enumValueStart); - } - if (!poolAppendString(&tempPool, prefix)) - return XML_ERROR_NO_MEMORY; - if (!poolAppend(&tempPool, enc, s, next)) - return XML_ERROR_NO_MEMORY; - declAttributeType = tempPool.start; - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: - case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: - if (dtd->keepProcessing) { - if (!defineAttribute(declElementType, declAttributeId, - declAttributeIsCdata, declAttributeIsId, - 0, parser)) - return XML_ERROR_NO_MEMORY; - if (attlistDeclHandler && declAttributeType) { - if (*declAttributeType == XML_T(ASCII_LPAREN) - || (*declAttributeType == XML_T(ASCII_N) - && declAttributeType[1] == XML_T(ASCII_O))) { - /* Enumerated or Notation type */ - if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&tempPool, XML_T('\0'))) - return XML_ERROR_NO_MEMORY; - declAttributeType = tempPool.start; - poolFinish(&tempPool); - } - *eventEndPP = s; - attlistDeclHandler(handlerArg, declElementType->name, - declAttributeId->name, declAttributeType, - 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); - poolClear(&tempPool); - handleDefault = XML_FALSE; - } - } - break; - case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: - case XML_ROLE_FIXED_ATTRIBUTE_VALUE: - if (dtd->keepProcessing) { - const XML_Char *attVal; - enum XML_Error result = - storeAttributeValue(parser, enc, declAttributeIsCdata, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar, - &dtd->pool); - if (result) - return result; - attVal = poolStart(&dtd->pool); - poolFinish(&dtd->pool); - /* ID attributes aren't allowed to have a default */ - if (!defineAttribute(declElementType, declAttributeId, - declAttributeIsCdata, XML_FALSE, attVal, parser)) - return XML_ERROR_NO_MEMORY; - if (attlistDeclHandler && declAttributeType) { - if (*declAttributeType == XML_T(ASCII_LPAREN) - || (*declAttributeType == XML_T(ASCII_N) - && declAttributeType[1] == XML_T(ASCII_O))) { - /* Enumerated or Notation type */ - if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) - || !poolAppendChar(&tempPool, XML_T('\0'))) - return XML_ERROR_NO_MEMORY; - declAttributeType = tempPool.start; - poolFinish(&tempPool); - } - *eventEndPP = s; - attlistDeclHandler(handlerArg, declElementType->name, - declAttributeId->name, declAttributeType, - attVal, - role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); - poolClear(&tempPool); - handleDefault = XML_FALSE; - } - } - break; - case XML_ROLE_ENTITY_VALUE: - if (dtd->keepProcessing) { - enum XML_Error result = storeEntityValue(parser, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (declEntity) { - declEntity->textPtr = poolStart(&dtd->entityValuePool); - declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); - poolFinish(&dtd->entityValuePool); - if (entityDeclHandler) { - *eventEndPP = s; - entityDeclHandler(handlerArg, - declEntity->name, - declEntity->is_param, - declEntity->textPtr, - declEntity->textLen, - curBase, 0, 0, 0); - handleDefault = XML_FALSE; - } - } - else - poolDiscard(&dtd->entityValuePool); - if (result != XML_ERROR_NONE) - return result; - } - break; - case XML_ROLE_DOCTYPE_SYSTEM_ID: -#ifdef XML_DTD - useForeignDTD = XML_FALSE; -#endif /* XML_DTD */ - dtd->hasParamEntityRefs = XML_TRUE; - if (startDoctypeDeclHandler) { - doctypeSysid = poolStoreString(&tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (doctypeSysid == NULL) - return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - handleDefault = XML_FALSE; - } -#ifdef XML_DTD - else - /* use externalSubsetName to make doctypeSysid non-NULL - for the case where no startDoctypeDeclHandler is set */ - doctypeSysid = externalSubsetName; -#endif /* XML_DTD */ - if (!dtd->standalone -#ifdef XML_DTD - && !paramEntityParsing -#endif /* XML_DTD */ - && notStandaloneHandler - && !notStandaloneHandler(handlerArg)) - return XML_ERROR_NOT_STANDALONE; -#ifndef XML_DTD - break; -#else /* XML_DTD */ - if (!declEntity) { - declEntity = (ENTITY *)lookup(&dtd->paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!declEntity) - return XML_ERROR_NO_MEMORY; - declEntity->publicId = NULL; - } - /* fall through */ -#endif /* XML_DTD */ - case XML_ROLE_ENTITY_SYSTEM_ID: - if (dtd->keepProcessing && declEntity) { - declEntity->systemId = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!declEntity->systemId) - return XML_ERROR_NO_MEMORY; - declEntity->base = curBase; - poolFinish(&dtd->pool); - if (entityDeclHandler) - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_ENTITY_COMPLETE: - if (dtd->keepProcessing && declEntity && entityDeclHandler) { - *eventEndPP = s; - entityDeclHandler(handlerArg, - declEntity->name, - declEntity->is_param, - 0,0, - declEntity->base, - declEntity->systemId, - declEntity->publicId, - 0); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_ENTITY_NOTATION_NAME: - if (dtd->keepProcessing && declEntity) { - declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); - if (!declEntity->notation) - return XML_ERROR_NO_MEMORY; - poolFinish(&dtd->pool); - if (unparsedEntityDeclHandler) { - *eventEndPP = s; - unparsedEntityDeclHandler(handlerArg, - declEntity->name, - declEntity->base, - declEntity->systemId, - declEntity->publicId, - declEntity->notation); - handleDefault = XML_FALSE; - } - else if (entityDeclHandler) { - *eventEndPP = s; - entityDeclHandler(handlerArg, - declEntity->name, - 0,0,0, - declEntity->base, - declEntity->systemId, - declEntity->publicId, - declEntity->notation); - handleDefault = XML_FALSE; - } - } - break; - case XML_ROLE_GENERAL_ENTITY_NAME: - { - if (XmlPredefinedEntityName(enc, s, next)) { - declEntity = NULL; - break; - } - if (dtd->keepProcessing) { - const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); - if (!name) - return XML_ERROR_NO_MEMORY; - declEntity = (ENTITY *)lookup(&dtd->generalEntities, name, - sizeof(ENTITY)); - if (!declEntity) - return XML_ERROR_NO_MEMORY; - if (declEntity->name != name) { - poolDiscard(&dtd->pool); - declEntity = NULL; - } - else { - poolFinish(&dtd->pool); - declEntity->publicId = NULL; - declEntity->is_param = XML_FALSE; - /* if we have a parent parser or are reading an internal parameter - entity, then the entity declaration is not considered "internal" - */ - declEntity->is_internal = !(parentParser || openInternalEntities); - if (entityDeclHandler) - handleDefault = XML_FALSE; - } - } - else { - poolDiscard(&dtd->pool); - declEntity = NULL; - } - } - break; - case XML_ROLE_PARAM_ENTITY_NAME: -#ifdef XML_DTD - if (dtd->keepProcessing) { - const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); - if (!name) - return XML_ERROR_NO_MEMORY; - declEntity = (ENTITY *)lookup(&dtd->paramEntities, - name, sizeof(ENTITY)); - if (!declEntity) - return XML_ERROR_NO_MEMORY; - if (declEntity->name != name) { - poolDiscard(&dtd->pool); - declEntity = NULL; - } - else { - poolFinish(&dtd->pool); - declEntity->publicId = NULL; - declEntity->is_param = XML_TRUE; - /* if we have a parent parser or are reading an internal parameter - entity, then the entity declaration is not considered "internal" - */ - declEntity->is_internal = !(parentParser || openInternalEntities); - if (entityDeclHandler) - handleDefault = XML_FALSE; - } - } - else { - poolDiscard(&dtd->pool); - declEntity = NULL; - } -#else /* not XML_DTD */ - declEntity = NULL; -#endif /* XML_DTD */ - break; - case XML_ROLE_NOTATION_NAME: - declNotationPublicId = NULL; - declNotationName = NULL; - if (notationDeclHandler) { - declNotationName = poolStoreString(&tempPool, enc, s, next); - if (!declNotationName) - return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_NOTATION_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, eventPP)) - return XML_ERROR_PUBLICID; - if (declNotationName) { /* means notationDeclHandler != NULL */ - XML_Char *tem = poolStoreString(&tempPool, - enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!tem) - return XML_ERROR_NO_MEMORY; - normalizePublicId(tem); - declNotationPublicId = tem; - poolFinish(&tempPool); - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_NOTATION_SYSTEM_ID: - if (declNotationName && notationDeclHandler) { - const XML_Char *systemId - = poolStoreString(&tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!systemId) - return XML_ERROR_NO_MEMORY; - *eventEndPP = s; - notationDeclHandler(handlerArg, - declNotationName, - curBase, - systemId, - declNotationPublicId); - handleDefault = XML_FALSE; - } - poolClear(&tempPool); - break; - case XML_ROLE_NOTATION_NO_SYSTEM_ID: - if (declNotationPublicId && notationDeclHandler) { - *eventEndPP = s; - notationDeclHandler(handlerArg, - declNotationName, - curBase, - 0, - declNotationPublicId); - handleDefault = XML_FALSE; - } - poolClear(&tempPool); - break; - case XML_ROLE_ERROR: - switch (tok) { - case XML_TOK_PARAM_ENTITY_REF: - /* PE references in internal subset are - not allowed within declarations. */ - return XML_ERROR_PARAM_ENTITY_REF; - case XML_TOK_XML_DECL: - return XML_ERROR_MISPLACED_XML_PI; - default: - return XML_ERROR_SYNTAX; - } -#ifdef XML_DTD - case XML_ROLE_IGNORE_SECT: - { - enum XML_Error result; - if (defaultHandler) - reportDefault(parser, enc, s, next); - handleDefault = XML_FALSE; - result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); - if (result != XML_ERROR_NONE) - return result; - else if (!next) { - processor = ignoreSectionProcessor; - return result; - } - } - break; -#endif /* XML_DTD */ - case XML_ROLE_GROUP_OPEN: - if (prologState.level >= groupSize) { - if (groupSize) { - char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - groupConnector = temp; - if (dtd->scaffIndex) { - int *temp = (int *)REALLOC(dtd->scaffIndex, - groupSize * sizeof(int)); - if (temp == NULL) - return XML_ERROR_NO_MEMORY; - dtd->scaffIndex = temp; - } - } - else { - groupConnector = (char *)MALLOC(groupSize = 32); - if (!groupConnector) - return XML_ERROR_NO_MEMORY; - } - } - groupConnector[prologState.level] = 0; - if (dtd->in_eldecl) { - int myindex = nextScaffoldPart(parser); - if (myindex < 0) - return XML_ERROR_NO_MEMORY; - dtd->scaffIndex[dtd->scaffLevel] = myindex; - dtd->scaffLevel++; - dtd->scaffold[myindex].type = XML_CTYPE_SEQ; - if (elementDeclHandler) - handleDefault = XML_FALSE; - } - break; - case XML_ROLE_GROUP_SEQUENCE: - if (groupConnector[prologState.level] == ASCII_PIPE) - return XML_ERROR_SYNTAX; - groupConnector[prologState.level] = ASCII_COMMA; - if (dtd->in_eldecl && elementDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_GROUP_CHOICE: - if (groupConnector[prologState.level] == ASCII_COMMA) - return XML_ERROR_SYNTAX; - if (dtd->in_eldecl - && !groupConnector[prologState.level] - && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type - != XML_CTYPE_MIXED) - ) { - dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type - = XML_CTYPE_CHOICE; - if (elementDeclHandler) - handleDefault = XML_FALSE; - } - groupConnector[prologState.level] = ASCII_PIPE; - break; - case XML_ROLE_PARAM_ENTITY_REF: -#ifdef XML_DTD - case XML_ROLE_INNER_PARAM_ENTITY_REF: - dtd->hasParamEntityRefs = XML_TRUE; - if (!paramEntityParsing) - dtd->keepProcessing = dtd->standalone; - else { - const XML_Char *name; - ENTITY *entity; - name = poolStoreString(&dtd->pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); - poolDiscard(&dtd->pool); - /* first, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal, - otherwise call the skipped entity handler - */ - if (prologState.documentEntity && - (dtd->standalone - ? !openInternalEntities - : !dtd->hasParamEntityRefs)) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) - return XML_ERROR_ENTITY_DECLARED_IN_PE; - } - else if (!entity) { - dtd->keepProcessing = dtd->standalone; - /* cannot report skipped entities in declarations */ - if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { - skippedEntityHandler(handlerArg, name, 1); - handleDefault = XML_FALSE; - } - break; - } - if (entity->open) - return XML_ERROR_RECURSIVE_ENTITY_REF; - if (entity->textPtr) { - enum XML_Error result; - XML_Bool betweenDecl = - (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); - result = processInternalEntity(parser, entity, betweenDecl); - if (result != XML_ERROR_NONE) - return result; - handleDefault = XML_FALSE; - break; - } - if (externalEntityRefHandler) { - dtd->paramEntityRead = XML_FALSE; - entity->open = XML_TRUE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { - entity->open = XML_FALSE; - return XML_ERROR_EXTERNAL_ENTITY_HANDLING; - } - entity->open = XML_FALSE; - handleDefault = XML_FALSE; - if (!dtd->paramEntityRead) { - dtd->keepProcessing = dtd->standalone; - break; - } - } - else { - dtd->keepProcessing = dtd->standalone; - break; - } - } -#endif /* XML_DTD */ - if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg)) - return XML_ERROR_NOT_STANDALONE; - break; - - /* Element declaration stuff */ - - case XML_ROLE_ELEMENT_NAME: - if (elementDeclHandler) { - declElementType = getElementType(parser, enc, s, next); - if (!declElementType) - return XML_ERROR_NO_MEMORY; - dtd->scaffLevel = 0; - dtd->scaffCount = 0; - dtd->in_eldecl = XML_TRUE; - handleDefault = XML_FALSE; - } - break; - - case XML_ROLE_CONTENT_ANY: - case XML_ROLE_CONTENT_EMPTY: - if (dtd->in_eldecl) { - if (elementDeclHandler) { - XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); - if (!content) - return XML_ERROR_NO_MEMORY; - content->quant = XML_CQUANT_NONE; - content->name = NULL; - content->numchildren = 0; - content->children = NULL; - content->type = ((role == XML_ROLE_CONTENT_ANY) ? - XML_CTYPE_ANY : - XML_CTYPE_EMPTY); - *eventEndPP = s; - elementDeclHandler(handlerArg, declElementType->name, content); - handleDefault = XML_FALSE; - } - dtd->in_eldecl = XML_FALSE; - } - break; - - case XML_ROLE_CONTENT_PCDATA: - if (dtd->in_eldecl) { - dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type - = XML_CTYPE_MIXED; - if (elementDeclHandler) - handleDefault = XML_FALSE; - } - break; - - case XML_ROLE_CONTENT_ELEMENT: - quant = XML_CQUANT_NONE; - goto elementContent; - case XML_ROLE_CONTENT_ELEMENT_OPT: - quant = XML_CQUANT_OPT; - goto elementContent; - case XML_ROLE_CONTENT_ELEMENT_REP: - quant = XML_CQUANT_REP; - goto elementContent; - case XML_ROLE_CONTENT_ELEMENT_PLUS: - quant = XML_CQUANT_PLUS; - elementContent: - if (dtd->in_eldecl) { - ELEMENT_TYPE *el; - const XML_Char *name; - int nameLen; - const char *nxt = (quant == XML_CQUANT_NONE - ? next - : next - enc->minBytesPerChar); - int myindex = nextScaffoldPart(parser); - if (myindex < 0) - return XML_ERROR_NO_MEMORY; - dtd->scaffold[myindex].type = XML_CTYPE_NAME; - dtd->scaffold[myindex].quant = quant; - el = getElementType(parser, enc, s, nxt); - if (!el) - return XML_ERROR_NO_MEMORY; - name = el->name; - dtd->scaffold[myindex].name = name; - nameLen = 0; - for (; name[nameLen++]; ); - dtd->contentStringLen += nameLen; - if (elementDeclHandler) - handleDefault = XML_FALSE; - } - break; - - case XML_ROLE_GROUP_CLOSE: - quant = XML_CQUANT_NONE; - goto closeGroup; - case XML_ROLE_GROUP_CLOSE_OPT: - quant = XML_CQUANT_OPT; - goto closeGroup; - case XML_ROLE_GROUP_CLOSE_REP: - quant = XML_CQUANT_REP; - goto closeGroup; - case XML_ROLE_GROUP_CLOSE_PLUS: - quant = XML_CQUANT_PLUS; - closeGroup: - if (dtd->in_eldecl) { - if (elementDeclHandler) - handleDefault = XML_FALSE; - dtd->scaffLevel--; - dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; - if (dtd->scaffLevel == 0) { - if (!handleDefault) { - XML_Content *model = build_model(parser); - if (!model) - return XML_ERROR_NO_MEMORY; - *eventEndPP = s; - elementDeclHandler(handlerArg, declElementType->name, model); - } - dtd->in_eldecl = XML_FALSE; - dtd->contentStringLen = 0; - } - } - break; - /* End element declaration stuff */ - - case XML_ROLE_PI: - if (!reportProcessingInstruction(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - handleDefault = XML_FALSE; - break; - case XML_ROLE_COMMENT: - if (!reportComment(parser, enc, s, next)) - return XML_ERROR_NO_MEMORY; - handleDefault = XML_FALSE; - break; - case XML_ROLE_NONE: - switch (tok) { - case XML_TOK_BOM: - handleDefault = XML_FALSE; - break; - } - break; - case XML_ROLE_DOCTYPE_NONE: - if (startDoctypeDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ENTITY_NONE: - if (dtd->keepProcessing && entityDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_NOTATION_NONE: - if (notationDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ATTLIST_NONE: - if (dtd->keepProcessing && attlistDeclHandler) - handleDefault = XML_FALSE; - break; - case XML_ROLE_ELEMENT_NONE: - if (elementDeclHandler) - handleDefault = XML_FALSE; - break; - } /* end of big switch */ - - if (handleDefault && defaultHandler) - reportDefault(parser, enc, s, next); - - switch (ps_parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: - s = next; - tok = XmlPrologTok(enc, s, end, &next); - } - } - /* not reached */ -} - -static enum XML_Error PTRCALL -epilogProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - processor = epilogProcessor; - eventPtr = s; - for (;;) { - const char *next = NULL; - int tok = XmlPrologTok(encoding, s, end, &next); - eventEndPtr = next; - switch (tok) { - /* report partial linebreak - it might be the last token */ - case -XML_TOK_PROLOG_S: - if (defaultHandler) { - reportDefault(parser, encoding, s, next); - if (ps_parsing == XML_FINISHED) - return XML_ERROR_ABORTED; - } - *nextPtr = next; - return XML_ERROR_NONE; - case XML_TOK_NONE: - *nextPtr = s; - return XML_ERROR_NONE; - case XML_TOK_PROLOG_S: - if (defaultHandler) - reportDefault(parser, encoding, s, next); - break; - case XML_TOK_PI: - if (!reportProcessingInstruction(parser, encoding, s, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_COMMENT: - if (!reportComment(parser, encoding, s, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_INVALID: - eventPtr = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - if (!ps_finalBuffer) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (!ps_finalBuffer) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - default: - return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; - } - eventPtr = s = next; - switch (ps_parsing) { - case XML_SUSPENDED: - *nextPtr = next; - return XML_ERROR_NONE; - case XML_FINISHED: - return XML_ERROR_ABORTED; - default: ; - } - } -} - -static enum XML_Error -processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl) -{ - const char *textStart, *textEnd; - const char *next; - enum XML_Error result; - OPEN_INTERNAL_ENTITY *openEntity; - - if (freeInternalEntities) { - openEntity = freeInternalEntities; - freeInternalEntities = openEntity->next; - } - else { - openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY)); - if (!openEntity) - return XML_ERROR_NO_MEMORY; - } - entity->open = XML_TRUE; - entity->processed = 0; - openEntity->next = openInternalEntities; - openInternalEntities = openEntity; - openEntity->entity = entity; - openEntity->startTagLevel = tagLevel; - openEntity->betweenDecl = betweenDecl; - openEntity->internalEventPtr = NULL; - openEntity->internalEventEndPtr = NULL; - textStart = (char *)entity->textPtr; - textEnd = (char *)(entity->textPtr + entity->textLen); - -#ifdef XML_DTD - if (entity->is_param) { - int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE); - } - else -#endif /* XML_DTD */ - result = doContent(parser, tagLevel, internalEncoding, textStart, - textEnd, &next, XML_FALSE); - - if (result == XML_ERROR_NONE) { - if (textEnd != next && ps_parsing == XML_SUSPENDED) { - entity->processed = (int)(next - textStart); - processor = internalEntityProcessor; - } - else { - entity->open = XML_FALSE; - openInternalEntities = openEntity->next; - /* put openEntity back in list of free instances */ - openEntity->next = freeInternalEntities; - freeInternalEntities = openEntity; - } - } - return result; -} - -static enum XML_Error PTRCALL -internalEntityProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - ENTITY *entity; - const char *textStart, *textEnd; - const char *next; - enum XML_Error result; - OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; - if (!openEntity) - return XML_ERROR_UNEXPECTED_STATE; - - entity = openEntity->entity; - textStart = ((char *)entity->textPtr) + entity->processed; - textEnd = (char *)(entity->textPtr + entity->textLen); - -#ifdef XML_DTD - if (entity->is_param) { - int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE); - } - else -#endif /* XML_DTD */ - result = doContent(parser, openEntity->startTagLevel, internalEncoding, - textStart, textEnd, &next, XML_FALSE); - - if (result != XML_ERROR_NONE) - return result; - else if (textEnd != next && ps_parsing == XML_SUSPENDED) { - entity->processed = (int)(next - (char *)entity->textPtr); - return result; - } - else { - entity->open = XML_FALSE; - openInternalEntities = openEntity->next; - /* put openEntity back in list of free instances */ - openEntity->next = freeInternalEntities; - freeInternalEntities = openEntity; - } - -#ifdef XML_DTD - if (entity->is_param) { - int tok; - processor = prologProcessor; - tok = XmlPrologTok(encoding, s, end, &next); - return doProlog(parser, encoding, s, end, tok, next, nextPtr, - (XML_Bool)!ps_finalBuffer); - } - else -#endif /* XML_DTD */ - { - processor = contentProcessor; - /* see externalEntityContentProcessor vs contentProcessor */ - return doContent(parser, parentParser ? 1 : 0, encoding, s, end, - nextPtr, (XML_Bool)!ps_finalBuffer); - } -} - -static enum XML_Error PTRCALL -errorProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) -{ - return errorCode; -} - -static enum XML_Error -storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, - const char *ptr, const char *end, - STRING_POOL *pool) -{ - enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, - end, pool); - if (result) - return result; - if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) - poolChop(pool); - if (!poolAppendChar(pool, XML_T('\0'))) - return XML_ERROR_NO_MEMORY; - return XML_ERROR_NONE; -} - -static enum XML_Error -appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, - const char *ptr, const char *end, - STRING_POOL *pool) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - for (;;) { - const char *next; - int tok = XmlAttributeValueTok(enc, ptr, end, &next); - switch (tok) { - case XML_TOK_NONE: - return XML_ERROR_NONE; - case XML_TOK_INVALID: - if (enc == encoding) - eventPtr = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - if (enc == encoding) - eventPtr = ptr; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, ptr); - if (n < 0) { - if (enc == encoding) - eventPtr = ptr; - return XML_ERROR_BAD_CHAR_REF; - } - if (!isCdata - && n == 0x20 /* space */ - && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) - break; - n = XmlEncode(n, (ICHAR *)buf); - if (!n) { - if (enc == encoding) - eventPtr = ptr; - return XML_ERROR_BAD_CHAR_REF; - } - for (i = 0; i < n; i++) { - if (!poolAppendChar(pool, buf[i])) - return XML_ERROR_NO_MEMORY; - } - } - break; - case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, ptr, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_TRAILING_CR: - next = ptr + enc->minBytesPerChar; - /* fall through */ - case XML_TOK_ATTRIBUTE_VALUE_S: - case XML_TOK_DATA_NEWLINE: - if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) - break; - if (!poolAppendChar(pool, 0x20)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_ENTITY_REF: - { - const XML_Char *name; - ENTITY *entity; - char checkEntityDecl; - XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (ch) { - if (!poolAppendChar(pool, ch)) - return XML_ERROR_NO_MEMORY; - break; - } - name = poolStoreString(&temp2Pool, enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); - poolDiscard(&temp2Pool); - /* First, determine if a check for an existing declaration is needed; - if yes, check that the entity exists, and that it is internal. - */ - if (pool == &dtd->pool) /* are we called from prolog? */ - checkEntityDecl = -#ifdef XML_DTD - prologState.documentEntity && -#endif /* XML_DTD */ - (dtd->standalone - ? !openInternalEntities - : !dtd->hasParamEntityRefs); - else /* if (pool == &tempPool): we are called from content */ - checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; - if (checkEntityDecl) { - if (!entity) - return XML_ERROR_UNDEFINED_ENTITY; - else if (!entity->is_internal) - return XML_ERROR_ENTITY_DECLARED_IN_PE; - } - else if (!entity) { - /* Cannot report skipped entity here - see comments on - skippedEntityHandler. - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, name, 0); - */ - /* Cannot call the default handler because this would be - out of sync with the call to the startElementHandler. - if ((pool == &tempPool) && defaultHandler) - reportDefault(parser, enc, ptr, next); - */ - break; - } - if (entity->open) { - if (enc == encoding) - eventPtr = ptr; - return XML_ERROR_RECURSIVE_ENTITY_REF; - } - if (entity->notation) { - if (enc == encoding) - eventPtr = ptr; - return XML_ERROR_BINARY_ENTITY_REF; - } - if (!entity->textPtr) { - if (enc == encoding) - eventPtr = ptr; - return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; - } - else { - enum XML_Error result; - const XML_Char *textEnd = entity->textPtr + entity->textLen; - entity->open = XML_TRUE; - result = appendAttributeValue(parser, internalEncoding, isCdata, - (char *)entity->textPtr, - (char *)textEnd, pool); - entity->open = XML_FALSE; - if (result) - return result; - } - } - break; - default: - if (enc == encoding) - eventPtr = ptr; - return XML_ERROR_UNEXPECTED_STATE; - } - ptr = next; - } - /* not reached */ -} - -static enum XML_Error -storeEntityValue(XML_Parser parser, - const ENCODING *enc, - const char *entityTextPtr, - const char *entityTextEnd) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - STRING_POOL *pool = &(dtd->entityValuePool); - enum XML_Error result = XML_ERROR_NONE; -#ifdef XML_DTD - int oldInEntityValue = prologState.inEntityValue; - prologState.inEntityValue = 1; -#endif /* XML_DTD */ - /* never return Null for the value argument in EntityDeclHandler, - since this would indicate an external entity; therefore we - have to make sure that entityValuePool.start is not null */ - if (!pool->blocks) { - if (!poolGrow(pool)) - return XML_ERROR_NO_MEMORY; - } - - for (;;) { - const char *next; - int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); - switch (tok) { - case XML_TOK_PARAM_ENTITY_REF: -#ifdef XML_DTD - if (isParamEntity || enc != encoding) { - const XML_Char *name; - ENTITY *entity; - name = poolStoreString(&tempPool, enc, - entityTextPtr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); - poolDiscard(&tempPool); - if (!entity) { - /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ - /* cannot report skipped entity here - see comments on - skippedEntityHandler - if (skippedEntityHandler) - skippedEntityHandler(handlerArg, name, 0); - */ - dtd->keepProcessing = dtd->standalone; - goto endEntityValue; - } - if (entity->open) { - if (enc == encoding) - eventPtr = entityTextPtr; - result = XML_ERROR_RECURSIVE_ENTITY_REF; - goto endEntityValue; - } - if (entity->systemId) { - if (externalEntityRefHandler) { - dtd->paramEntityRead = XML_FALSE; - entity->open = XML_TRUE; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { - entity->open = XML_FALSE; - result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; - goto endEntityValue; - } - entity->open = XML_FALSE; - if (!dtd->paramEntityRead) - dtd->keepProcessing = dtd->standalone; - } - else - dtd->keepProcessing = dtd->standalone; - } - else { - entity->open = XML_TRUE; - result = storeEntityValue(parser, - internalEncoding, - (char *)entity->textPtr, - (char *)(entity->textPtr - + entity->textLen)); - entity->open = XML_FALSE; - if (result) - goto endEntityValue; - } - break; - } -#endif /* XML_DTD */ - /* In the internal subset, PE references are not legal - within markup declarations, e.g entity values in this case. */ - eventPtr = entityTextPtr; - result = XML_ERROR_PARAM_ENTITY_REF; - goto endEntityValue; - case XML_TOK_NONE: - result = XML_ERROR_NONE; - goto endEntityValue; - case XML_TOK_ENTITY_REF: - case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, entityTextPtr, next)) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - break; - case XML_TOK_TRAILING_CR: - next = entityTextPtr + enc->minBytesPerChar; - /* fall through */ - case XML_TOK_DATA_NEWLINE: - if (pool->end == pool->ptr && !poolGrow(pool)) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - *(pool->ptr)++ = 0xA; - break; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, entityTextPtr); - if (n < 0) { - if (enc == encoding) - eventPtr = entityTextPtr; - result = XML_ERROR_BAD_CHAR_REF; - goto endEntityValue; - } - n = XmlEncode(n, (ICHAR *)buf); - if (!n) { - if (enc == encoding) - eventPtr = entityTextPtr; - result = XML_ERROR_BAD_CHAR_REF; - goto endEntityValue; - } - for (i = 0; i < n; i++) { - if (pool->end == pool->ptr && !poolGrow(pool)) { - result = XML_ERROR_NO_MEMORY; - goto endEntityValue; - } - *(pool->ptr)++ = buf[i]; - } - } - break; - case XML_TOK_PARTIAL: - if (enc == encoding) - eventPtr = entityTextPtr; - result = XML_ERROR_INVALID_TOKEN; - goto endEntityValue; - case XML_TOK_INVALID: - if (enc == encoding) - eventPtr = next; - result = XML_ERROR_INVALID_TOKEN; - goto endEntityValue; - default: - if (enc == encoding) - eventPtr = entityTextPtr; - result = XML_ERROR_UNEXPECTED_STATE; - goto endEntityValue; - } - entityTextPtr = next; - } -endEntityValue: -#ifdef XML_DTD - prologState.inEntityValue = oldInEntityValue; -#endif /* XML_DTD */ - return result; -} - -static void FASTCALL -normalizeLines(XML_Char *s) -{ - XML_Char *p; - for (;; s++) { - if (*s == XML_T('\0')) - return; - if (*s == 0xD) - break; - } - p = s; - do { - if (*s == 0xD) { - *p++ = 0xA; - if (*++s == 0xA) - s++; - } - else - *p++ = *s++; - } while (*s); - *p = XML_T('\0'); -} - -static int -reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ - const XML_Char *target; - XML_Char *data; - const char *tem; - if (!processingInstructionHandler) { - if (defaultHandler) - reportDefault(parser, enc, start, end); - return 1; - } - start += enc->minBytesPerChar * 2; - tem = start + XmlNameLength(enc, start); - target = poolStoreString(&tempPool, enc, start, tem); - if (!target) - return 0; - poolFinish(&tempPool); - data = poolStoreString(&tempPool, enc, - XmlSkipS(enc, tem), - end - enc->minBytesPerChar*2); - if (!data) - return 0; - normalizeLines(data); - processingInstructionHandler(handlerArg, target, data); - poolClear(&tempPool); - return 1; -} - -static int -reportComment(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ - XML_Char *data; - if (!commentHandler) { - if (defaultHandler) - reportDefault(parser, enc, start, end); - return 1; - } - data = poolStoreString(&tempPool, - enc, - start + enc->minBytesPerChar * 4, - end - enc->minBytesPerChar * 3); - if (!data) - return 0; - normalizeLines(data); - commentHandler(handlerArg, data); - poolClear(&tempPool); - return 1; -} - -static void -reportDefault(XML_Parser parser, const ENCODING *enc, - const char *s, const char *end) -{ - if (MUST_CONVERT(enc, s)) { - const char **eventPP; - const char **eventEndPP; - if (enc == encoding) { - eventPP = &eventPtr; - eventEndPP = &eventEndPtr; - } - else { - eventPP = &(openInternalEntities->internalEventPtr); - eventEndPP = &(openInternalEntities->internalEventEndPtr); - } - do { - ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); - *eventEndPP = s; - defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); - *eventPP = s; - } while (s != end); - } - else - defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); -} - - -static int -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, - XML_Bool isId, const XML_Char *value, XML_Parser parser) -{ - DEFAULT_ATTRIBUTE *att; - if (value || isId) { - /* The handling of default attributes gets messed up if we have - a default which duplicates a non-default. */ - int i; - for (i = 0; i < type->nDefaultAtts; i++) - if (attId == type->defaultAtts[i].id) - return 1; - if (isId && !type->idAtt && !attId->xmlns) - type->idAtt = attId; - } - if (type->nDefaultAtts == type->allocDefaultAtts) { - if (type->allocDefaultAtts == 0) { - type->allocDefaultAtts = 8; - type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts - * sizeof(DEFAULT_ATTRIBUTE)); - if (!type->defaultAtts) - return 0; - } - else { - DEFAULT_ATTRIBUTE *temp; - int count = type->allocDefaultAtts * 2; - temp = (DEFAULT_ATTRIBUTE *) - REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); - if (temp == NULL) - return 0; - type->allocDefaultAtts = count; - type->defaultAtts = temp; - } - } - att = type->defaultAtts + type->nDefaultAtts; - att->id = attId; - att->value = value; - att->isCdata = isCdata; - if (!isCdata) - attId->maybeTokenized = XML_TRUE; - type->nDefaultAtts += 1; - return 1; -} - -static int -setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - const XML_Char *name; - for (name = elementType->name; *name; name++) { - if (*name == XML_T(ASCII_COLON)) { - PREFIX *prefix; - const XML_Char *s; - for (s = elementType->name; s != name; s++) { - if (!poolAppendChar(&dtd->pool, *s)) - return 0; - } - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) - return 0; - prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), - sizeof(PREFIX)); - if (!prefix) - return 0; - if (prefix->name == poolStart(&dtd->pool)) - poolFinish(&dtd->pool); - else - poolDiscard(&dtd->pool); - elementType->prefix = prefix; - - } - } - return 1; -} - -static ATTRIBUTE_ID * -getAttributeId(XML_Parser parser, const ENCODING *enc, - const char *start, const char *end) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - ATTRIBUTE_ID *id; - const XML_Char *name; - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) - return NULL; - name = poolStoreString(&dtd->pool, enc, start, end); - if (!name) - return NULL; - /* skip quotation mark - its storage will be re-used (like in name[-1]) */ - ++name; - id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); - if (!id) - return NULL; - if (id->name != name) - poolDiscard(&dtd->pool); - else { - poolFinish(&dtd->pool); - if (!ns) - ; - else if (name[0] == XML_T(ASCII_x) - && name[1] == XML_T(ASCII_m) - && name[2] == XML_T(ASCII_l) - && name[3] == XML_T(ASCII_n) - && name[4] == XML_T(ASCII_s) - && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { - if (name[5] == XML_T('\0')) - id->prefix = &dtd->defaultPrefix; - else - id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX)); - id->xmlns = XML_TRUE; - } - else { - int i; - for (i = 0; name[i]; i++) { - /* attributes without prefix are *not* in the default namespace */ - if (name[i] == XML_T(ASCII_COLON)) { - int j; - for (j = 0; j < i; j++) { - if (!poolAppendChar(&dtd->pool, name[j])) - return NULL; - } - if (!poolAppendChar(&dtd->pool, XML_T('\0'))) - return NULL; - id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), - sizeof(PREFIX)); - if (id->prefix->name == poolStart(&dtd->pool)) - poolFinish(&dtd->pool); - else - poolDiscard(&dtd->pool); - break; - } - } - } - } - return id; -} - -#define CONTEXT_SEP XML_T(ASCII_FF) - -static const XML_Char * -getContext(XML_Parser parser) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - HASH_TABLE_ITER iter; - XML_Bool needSep = XML_FALSE; - - if (dtd->defaultPrefix.binding) { - int i; - int len; - if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) - return NULL; - len = dtd->defaultPrefix.binding->uriLen; - if (namespaceSeparator) - len--; - for (i = 0; i < len; i++) - if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) - return NULL; - needSep = XML_TRUE; - } - - hashTableIterInit(&iter, &(dtd->prefixes)); - for (;;) { - int i; - int len; - const XML_Char *s; - PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); - if (!prefix) - break; - if (!prefix->binding) - continue; - if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) - return NULL; - for (s = prefix->name; *s; s++) - if (!poolAppendChar(&tempPool, *s)) - return NULL; - if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) - return NULL; - len = prefix->binding->uriLen; - if (namespaceSeparator) - len--; - for (i = 0; i < len; i++) - if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) - return NULL; - needSep = XML_TRUE; - } - - - hashTableIterInit(&iter, &(dtd->generalEntities)); - for (;;) { - const XML_Char *s; - ENTITY *e = (ENTITY *)hashTableIterNext(&iter); - if (!e) - break; - if (!e->open) - continue; - if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) - return NULL; - for (s = e->name; *s; s++) - if (!poolAppendChar(&tempPool, *s)) - return 0; - needSep = XML_TRUE; - } - - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return NULL; - return tempPool.start; -} - -static XML_Bool -setContext(XML_Parser parser, const XML_Char *context) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - const XML_Char *s = context; - - while (*context != XML_T('\0')) { - if (*s == CONTEXT_SEP || *s == XML_T('\0')) { - ENTITY *e; - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return XML_FALSE; - e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0); - if (e) - e->open = XML_TRUE; - if (*s != XML_T('\0')) - s++; - context = s; - poolDiscard(&tempPool); - } - else if (*s == XML_T(ASCII_EQUALS)) { - PREFIX *prefix; - if (poolLength(&tempPool) == 0) - prefix = &dtd->defaultPrefix; - else { - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return XML_FALSE; - prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool), - sizeof(PREFIX)); - if (!prefix) - return XML_FALSE; - if (prefix->name == poolStart(&tempPool)) { - prefix->name = poolCopyString(&dtd->pool, prefix->name); - if (!prefix->name) - return XML_FALSE; - } - poolDiscard(&tempPool); - } - for (context = s + 1; - *context != CONTEXT_SEP && *context != XML_T('\0'); - context++) - if (!poolAppendChar(&tempPool, *context)) - return XML_FALSE; - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return XML_FALSE; - if (addBinding(parser, prefix, NULL, poolStart(&tempPool), - &inheritedBindings) != XML_ERROR_NONE) - return XML_FALSE; - poolDiscard(&tempPool); - if (*context != XML_T('\0')) - ++context; - s = context; - } - else { - if (!poolAppendChar(&tempPool, *s)) - return XML_FALSE; - s++; - } - } - return XML_TRUE; -} - -static void FASTCALL -normalizePublicId(XML_Char *publicId) -{ - XML_Char *p = publicId; - XML_Char *s; - for (s = publicId; *s; s++) { - switch (*s) { - case 0x20: - case 0xD: - case 0xA: - if (p != publicId && p[-1] != 0x20) - *p++ = 0x20; - break; - default: - *p++ = *s; - } - } - if (p != publicId && p[-1] == 0x20) - --p; - *p = XML_T('\0'); -} - -static DTD * -dtdCreate(const XML_Memory_Handling_Suite *ms) -{ - DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); - if (p == NULL) - return p; - poolInit(&(p->pool), ms); - poolInit(&(p->entityValuePool), ms); - hashTableInit(&(p->generalEntities), ms); - hashTableInit(&(p->elementTypes), ms); - hashTableInit(&(p->attributeIds), ms); - hashTableInit(&(p->prefixes), ms); -#ifdef XML_DTD - p->paramEntityRead = XML_FALSE; - hashTableInit(&(p->paramEntities), ms); -#endif /* XML_DTD */ - p->defaultPrefix.name = NULL; - p->defaultPrefix.binding = NULL; - - p->in_eldecl = XML_FALSE; - p->scaffIndex = NULL; - p->scaffold = NULL; - p->scaffLevel = 0; - p->scaffSize = 0; - p->scaffCount = 0; - p->contentStringLen = 0; - - p->keepProcessing = XML_TRUE; - p->hasParamEntityRefs = XML_FALSE; - p->standalone = XML_FALSE; - return p; -} - -static void -dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) -{ - HASH_TABLE_ITER iter; - hashTableIterInit(&iter, &(p->elementTypes)); - for (;;) { - ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!e) - break; - if (e->allocDefaultAtts != 0) - ms->free_fcn(e->defaultAtts); - } - hashTableClear(&(p->generalEntities)); -#ifdef XML_DTD - p->paramEntityRead = XML_FALSE; - hashTableClear(&(p->paramEntities)); -#endif /* XML_DTD */ - hashTableClear(&(p->elementTypes)); - hashTableClear(&(p->attributeIds)); - hashTableClear(&(p->prefixes)); - poolClear(&(p->pool)); - poolClear(&(p->entityValuePool)); - p->defaultPrefix.name = NULL; - p->defaultPrefix.binding = NULL; - - p->in_eldecl = XML_FALSE; - - ms->free_fcn(p->scaffIndex); - p->scaffIndex = NULL; - ms->free_fcn(p->scaffold); - p->scaffold = NULL; - - p->scaffLevel = 0; - p->scaffSize = 0; - p->scaffCount = 0; - p->contentStringLen = 0; - - p->keepProcessing = XML_TRUE; - p->hasParamEntityRefs = XML_FALSE; - p->standalone = XML_FALSE; -} - -static void -dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) -{ - HASH_TABLE_ITER iter; - hashTableIterInit(&iter, &(p->elementTypes)); - for (;;) { - ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!e) - break; - if (e->allocDefaultAtts != 0) - ms->free_fcn(e->defaultAtts); - } - hashTableDestroy(&(p->generalEntities)); -#ifdef XML_DTD - hashTableDestroy(&(p->paramEntities)); -#endif /* XML_DTD */ - hashTableDestroy(&(p->elementTypes)); - hashTableDestroy(&(p->attributeIds)); - hashTableDestroy(&(p->prefixes)); - poolDestroy(&(p->pool)); - poolDestroy(&(p->entityValuePool)); - if (isDocEntity) { - ms->free_fcn(p->scaffIndex); - ms->free_fcn(p->scaffold); - } - ms->free_fcn(p); -} - -/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. - The new DTD has already been initialized. -*/ -static int -dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) -{ - HASH_TABLE_ITER iter; - - /* Copy the prefix table. */ - - hashTableIterInit(&iter, &(oldDtd->prefixes)); - for (;;) { - const XML_Char *name; - const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); - if (!oldP) - break; - name = poolCopyString(&(newDtd->pool), oldP->name); - if (!name) - return 0; - if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX))) - return 0; - } - - hashTableIterInit(&iter, &(oldDtd->attributeIds)); - - /* Copy the attribute id table. */ - - for (;;) { - ATTRIBUTE_ID *newA; - const XML_Char *name; - const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); - - if (!oldA) - break; - /* Remember to allocate the scratch byte before the name. */ - if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) - return 0; - name = poolCopyString(&(newDtd->pool), oldA->name); - if (!name) - return 0; - ++name; - newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, - sizeof(ATTRIBUTE_ID)); - if (!newA) - return 0; - newA->maybeTokenized = oldA->maybeTokenized; - if (oldA->prefix) { - newA->xmlns = oldA->xmlns; - if (oldA->prefix == &oldDtd->defaultPrefix) - newA->prefix = &newDtd->defaultPrefix; - else - newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), - oldA->prefix->name, 0); - } - } - - /* Copy the element type table. */ - - hashTableIterInit(&iter, &(oldDtd->elementTypes)); - - for (;;) { - int i; - ELEMENT_TYPE *newE; - const XML_Char *name; - const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!oldE) - break; - name = poolCopyString(&(newDtd->pool), oldE->name); - if (!name) - return 0; - newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, - sizeof(ELEMENT_TYPE)); - if (!newE) - return 0; - if (oldE->nDefaultAtts) { - newE->defaultAtts = (DEFAULT_ATTRIBUTE *) - ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); - if (!newE->defaultAtts) { - ms->free_fcn(newE); - return 0; - } - } - if (oldE->idAtt) - newE->idAtt = (ATTRIBUTE_ID *) - lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0); - newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; - if (oldE->prefix) - newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), - oldE->prefix->name, 0); - for (i = 0; i < newE->nDefaultAtts; i++) { - newE->defaultAtts[i].id = (ATTRIBUTE_ID *) - lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); - newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; - if (oldE->defaultAtts[i].value) { - newE->defaultAtts[i].value - = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); - if (!newE->defaultAtts[i].value) - return 0; - } - else - newE->defaultAtts[i].value = NULL; - } - } - - /* Copy the entity tables. */ - if (!copyEntityTable(&(newDtd->generalEntities), - &(newDtd->pool), - &(oldDtd->generalEntities))) - return 0; - -#ifdef XML_DTD - if (!copyEntityTable(&(newDtd->paramEntities), - &(newDtd->pool), - &(oldDtd->paramEntities))) - return 0; - newDtd->paramEntityRead = oldDtd->paramEntityRead; -#endif /* XML_DTD */ - - newDtd->keepProcessing = oldDtd->keepProcessing; - newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; - newDtd->standalone = oldDtd->standalone; - - /* Don't want deep copying for scaffolding */ - newDtd->in_eldecl = oldDtd->in_eldecl; - newDtd->scaffold = oldDtd->scaffold; - newDtd->contentStringLen = oldDtd->contentStringLen; - newDtd->scaffSize = oldDtd->scaffSize; - newDtd->scaffLevel = oldDtd->scaffLevel; - newDtd->scaffIndex = oldDtd->scaffIndex; - - return 1; -} /* End dtdCopy */ - -static int -copyEntityTable(HASH_TABLE *newTable, - STRING_POOL *newPool, - const HASH_TABLE *oldTable) -{ - HASH_TABLE_ITER iter; - const XML_Char *cachedOldBase = NULL; - const XML_Char *cachedNewBase = NULL; - - hashTableIterInit(&iter, oldTable); - - for (;;) { - ENTITY *newE; - const XML_Char *name; - const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); - if (!oldE) - break; - name = poolCopyString(newPool, oldE->name); - if (!name) - return 0; - newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); - if (!newE) - return 0; - if (oldE->systemId) { - const XML_Char *tem = poolCopyString(newPool, oldE->systemId); - if (!tem) - return 0; - newE->systemId = tem; - if (oldE->base) { - if (oldE->base == cachedOldBase) - newE->base = cachedNewBase; - else { - cachedOldBase = oldE->base; - tem = poolCopyString(newPool, cachedOldBase); - if (!tem) - return 0; - cachedNewBase = newE->base = tem; - } - } - if (oldE->publicId) { - tem = poolCopyString(newPool, oldE->publicId); - if (!tem) - return 0; - newE->publicId = tem; - } - } - else { - const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, - oldE->textLen); - if (!tem) - return 0; - newE->textPtr = tem; - newE->textLen = oldE->textLen; - } - if (oldE->notation) { - const XML_Char *tem = poolCopyString(newPool, oldE->notation); - if (!tem) - return 0; - newE->notation = tem; - } - newE->is_param = oldE->is_param; - newE->is_internal = oldE->is_internal; - } - return 1; -} - -#define INIT_POWER 6 - -static XML_Bool FASTCALL -keyeq(KEY s1, KEY s2) -{ - for (; *s1 == *s2; s1++, s2++) - if (*s1 == 0) - return XML_TRUE; - return XML_FALSE; -} - -static unsigned long FASTCALL -hash(KEY s) -{ - unsigned long h = 0; - while (*s) - h = CHAR_HASH(h, *s++); - return h; -} - -static NAMED * -lookup(HASH_TABLE *table, KEY name, size_t createSize) -{ - size_t i; - if (table->size == 0) { - size_t tsize; - if (!createSize) - return NULL; - table->power = INIT_POWER; - /* table->size is a power of 2 */ - table->size = (size_t)1 << INIT_POWER; - tsize = table->size * sizeof(NAMED *); - table->v = (NAMED **)table->mem->malloc_fcn(tsize); - if (!table->v) { - table->size = 0; - return NULL; - } - memset(table->v, 0, tsize); - i = hash(name) & ((unsigned long)table->size - 1); - } - else { - unsigned long h = hash(name); - unsigned long mask = (unsigned long)table->size - 1; - unsigned char step = 0; - i = h & mask; - while (table->v[i]) { - if (keyeq(name, table->v[i]->name)) - return table->v[i]; - if (!step) - step = PROBE_STEP(h, mask, table->power); - i < step ? (i += table->size - step) : (i -= step); - } - if (!createSize) - return NULL; - - /* check for overflow (table is half full) */ - if (table->used >> (table->power - 1)) { - unsigned char newPower = table->power + 1; - size_t newSize = (size_t)1 << newPower; - unsigned long newMask = (unsigned long)newSize - 1; - size_t tsize = newSize * sizeof(NAMED *); - NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); - if (!newV) - return NULL; - memset(newV, 0, tsize); - for (i = 0; i < table->size; i++) - if (table->v[i]) { - unsigned long newHash = hash(table->v[i]->name); - size_t j = newHash & newMask; - step = 0; - while (newV[j]) { - if (!step) - step = PROBE_STEP(newHash, newMask, newPower); - j < step ? (j += newSize - step) : (j -= step); - } - newV[j] = table->v[i]; - } - table->mem->free_fcn(table->v); - table->v = newV; - table->power = newPower; - table->size = newSize; - i = h & newMask; - step = 0; - while (table->v[i]) { - if (!step) - step = PROBE_STEP(h, newMask, newPower); - i < step ? (i += newSize - step) : (i -= step); - } - } - } - table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); - if (!table->v[i]) - return NULL; - memset(table->v[i], 0, createSize); - table->v[i]->name = name; - (table->used)++; - return table->v[i]; -} - -static void FASTCALL -hashTableClear(HASH_TABLE *table) -{ - size_t i; - for (i = 0; i < table->size; i++) { - table->mem->free_fcn(table->v[i]); - table->v[i] = NULL; - } - table->used = 0; -} - -static void FASTCALL -hashTableDestroy(HASH_TABLE *table) -{ - size_t i; - for (i = 0; i < table->size; i++) - table->mem->free_fcn(table->v[i]); - table->mem->free_fcn(table->v); -} - -static void FASTCALL -hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) -{ - p->power = 0; - p->size = 0; - p->used = 0; - p->v = NULL; - p->mem = ms; -} - -static void FASTCALL -hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) -{ - iter->p = table->v; - iter->end = iter->p + table->size; -} - -static NAMED * FASTCALL -hashTableIterNext(HASH_TABLE_ITER *iter) -{ - while (iter->p != iter->end) { - NAMED *tem = *(iter->p)++; - if (tem) - return tem; - } - return NULL; -} - -static void FASTCALL -poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) -{ - pool->blocks = NULL; - pool->freeBlocks = NULL; - pool->start = NULL; - pool->ptr = NULL; - pool->end = NULL; - pool->mem = ms; -} - -static void FASTCALL -poolClear(STRING_POOL *pool) -{ - if (!pool->freeBlocks) - pool->freeBlocks = pool->blocks; - else { - BLOCK *p = pool->blocks; - while (p) { - BLOCK *tem = p->next; - p->next = pool->freeBlocks; - pool->freeBlocks = p; - p = tem; - } - } - pool->blocks = NULL; - pool->start = NULL; - pool->ptr = NULL; - pool->end = NULL; -} - -static void FASTCALL -poolDestroy(STRING_POOL *pool) -{ - BLOCK *p = pool->blocks; - while (p) { - BLOCK *tem = p->next; - pool->mem->free_fcn(p); - p = tem; - } - p = pool->freeBlocks; - while (p) { - BLOCK *tem = p->next; - pool->mem->free_fcn(p); - p = tem; - } -} - -static XML_Char * -poolAppend(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!pool->ptr && !poolGrow(pool)) - return NULL; - for (;;) { - XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); - if (ptr == end) - break; - if (!poolGrow(pool)) - return NULL; - } - return pool->start; -} - -static const XML_Char * FASTCALL -poolCopyString(STRING_POOL *pool, const XML_Char *s) -{ - do { - if (!poolAppendChar(pool, *s)) - return NULL; - } while (*s++); - s = pool->start; - poolFinish(pool); - return s; -} - -static const XML_Char * -poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) -{ - if (!pool->ptr && !poolGrow(pool)) - return NULL; - for (; n > 0; --n, s++) { - if (!poolAppendChar(pool, *s)) - return NULL; - } - s = pool->start; - poolFinish(pool); - return s; -} - -static const XML_Char * FASTCALL -poolAppendString(STRING_POOL *pool, const XML_Char *s) -{ - while (*s) { - if (!poolAppendChar(pool, *s)) - return NULL; - s++; - } - return pool->start; -} - -static XML_Char * -poolStoreString(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!poolAppend(pool, enc, ptr, end)) - return NULL; - if (pool->ptr == pool->end && !poolGrow(pool)) - return NULL; - *(pool->ptr)++ = 0; - return pool->start; -} - -static XML_Bool FASTCALL -poolGrow(STRING_POOL *pool) -{ - if (pool->freeBlocks) { - if (pool->start == 0) { - pool->blocks = pool->freeBlocks; - pool->freeBlocks = pool->freeBlocks->next; - pool->blocks->next = NULL; - pool->start = pool->blocks->s; - pool->end = pool->start + pool->blocks->size; - pool->ptr = pool->start; - return XML_TRUE; - } - if (pool->end - pool->start < pool->freeBlocks->size) { - BLOCK *tem = pool->freeBlocks->next; - pool->freeBlocks->next = pool->blocks; - pool->blocks = pool->freeBlocks; - pool->freeBlocks = tem; - memcpy(pool->blocks->s, pool->start, - (pool->end - pool->start) * sizeof(XML_Char)); - pool->ptr = pool->blocks->s + (pool->ptr - pool->start); - pool->start = pool->blocks->s; - pool->end = pool->start + pool->blocks->size; - return XML_TRUE; - } - } - if (pool->blocks && pool->start == pool->blocks->s) { - int blockSize = (int)(pool->end - pool->start)*2; - pool->blocks = (BLOCK *) - pool->mem->realloc_fcn(pool->blocks, - (offsetof(BLOCK, s) - + blockSize * sizeof(XML_Char))); - if (pool->blocks == NULL) - return XML_FALSE; - pool->blocks->size = blockSize; - pool->ptr = pool->blocks->s + (pool->ptr - pool->start); - pool->start = pool->blocks->s; - pool->end = pool->start + blockSize; - } - else { - BLOCK *tem; - int blockSize = (int)(pool->end - pool->start); - if (blockSize < INIT_BLOCK_SIZE) - blockSize = INIT_BLOCK_SIZE; - else - blockSize *= 2; - tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) - + blockSize * sizeof(XML_Char)); - if (!tem) - return XML_FALSE; - tem->size = blockSize; - tem->next = pool->blocks; - pool->blocks = tem; - if (pool->ptr != pool->start) - memcpy(tem->s, pool->start, - (pool->ptr - pool->start) * sizeof(XML_Char)); - pool->ptr = tem->s + (pool->ptr - pool->start); - pool->start = tem->s; - pool->end = tem->s + blockSize; - } - return XML_TRUE; -} - -static int FASTCALL -nextScaffoldPart(XML_Parser parser) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - CONTENT_SCAFFOLD * me; - int next; - - if (!dtd->scaffIndex) { - dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); - if (!dtd->scaffIndex) - return -1; - dtd->scaffIndex[0] = 0; - } - - if (dtd->scaffCount >= dtd->scaffSize) { - CONTENT_SCAFFOLD *temp; - if (dtd->scaffold) { - temp = (CONTENT_SCAFFOLD *) - REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); - if (temp == NULL) - return -1; - dtd->scaffSize *= 2; - } - else { - temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS - * sizeof(CONTENT_SCAFFOLD)); - if (temp == NULL) - return -1; - dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; - } - dtd->scaffold = temp; - } - next = dtd->scaffCount++; - me = &dtd->scaffold[next]; - if (dtd->scaffLevel) { - CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; - if (parent->lastchild) { - dtd->scaffold[parent->lastchild].nextsib = next; - } - if (!parent->childcnt) - parent->firstchild = next; - parent->lastchild = next; - parent->childcnt++; - } - me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; - return next; -} - -static void -build_node(XML_Parser parser, - int src_node, - XML_Content *dest, - XML_Content **contpos, - XML_Char **strpos) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - dest->type = dtd->scaffold[src_node].type; - dest->quant = dtd->scaffold[src_node].quant; - if (dest->type == XML_CTYPE_NAME) { - const XML_Char *src; - dest->name = *strpos; - src = dtd->scaffold[src_node].name; - for (;;) { - *(*strpos)++ = *src; - if (!*src) - break; - src++; - } - dest->numchildren = 0; - dest->children = NULL; - } - else { - unsigned int i; - int cn; - dest->numchildren = dtd->scaffold[src_node].childcnt; - dest->children = *contpos; - *contpos += dest->numchildren; - for (i = 0, cn = dtd->scaffold[src_node].firstchild; - i < dest->numchildren; - i++, cn = dtd->scaffold[cn].nextsib) { - build_node(parser, cn, &(dest->children[i]), contpos, strpos); - } - dest->name = NULL; - } -} - -static XML_Content * -build_model (XML_Parser parser) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - XML_Content *ret; - XML_Content *cpos; - XML_Char * str; - int allocsize = (dtd->scaffCount * sizeof(XML_Content) - + (dtd->contentStringLen * sizeof(XML_Char))); - - ret = (XML_Content *)MALLOC(allocsize); - if (!ret) - return NULL; - - str = (XML_Char *) (&ret[dtd->scaffCount]); - cpos = &ret[1]; - - build_node(parser, 0, ret, &cpos, &str); - return ret; -} - -static ELEMENT_TYPE * -getElementType(XML_Parser parser, - const ENCODING *enc, - const char *ptr, - const char *end) -{ - DTD * const dtd = _dtd; /* save one level of indirection */ - const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); - ELEMENT_TYPE *ret; - - if (!name) - return NULL; - ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); - if (!ret) - return NULL; - if (ret->name != name) - poolDiscard(&dtd->pool); - else { - poolFinish(&dtd->pool); - if (!setElementTypePrefix(parser, ret)) - return NULL; - } - return ret; -} diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlrole.c b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlrole.c deleted file mode 100644 index 9c5e25b..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlrole.c +++ /dev/null @@ -1,1336 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#include <stddef.h> - -#ifdef COMPILED_FROM_DSP -#include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos4__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" -#else -#ifdef HAVE_EXPAT_CONFIG_H -#include <expat_config.h> -#endif -#endif /* ndef COMPILED_FROM_DSP */ - -#include "expat_external.h" -#include "internal.h" -#include "xmlrole.h" -#include "ascii.h" - -/* Doesn't check: - - that ,| are not mixed in a model group - content of literals - -*/ - -static const char KW_ANY[] = { - ASCII_A, ASCII_N, ASCII_Y, '\0' }; -static const char KW_ATTLIST[] = { - ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' }; -static const char KW_CDATA[] = { - ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_DOCTYPE[] = { - ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' }; -static const char KW_ELEMENT[] = { - ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' }; -static const char KW_EMPTY[] = { - ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' }; -static const char KW_ENTITIES[] = { - ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, - '\0' }; -static const char KW_ENTITY[] = { - ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; -static const char KW_FIXED[] = { - ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' }; -static const char KW_ID[] = { - ASCII_I, ASCII_D, '\0' }; -static const char KW_IDREF[] = { - ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; -static const char KW_IDREFS[] = { - ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; -#ifdef XML_DTD -static const char KW_IGNORE[] = { - ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' }; -#endif -static const char KW_IMPLIED[] = { - ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' }; -#ifdef XML_DTD -static const char KW_INCLUDE[] = { - ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' }; -#endif -static const char KW_NDATA[] = { - ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_NMTOKEN[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; -static const char KW_NMTOKENS[] = { - ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, - '\0' }; -static const char KW_NOTATION[] = - { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, - '\0' }; -static const char KW_PCDATA[] = { - ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_PUBLIC[] = { - ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' }; -static const char KW_REQUIRED[] = { - ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, - '\0' }; -static const char KW_SYSTEM[] = { - ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' }; - -#ifndef MIN_BYTES_PER_CHAR -#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) -#endif - -#ifdef XML_DTD -#define setTopLevel(state) \ - ((state)->handler = ((state)->documentEntity \ - ? internalSubset \ - : externalSubset1)) -#else /* not XML_DTD */ -#define setTopLevel(state) ((state)->handler = internalSubset) -#endif /* not XML_DTD */ - -typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc); - -static PROLOG_HANDLER - prolog0, prolog1, prolog2, - doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, - internalSubset, - entity0, entity1, entity2, entity3, entity4, entity5, entity6, - entity7, entity8, entity9, entity10, - notation0, notation1, notation2, notation3, notation4, - attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, - attlist7, attlist8, attlist9, - element0, element1, element2, element3, element4, element5, element6, - element7, -#ifdef XML_DTD - externalSubset0, externalSubset1, - condSect0, condSect1, condSect2, -#endif /* XML_DTD */ - declClose, - error; - -static int FASTCALL common(PROLOG_STATE *state, int tok); - -static int PTRCALL -prolog0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - state->handler = prolog1; - return XML_ROLE_NONE; - case XML_TOK_XML_DECL: - state->handler = prolog1; - return XML_ROLE_XML_DECL; - case XML_TOK_PI: - state->handler = prolog1; - return XML_ROLE_PI; - case XML_TOK_COMMENT: - state->handler = prolog1; - return XML_ROLE_COMMENT; - case XML_TOK_BOM: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) - break; - state->handler = doctype0; - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static int PTRCALL -prolog1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_PI: - return XML_ROLE_PI; - case XML_TOK_COMMENT: - return XML_ROLE_COMMENT; - case XML_TOK_BOM: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) - break; - state->handler = doctype0; - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static int PTRCALL -prolog2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_PI: - return XML_ROLE_PI; - case XML_TOK_COMMENT: - return XML_ROLE_COMMENT; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static int PTRCALL -doctype0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = doctype1; - return XML_ROLE_DOCTYPE_NAME; - } - return common(state, tok); -} - -static int PTRCALL -doctype1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = internalSubset; - return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = doctype3; - return XML_ROLE_DOCTYPE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = doctype2; - return XML_ROLE_DOCTYPE_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -doctype2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_LITERAL: - state->handler = doctype3; - return XML_ROLE_DOCTYPE_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -doctype3(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_LITERAL: - state->handler = doctype4; - return XML_ROLE_DOCTYPE_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -doctype4(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = internalSubset; - return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - } - return common(state, tok); -} - -static int PTRCALL -doctype5(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - } - return common(state, tok); -} - -static int PTRCALL -internalSubset(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ENTITY)) { - state->handler = entity0; - return XML_ROLE_ENTITY_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ATTLIST)) { - state->handler = attlist0; - return XML_ROLE_ATTLIST_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ELEMENT)) { - state->handler = element0; - return XML_ROLE_ELEMENT_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_NOTATION)) { - state->handler = notation0; - return XML_ROLE_NOTATION_NONE; - } - break; - case XML_TOK_PI: - return XML_ROLE_PI; - case XML_TOK_COMMENT: - return XML_ROLE_COMMENT; - case XML_TOK_PARAM_ENTITY_REF: - return XML_ROLE_PARAM_ENTITY_REF; - case XML_TOK_CLOSE_BRACKET: - state->handler = doctype5; - return XML_ROLE_DOCTYPE_NONE; - case XML_TOK_NONE: - return XML_ROLE_NONE; - } - return common(state, tok); -} - -#ifdef XML_DTD - -static int PTRCALL -externalSubset0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - state->handler = externalSubset1; - if (tok == XML_TOK_XML_DECL) - return XML_ROLE_TEXT_DECL; - return externalSubset1(state, tok, ptr, end, enc); -} - -static int PTRCALL -externalSubset1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_COND_SECT_OPEN: - state->handler = condSect0; - return XML_ROLE_NONE; - case XML_TOK_COND_SECT_CLOSE: - if (state->includeLevel == 0) - break; - state->includeLevel -= 1; - return XML_ROLE_NONE; - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_BRACKET: - break; - case XML_TOK_NONE: - if (state->includeLevel) - break; - return XML_ROLE_NONE; - default: - return internalSubset(state, tok, ptr, end, enc); - } - return common(state, tok); -} - -#endif /* XML_DTD */ - -static int PTRCALL -entity0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_PERCENT: - state->handler = entity1; - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - state->handler = entity2; - return XML_ROLE_GENERAL_ENTITY_NAME; - } - return common(state, tok); -} - -static int PTRCALL -entity1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - state->handler = entity7; - return XML_ROLE_PARAM_ENTITY_NAME; - } - return common(state, tok); -} - -static int PTRCALL -entity2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = entity4; - return XML_ROLE_ENTITY_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = entity3; - return XML_ROLE_ENTITY_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_ENTITY_NONE; - return XML_ROLE_ENTITY_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -entity3(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity4; - return XML_ROLE_ENTITY_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity4(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity5; - return XML_ROLE_ENTITY_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity5(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_ENTITY_COMPLETE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { - state->handler = entity6; - return XML_ROLE_ENTITY_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -entity6(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - state->handler = declClose; - state->role_none = XML_ROLE_ENTITY_NONE; - return XML_ROLE_ENTITY_NOTATION_NAME; - } - return common(state, tok); -} - -static int PTRCALL -entity7(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = entity9; - return XML_ROLE_ENTITY_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = entity8; - return XML_ROLE_ENTITY_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_ENTITY_NONE; - return XML_ROLE_ENTITY_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -entity8(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity9; - return XML_ROLE_ENTITY_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity9(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_LITERAL: - state->handler = entity10; - return XML_ROLE_ENTITY_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -entity10(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ENTITY_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_ENTITY_COMPLETE; - } - return common(state, tok); -} - -static int PTRCALL -notation0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_NAME: - state->handler = notation1; - return XML_ROLE_NOTATION_NAME; - } - return common(state, tok); -} - -static int PTRCALL -notation1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = notation3; - return XML_ROLE_NOTATION_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = notation2; - return XML_ROLE_NOTATION_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -notation2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_LITERAL: - state->handler = notation4; - return XML_ROLE_NOTATION_PUBLIC_ID; - } - return common(state, tok); -} - -static int PTRCALL -notation3(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_NOTATION_NONE; - return XML_ROLE_NOTATION_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -notation4(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NOTATION_NONE; - case XML_TOK_LITERAL: - state->handler = declClose; - state->role_none = XML_ROLE_NOTATION_NONE; - return XML_ROLE_NOTATION_SYSTEM_ID; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_NOTATION_NO_SYSTEM_ID; - } - return common(state, tok); -} - -static int PTRCALL -attlist0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist1; - return XML_ROLE_ATTLIST_ELEMENT_NAME; - } - return common(state, tok); -} - -static int PTRCALL -attlist1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist2; - return XML_ROLE_ATTRIBUTE_NAME; - } - return common(state, tok); -} - -static int PTRCALL -attlist2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - { - static const char * const types[] = { - KW_CDATA, - KW_ID, - KW_IDREF, - KW_IDREFS, - KW_ENTITY, - KW_ENTITIES, - KW_NMTOKEN, - KW_NMTOKENS, - }; - int i; - for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) - if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { - state->handler = attlist8; - return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; - } - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { - state->handler = attlist5; - return XML_ROLE_ATTLIST_NONE; - } - break; - case XML_TOK_OPEN_PAREN: - state->handler = attlist3; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -static int PTRCALL -attlist3(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NMTOKEN: - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist4; - return XML_ROLE_ATTRIBUTE_ENUM_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -attlist4(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = attlist8; - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_OR: - state->handler = attlist3; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -static int PTRCALL -attlist5(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_OPEN_PAREN: - state->handler = attlist6; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -static int PTRCALL -attlist6(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_NAME: - state->handler = attlist7; - return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -attlist7(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = attlist8; - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_OR: - state->handler = attlist6; - return XML_ROLE_ATTLIST_NONE; - } - return common(state, tok); -} - -/* default value */ -static int PTRCALL -attlist8(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_IMPLIED)) { - state->handler = attlist1; - return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; - } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_REQUIRED)) { - state->handler = attlist1; - return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; - } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_FIXED)) { - state->handler = attlist9; - return XML_ROLE_ATTLIST_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = attlist1; - return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -attlist9(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ATTLIST_NONE; - case XML_TOK_LITERAL: - state->handler = attlist1; - return XML_ROLE_FIXED_ATTRIBUTE_VALUE; - } - return common(state, tok); -} - -static int PTRCALL -element0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element1; - return XML_ROLE_ELEMENT_NAME; - } - return common(state, tok); -} - -static int PTRCALL -element1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_CONTENT_EMPTY; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_CONTENT_ANY; - } - break; - case XML_TOK_OPEN_PAREN: - state->handler = element2; - state->level = 1; - return XML_ROLE_GROUP_OPEN; - } - return common(state, tok); -} - -static int PTRCALL -element2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_PCDATA)) { - state->handler = element3; - return XML_ROLE_CONTENT_PCDATA; - } - break; - case XML_TOK_OPEN_PAREN: - state->level = 2; - state->handler = element6; - return XML_ROLE_GROUP_OPEN; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT; - case XML_TOK_NAME_QUESTION: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_OPT; - case XML_TOK_NAME_ASTERISK: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_REP; - case XML_TOK_NAME_PLUS: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_PLUS; - } - return common(state, tok); -} - -static int PTRCALL -element3(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_GROUP_CLOSE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_OR: - state->handler = element4; - return XML_ROLE_ELEMENT_NONE; - } - return common(state, tok); -} - -static int PTRCALL -element4(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element5; - return XML_ROLE_CONTENT_ELEMENT; - } - return common(state, tok); -} - -static int PTRCALL -element5(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_OR: - state->handler = element4; - return XML_ROLE_ELEMENT_NONE; - } - return common(state, tok); -} - -static int PTRCALL -element6(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_OPEN_PAREN: - state->level += 1; - return XML_ROLE_GROUP_OPEN; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT; - case XML_TOK_NAME_QUESTION: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_OPT; - case XML_TOK_NAME_ASTERISK: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_REP; - case XML_TOK_NAME_PLUS: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_PLUS; - } - return common(state, tok); -} - -static int PTRCALL -element7(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_ELEMENT_NONE; - case XML_TOK_CLOSE_PAREN: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_CLOSE_PAREN_QUESTION: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE_OPT; - case XML_TOK_CLOSE_PAREN_PLUS: - state->level -= 1; - if (state->level == 0) { - state->handler = declClose; - state->role_none = XML_ROLE_ELEMENT_NONE; - } - return XML_ROLE_GROUP_CLOSE_PLUS; - case XML_TOK_COMMA: - state->handler = element6; - return XML_ROLE_GROUP_SEQUENCE; - case XML_TOK_OR: - state->handler = element6; - return XML_ROLE_GROUP_CHOICE; - } - return common(state, tok); -} - -#ifdef XML_DTD - -static int PTRCALL -condSect0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { - state->handler = condSect1; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { - state->handler = condSect2; - return XML_ROLE_NONE; - } - break; - } - return common(state, tok); -} - -static int PTRCALL -condSect1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = externalSubset1; - state->includeLevel += 1; - return XML_ROLE_NONE; - } - return common(state, tok); -} - -static int PTRCALL -condSect2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = externalSubset1; - return XML_ROLE_IGNORE_SECT; - } - return common(state, tok); -} - -#endif /* XML_DTD */ - -static int PTRCALL -declClose(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return state->role_none; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return state->role_none; - } - return common(state, tok); -} - -static int PTRCALL -error(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - return XML_ROLE_NONE; -} - -static int FASTCALL -common(PROLOG_STATE *state, int tok) -{ -#ifdef XML_DTD - if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) - return XML_ROLE_INNER_PARAM_ENTITY_REF; -#endif - state->handler = error; - return XML_ROLE_ERROR; -} - -void -XmlPrologStateInit(PROLOG_STATE *state) -{ - state->handler = prolog0; -#ifdef XML_DTD - state->documentEntity = 1; - state->includeLevel = 0; - state->inEntityValue = 0; -#endif /* XML_DTD */ -} - -#ifdef XML_DTD - -void -XmlPrologStateInitExternalEntity(PROLOG_STATE *state) -{ - state->handler = externalSubset0; - state->documentEntity = 0; - state->includeLevel = 0; -} - -#endif /* XML_DTD */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlrole.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlrole.h deleted file mode 100644 index 4dd9f06..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmlrole.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#ifndef XmlRole_INCLUDED -#define XmlRole_INCLUDED 1 - -#ifdef __VMS -/* 0 1 2 3 0 1 2 3 - 1234567890123456789012345678901 1234567890123456789012345678901 */ -#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt -#endif - -#include "xmltok.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - XML_ROLE_ERROR = -1, - XML_ROLE_NONE = 0, - XML_ROLE_XML_DECL, - XML_ROLE_INSTANCE_START, - XML_ROLE_DOCTYPE_NONE, - XML_ROLE_DOCTYPE_NAME, - XML_ROLE_DOCTYPE_SYSTEM_ID, - XML_ROLE_DOCTYPE_PUBLIC_ID, - XML_ROLE_DOCTYPE_INTERNAL_SUBSET, - XML_ROLE_DOCTYPE_CLOSE, - XML_ROLE_GENERAL_ENTITY_NAME, - XML_ROLE_PARAM_ENTITY_NAME, - XML_ROLE_ENTITY_NONE, - XML_ROLE_ENTITY_VALUE, - XML_ROLE_ENTITY_SYSTEM_ID, - XML_ROLE_ENTITY_PUBLIC_ID, - XML_ROLE_ENTITY_COMPLETE, - XML_ROLE_ENTITY_NOTATION_NAME, - XML_ROLE_NOTATION_NONE, - XML_ROLE_NOTATION_NAME, - XML_ROLE_NOTATION_SYSTEM_ID, - XML_ROLE_NOTATION_NO_SYSTEM_ID, - XML_ROLE_NOTATION_PUBLIC_ID, - XML_ROLE_ATTRIBUTE_NAME, - XML_ROLE_ATTRIBUTE_TYPE_CDATA, - XML_ROLE_ATTRIBUTE_TYPE_ID, - XML_ROLE_ATTRIBUTE_TYPE_IDREF, - XML_ROLE_ATTRIBUTE_TYPE_IDREFS, - XML_ROLE_ATTRIBUTE_TYPE_ENTITY, - XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, - XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, - XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, - XML_ROLE_ATTRIBUTE_ENUM_VALUE, - XML_ROLE_ATTRIBUTE_NOTATION_VALUE, - XML_ROLE_ATTLIST_NONE, - XML_ROLE_ATTLIST_ELEMENT_NAME, - XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, - XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, - XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, - XML_ROLE_FIXED_ATTRIBUTE_VALUE, - XML_ROLE_ELEMENT_NONE, - XML_ROLE_ELEMENT_NAME, - XML_ROLE_CONTENT_ANY, - XML_ROLE_CONTENT_EMPTY, - XML_ROLE_CONTENT_PCDATA, - XML_ROLE_GROUP_OPEN, - XML_ROLE_GROUP_CLOSE, - XML_ROLE_GROUP_CLOSE_REP, - XML_ROLE_GROUP_CLOSE_OPT, - XML_ROLE_GROUP_CLOSE_PLUS, - XML_ROLE_GROUP_CHOICE, - XML_ROLE_GROUP_SEQUENCE, - XML_ROLE_CONTENT_ELEMENT, - XML_ROLE_CONTENT_ELEMENT_REP, - XML_ROLE_CONTENT_ELEMENT_OPT, - XML_ROLE_CONTENT_ELEMENT_PLUS, - XML_ROLE_PI, - XML_ROLE_COMMENT, -#ifdef XML_DTD - XML_ROLE_TEXT_DECL, - XML_ROLE_IGNORE_SECT, - XML_ROLE_INNER_PARAM_ENTITY_REF, -#endif /* XML_DTD */ - XML_ROLE_PARAM_ENTITY_REF -}; - -typedef struct prolog_state { - int (PTRCALL *handler) (struct prolog_state *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc); - unsigned level; - int role_none; -#ifdef XML_DTD - unsigned includeLevel; - int documentEntity; - int inEntityValue; -#endif /* XML_DTD */ -} PROLOG_STATE; - -void XmlPrologStateInit(PROLOG_STATE *); -#ifdef XML_DTD -void XmlPrologStateInitExternalEntity(PROLOG_STATE *); -#endif /* XML_DTD */ - -#define XmlTokenRole(state, tok, ptr, end, enc) \ - (((state)->handler)(state, tok, ptr, end, enc)) - -#ifdef __cplusplus -} -#endif - -#endif /* not XmlRole_INCLUDED */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok.c b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok.c deleted file mode 100644 index 068afde..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok.c +++ /dev/null @@ -1,1651 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#include <stddef.h> - -#ifdef COMPILED_FROM_DSP -#include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos4__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" -#else -#ifdef HAVE_EXPAT_CONFIG_H -#include <expat_config.h> -#endif -#endif /* ndef COMPILED_FROM_DSP */ - -#include "expat_external.h" -#include "internal.h" -#include "xmltok.h" -#include "nametab.h" - -#ifdef XML_DTD -#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) -#else -#define IGNORE_SECTION_TOK_VTABLE /* as nothing */ -#endif - -#define VTABLE1 \ - { PREFIX(prologTok), PREFIX(contentTok), \ - PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ - { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ - PREFIX(sameName), \ - PREFIX(nameMatchesAscii), \ - PREFIX(nameLength), \ - PREFIX(skipS), \ - PREFIX(getAtts), \ - PREFIX(charRefNumber), \ - PREFIX(predefinedEntityName), \ - PREFIX(updatePosition), \ - PREFIX(isPublicId) - -#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) - -#define UCS2_GET_NAMING(pages, hi, lo) \ - (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) - -/* A 2 byte UTF-8 representation splits the characters 11 bits between - the bottom 5 and 6 bits of the bytes. We need 8 bits to index into - pages, 3 bits to add to that index and 5 bits to generate the mask. -*/ -#define UTF8_GET_NAMING2(pages, byte) \ - (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ - + ((((byte)[0]) & 3) << 1) \ - + ((((byte)[1]) >> 5) & 1)] \ - & (1 << (((byte)[1]) & 0x1F))) - -/* A 3 byte UTF-8 representation splits the characters 16 bits between - the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index - into pages, 3 bits to add to that index and 5 bits to generate the - mask. -*/ -#define UTF8_GET_NAMING3(pages, byte) \ - (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ - + ((((byte)[1]) >> 2) & 0xF)] \ - << 3) \ - + ((((byte)[1]) & 3) << 1) \ - + ((((byte)[2]) >> 5) & 1)] \ - & (1 << (((byte)[2]) & 0x1F))) - -#define UTF8_GET_NAMING(pages, p, n) \ - ((n) == 2 \ - ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ - : ((n) == 3 \ - ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ - : 0)) - -/* Detection of invalid UTF-8 sequences is based on Table 3.1B - of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ - with the additional restriction of not allowing the Unicode - code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). - Implementation details: - (A & 0x80) == 0 means A < 0x80 - and - (A & 0xC0) == 0xC0 means A > 0xBF -*/ - -#define UTF8_INVALID2(p) \ - ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) - -#define UTF8_INVALID3(p) \ - (((p)[2] & 0x80) == 0 \ - || \ - ((*p) == 0xEF && (p)[1] == 0xBF \ - ? \ - (p)[2] > 0xBD \ - : \ - ((p)[2] & 0xC0) == 0xC0) \ - || \ - ((*p) == 0xE0 \ - ? \ - (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ - : \ - ((p)[1] & 0x80) == 0 \ - || \ - ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) - -#define UTF8_INVALID4(p) \ - (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \ - || \ - ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \ - || \ - ((*p) == 0xF0 \ - ? \ - (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ - : \ - ((p)[1] & 0x80) == 0 \ - || \ - ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) - -static int PTRFASTCALL -isNever(const ENCODING *enc, const char *p) -{ - return 0; -} - -static int PTRFASTCALL -utf8_isName2(const ENCODING *enc, const char *p) -{ - return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isName3(const ENCODING *enc, const char *p) -{ - return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); -} - -#define utf8_isName4 isNever - -static int PTRFASTCALL -utf8_isNmstrt2(const ENCODING *enc, const char *p) -{ - return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isNmstrt3(const ENCODING *enc, const char *p) -{ - return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); -} - -#define utf8_isNmstrt4 isNever - -static int PTRFASTCALL -utf8_isInvalid2(const ENCODING *enc, const char *p) -{ - return UTF8_INVALID2((const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isInvalid3(const ENCODING *enc, const char *p) -{ - return UTF8_INVALID3((const unsigned char *)p); -} - -static int PTRFASTCALL -utf8_isInvalid4(const ENCODING *enc, const char *p) -{ - return UTF8_INVALID4((const unsigned char *)p); -} - -struct normal_encoding { - ENCODING enc; - unsigned char type[256]; -#ifdef XML_MIN_SIZE - int (PTRFASTCALL *byteType)(const ENCODING *, const char *); - int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); - int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); - int (PTRCALL *charMatches)(const ENCODING *, const char *, int); -#endif /* XML_MIN_SIZE */ - int (PTRFASTCALL *isName2)(const ENCODING *, const char *); - int (PTRFASTCALL *isName3)(const ENCODING *, const char *); - int (PTRFASTCALL *isName4)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); - int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); - int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); -}; - -#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc)) - -#ifdef XML_MIN_SIZE - -#define STANDARD_VTABLE(E) \ - E ## byteType, \ - E ## isNameMin, \ - E ## isNmstrtMin, \ - E ## byteToAscii, \ - E ## charMatches, - -#else - -#define STANDARD_VTABLE(E) /* as nothing */ - -#endif - -#define NORMAL_VTABLE(E) \ - E ## isName2, \ - E ## isName3, \ - E ## isName4, \ - E ## isNmstrt2, \ - E ## isNmstrt3, \ - E ## isNmstrt4, \ - E ## isInvalid2, \ - E ## isInvalid3, \ - E ## isInvalid4 - -static int FASTCALL checkCharRefNumber(int); - -#include "xmltok_impl.h" -#include "ascii.h" - -#ifdef XML_MIN_SIZE -#define sb_isNameMin isNever -#define sb_isNmstrtMin isNever -#endif - -#ifdef XML_MIN_SIZE -#define MINBPC(enc) ((enc)->minBytesPerChar) -#else -/* minimum bytes per character */ -#define MINBPC(enc) 1 -#endif - -#define SB_BYTE_TYPE(enc, p) \ - (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) - -#ifdef XML_MIN_SIZE -static int PTRFASTCALL -sb_byteType(const ENCODING *enc, const char *p) -{ - return SB_BYTE_TYPE(enc, p); -} -#define BYTE_TYPE(enc, p) \ - (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) -#else -#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) -#endif - -#ifdef XML_MIN_SIZE -#define BYTE_TO_ASCII(enc, p) \ - (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) -static int PTRFASTCALL -sb_byteToAscii(const ENCODING *enc, const char *p) -{ - return *p; -} -#else -#define BYTE_TO_ASCII(enc, p) (*(p)) -#endif - -#define IS_NAME_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p)) -#define IS_NMSTRT_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p)) -#define IS_INVALID_CHAR(enc, p, n) \ - (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p)) - -#ifdef XML_MIN_SIZE -#define IS_NAME_CHAR_MINBPC(enc, p) \ - (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ - (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) -#else -#define IS_NAME_CHAR_MINBPC(enc, p) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) -#endif - -#ifdef XML_MIN_SIZE -#define CHAR_MATCHES(enc, p, c) \ - (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) -static int PTRCALL -sb_charMatches(const ENCODING *enc, const char *p, int c) -{ - return *p == c; -} -#else -/* c is an ASCII character */ -#define CHAR_MATCHES(enc, p, c) (*(p) == c) -#endif - -#define PREFIX(ident) normal_ ## ident -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ - UTF8_cval1 = 0x00, - UTF8_cval2 = 0xc0, - UTF8_cval3 = 0xe0, - UTF8_cval4 = 0xf0 -}; - -static void PTRCALL -utf8_toUtf8(const ENCODING *enc, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - char *to; - const char *from; - if (fromLim - *fromP > toLim - *toP) { - /* Avoid copying partial characters. */ - for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) - if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) - break; - } - for (to = *toP, from = *fromP; from != fromLim; from++, to++) - *to = *from; - *fromP = from; - *toP = to; -} - -static void PTRCALL -utf8_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - unsigned short *to = *toP; - const char *from = *fromP; - while (from != fromLim && to != toLim) { - switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { - case BT_LEAD2: - *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); - from += 2; - break; - case BT_LEAD3: - *to++ = (unsigned short)(((from[0] & 0xf) << 12) - | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); - from += 3; - break; - case BT_LEAD4: - { - unsigned long n; - if (to + 1 == toLim) - goto after; - n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) - | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); - n -= 0x10000; - to[0] = (unsigned short)((n >> 10) | 0xD800); - to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); - to += 2; - from += 4; - } - break; - default: - *to++ = *from++; - break; - } - } -after: - *fromP = from; - *toP = to; -} - -#ifdef XML_NS -static const struct normal_encoding utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; -#endif - -static const struct normal_encoding utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -#ifdef XML_NS - -static const struct normal_encoding internal_utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "iasciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -#endif - -static const struct normal_encoding internal_utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -static void PTRCALL -latin1_toUtf8(const ENCODING *enc, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - for (;;) { - unsigned char c; - if (*fromP == fromLim) - break; - c = (unsigned char)**fromP; - if (c & 0x80) { - if (toLim - *toP < 2) - break; - *(*toP)++ = (char)((c >> 6) | UTF8_cval2); - *(*toP)++ = (char)((c & 0x3f) | 0x80); - (*fromP)++; - } - else { - if (*toP == toLim) - break; - *(*toP)++ = *(*fromP)++; - } - } -} - -static void PTRCALL -latin1_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - while (*fromP != fromLim && *toP != toLim) - *(*toP)++ = (unsigned char)*(*fromP)++; -} - -#ifdef XML_NS - -static const struct normal_encoding latin1_encoding_ns = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) -}; - -#endif - -static const struct normal_encoding latin1_encoding = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) -}; - -static void PTRCALL -ascii_toUtf8(const ENCODING *enc, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - while (*fromP != fromLim && *toP != toLim) - *(*toP)++ = *(*fromP)++; -} - -#ifdef XML_NS - -static const struct normal_encoding ascii_encoding_ns = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) -}; - -#endif - -static const struct normal_encoding ascii_encoding = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) -}; - -static int PTRFASTCALL -unicode_byte_type(char hi, char lo) -{ - switch ((unsigned char)hi) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - return BT_LEAD4; - case 0xDC: case 0xDD: case 0xDE: case 0xDF: - return BT_TRAIL; - case 0xFF: - switch ((unsigned char)lo) { - case 0xFF: - case 0xFE: - return BT_NONXML; - } - break; - } - return BT_NONASCII; -} - -#define DEFINE_UTF16_TO_UTF8(E) \ -static void PTRCALL \ -E ## toUtf8(const ENCODING *enc, \ - const char **fromP, const char *fromLim, \ - char **toP, const char *toLim) \ -{ \ - const char *from; \ - for (from = *fromP; from != fromLim; from += 2) { \ - int plane; \ - unsigned char lo2; \ - unsigned char lo = GET_LO(from); \ - unsigned char hi = GET_HI(from); \ - switch (hi) { \ - case 0: \ - if (lo < 0x80) { \ - if (*toP == toLim) { \ - *fromP = from; \ - return; \ - } \ - *(*toP)++ = lo; \ - break; \ - } \ - /* fall through */ \ - case 0x1: case 0x2: case 0x3: \ - case 0x4: case 0x5: case 0x6: case 0x7: \ - if (toLim - *toP < 2) { \ - *fromP = from; \ - return; \ - } \ - *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - default: \ - if (toLim - *toP < 3) { \ - *fromP = from; \ - return; \ - } \ - /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ - *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ - *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ - if (toLim - *toP < 4) { \ - *fromP = from; \ - return; \ - } \ - plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ - *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ - *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ - from += 2; \ - lo2 = GET_LO(from); \ - *(*toP)++ = (((lo & 0x3) << 4) \ - | ((GET_HI(from) & 0x3) << 2) \ - | (lo2 >> 6) \ - | 0x80); \ - *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ - break; \ - } \ - } \ - *fromP = from; \ -} - -#define DEFINE_UTF16_TO_UTF16(E) \ -static void PTRCALL \ -E ## toUtf16(const ENCODING *enc, \ - const char **fromP, const char *fromLim, \ - unsigned short **toP, const unsigned short *toLim) \ -{ \ - /* Avoid copying first half only of surrogate */ \ - if (fromLim - *fromP > ((toLim - *toP) << 1) \ - && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ - fromLim -= 2; \ - for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ - *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ -} - -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) -#define GET_LO(ptr) ((unsigned char)(ptr)[0]) -#define GET_HI(ptr) ((unsigned char)(ptr)[1]) - -DEFINE_UTF16_TO_UTF8(little2_) -DEFINE_UTF16_TO_UTF16(little2_) - -#undef SET2 -#undef GET_LO -#undef GET_HI - -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) -#define GET_LO(ptr) ((unsigned char)(ptr)[1]) -#define GET_HI(ptr) ((unsigned char)(ptr)[0]) - -DEFINE_UTF16_TO_UTF8(big2_) -DEFINE_UTF16_TO_UTF16(big2_) - -#undef SET2 -#undef GET_LO -#undef GET_HI - -#define LITTLE2_BYTE_TYPE(enc, p) \ - ((p)[1] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ - : unicode_byte_type((p)[1], (p)[0])) -#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) -#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) -#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) -#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) - -#ifdef XML_MIN_SIZE - -static int PTRFASTCALL -little2_byteType(const ENCODING *enc, const char *p) -{ - return LITTLE2_BYTE_TYPE(enc, p); -} - -static int PTRFASTCALL -little2_byteToAscii(const ENCODING *enc, const char *p) -{ - return LITTLE2_BYTE_TO_ASCII(enc, p); -} - -static int PTRCALL -little2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return LITTLE2_CHAR_MATCHES(enc, p, c); -} - -static int PTRFASTCALL -little2_isNameMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); -} - -static int PTRFASTCALL -little2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); -} - -#undef VTABLE -#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 - -#else /* not XML_MIN_SIZE */ - -#undef PREFIX -#define PREFIX(ident) little2_ ## ident -#define MINBPC(enc) 2 -/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -#endif /* not XML_MIN_SIZE */ - -#ifdef XML_NS - -static const struct normal_encoding little2_encoding_ns = { - { VTABLE, 2, 0, -#if BYTEORDER == 1234 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) -}; - -#endif - -static const struct normal_encoding little2_encoding = { - { VTABLE, 2, 0, -#if BYTEORDER == 1234 - 1 -#else - 0 -#endif - }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) -}; - -#if BYTEORDER != 4321 - -#ifdef XML_NS - -static const struct normal_encoding internal_little2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) -}; - -#endif - -static const struct normal_encoding internal_little2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) -}; - -#endif - - -#define BIG2_BYTE_TYPE(enc, p) \ - ((p)[0] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ - : unicode_byte_type((p)[0], (p)[1])) -#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) -#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) -#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) -#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) - -#ifdef XML_MIN_SIZE - -static int PTRFASTCALL -big2_byteType(const ENCODING *enc, const char *p) -{ - return BIG2_BYTE_TYPE(enc, p); -} - -static int PTRFASTCALL -big2_byteToAscii(const ENCODING *enc, const char *p) -{ - return BIG2_BYTE_TO_ASCII(enc, p); -} - -static int PTRCALL -big2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return BIG2_CHAR_MATCHES(enc, p, c); -} - -static int PTRFASTCALL -big2_isNameMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NAME_CHAR_MINBPC(enc, p); -} - -static int PTRFASTCALL -big2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); -} - -#undef VTABLE -#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 - -#else /* not XML_MIN_SIZE */ - -#undef PREFIX -#define PREFIX(ident) big2_ ## ident -#define MINBPC(enc) 2 -/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#define XML_TOK_IMPL_C -#include "xmltok_impl.c" -#undef XML_TOK_IMPL_C - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -#endif /* not XML_MIN_SIZE */ - -#ifdef XML_NS - -static const struct normal_encoding big2_encoding_ns = { - { VTABLE, 2, 0, -#if BYTEORDER == 4321 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) -}; - -#endif - -static const struct normal_encoding big2_encoding = { - { VTABLE, 2, 0, -#if BYTEORDER == 4321 - 1 -#else - 0 -#endif - }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) -}; - -#if BYTEORDER != 1234 - -#ifdef XML_NS - -static const struct normal_encoding internal_big2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) -}; - -#endif - -static const struct normal_encoding internal_big2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) -}; - -#endif - -#undef PREFIX - -static int FASTCALL -streqci(const char *s1, const char *s2) -{ - for (;;) { - char c1 = *s1++; - char c2 = *s2++; - if (ASCII_a <= c1 && c1 <= ASCII_z) - c1 += ASCII_A - ASCII_a; - if (ASCII_a <= c2 && c2 <= ASCII_z) - c2 += ASCII_A - ASCII_a; - if (c1 != c2) - return 0; - if (!c1) - break; - } - return 1; -} - -static void PTRCALL -initUpdatePosition(const ENCODING *enc, const char *ptr, - const char *end, POSITION *pos) -{ - normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); -} - -static int -toAscii(const ENCODING *enc, const char *ptr, const char *end) -{ - char buf[1]; - char *p = buf; - XmlUtf8Convert(enc, &ptr, end, &p, p + 1); - if (p == buf) - return -1; - else - return buf[0]; -} - -static int FASTCALL -isSpace(int c) -{ - switch (c) { - case 0x20: - case 0xD: - case 0xA: - case 0x9: - return 1; - } - return 0; -} - -/* Return 1 if there's just optional white space or there's an S - followed by name=val. -*/ -static int -parsePseudoAttribute(const ENCODING *enc, - const char *ptr, - const char *end, - const char **namePtr, - const char **nameEndPtr, - const char **valPtr, - const char **nextTokPtr) -{ - int c; - char open; - if (ptr == end) { - *namePtr = NULL; - return 1; - } - if (!isSpace(toAscii(enc, ptr, end))) { - *nextTokPtr = ptr; - return 0; - } - do { - ptr += enc->minBytesPerChar; - } while (isSpace(toAscii(enc, ptr, end))); - if (ptr == end) { - *namePtr = NULL; - return 1; - } - *namePtr = ptr; - for (;;) { - c = toAscii(enc, ptr, end); - if (c == -1) { - *nextTokPtr = ptr; - return 0; - } - if (c == ASCII_EQUALS) { - *nameEndPtr = ptr; - break; - } - if (isSpace(c)) { - *nameEndPtr = ptr; - do { - ptr += enc->minBytesPerChar; - } while (isSpace(c = toAscii(enc, ptr, end))); - if (c != ASCII_EQUALS) { - *nextTokPtr = ptr; - return 0; - } - break; - } - ptr += enc->minBytesPerChar; - } - if (ptr == *namePtr) { - *nextTokPtr = ptr; - return 0; - } - ptr += enc->minBytesPerChar; - c = toAscii(enc, ptr, end); - while (isSpace(c)) { - ptr += enc->minBytesPerChar; - c = toAscii(enc, ptr, end); - } - if (c != ASCII_QUOT && c != ASCII_APOS) { - *nextTokPtr = ptr; - return 0; - } - open = (char)c; - ptr += enc->minBytesPerChar; - *valPtr = ptr; - for (;; ptr += enc->minBytesPerChar) { - c = toAscii(enc, ptr, end); - if (c == open) - break; - if (!(ASCII_a <= c && c <= ASCII_z) - && !(ASCII_A <= c && c <= ASCII_Z) - && !(ASCII_0 <= c && c <= ASCII_9) - && c != ASCII_PERIOD - && c != ASCII_MINUS - && c != ASCII_UNDERSCORE) { - *nextTokPtr = ptr; - return 0; - } - } - *nextTokPtr = ptr + enc->minBytesPerChar; - return 1; -} - -static const char KW_version[] = { - ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0' -}; - -static const char KW_encoding[] = { - ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0' -}; - -static const char KW_standalone[] = { - ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, - ASCII_n, ASCII_e, '\0' -}; - -static const char KW_yes[] = { - ASCII_y, ASCII_e, ASCII_s, '\0' -}; - -static const char KW_no[] = { - ASCII_n, ASCII_o, '\0' -}; - -static int -doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, - const char *, - const char *), - int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingName, - const ENCODING **encoding, - int *standalone) -{ - const char *val = NULL; - const char *name = NULL; - const char *nameEnd = NULL; - ptr += 5 * enc->minBytesPerChar; - end -= 2 * enc->minBytesPerChar; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) - || !name) { - *badPtr = ptr; - return 0; - } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { - if (!isGeneralTextEntity) { - *badPtr = name; - return 0; - } - } - else { - if (versionPtr) - *versionPtr = val; - if (versionEndPtr) - *versionEndPtr = ptr; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { - *badPtr = ptr; - return 0; - } - if (!name) { - if (isGeneralTextEntity) { - /* a TextDecl must have an EncodingDecl */ - *badPtr = ptr; - return 0; - } - return 1; - } - } - if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { - int c = toAscii(enc, val, end); - if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) { - *badPtr = val; - return 0; - } - if (encodingName) - *encodingName = val; - if (encoding) - *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { - *badPtr = ptr; - return 0; - } - if (!name) - return 1; - } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) - || isGeneralTextEntity) { - *badPtr = name; - return 0; - } - if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { - if (standalone) - *standalone = 1; - } - else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { - if (standalone) - *standalone = 0; - } - else { - *badPtr = val; - return 0; - } - while (isSpace(toAscii(enc, ptr, end))) - ptr += enc->minBytesPerChar; - if (ptr != end) { - *badPtr = ptr; - return 0; - } - return 1; -} - -static int FASTCALL -checkCharRefNumber(int result) -{ - switch (result >> 8) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - case 0xDC: case 0xDD: case 0xDE: case 0xDF: - return -1; - case 0: - if (latin1_encoding.type[result] == BT_NONXML) - return -1; - break; - case 0xFF: - if (result == 0xFFFE || result == 0xFFFF) - return -1; - break; - } - return result; -} - -int FASTCALL -XmlUtf8Encode(int c, char *buf) -{ - enum { - /* minN is minimum legal resulting value for N byte sequence */ - min2 = 0x80, - min3 = 0x800, - min4 = 0x10000 - }; - - if (c < 0) - return 0; - if (c < min2) { - buf[0] = (char)(c | UTF8_cval1); - return 1; - } - if (c < min3) { - buf[0] = (char)((c >> 6) | UTF8_cval2); - buf[1] = (char)((c & 0x3f) | 0x80); - return 2; - } - if (c < min4) { - buf[0] = (char)((c >> 12) | UTF8_cval3); - buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); - buf[2] = (char)((c & 0x3f) | 0x80); - return 3; - } - if (c < 0x110000) { - buf[0] = (char)((c >> 18) | UTF8_cval4); - buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); - buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); - buf[3] = (char)((c & 0x3f) | 0x80); - return 4; - } - return 0; -} - -int FASTCALL -XmlUtf16Encode(int charNum, unsigned short *buf) -{ - if (charNum < 0) - return 0; - if (charNum < 0x10000) { - buf[0] = (unsigned short)charNum; - return 1; - } - if (charNum < 0x110000) { - charNum -= 0x10000; - buf[0] = (unsigned short)((charNum >> 10) + 0xD800); - buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); - return 2; - } - return 0; -} - -struct unknown_encoding { - struct normal_encoding normal; - CONVERTER convert; - void *userData; - unsigned short utf16[256]; - char utf8[256][4]; -}; - -#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc)) - -int -XmlSizeOfUnknownEncoding(void) -{ - return sizeof(struct unknown_encoding); -} - -static int PTRFASTCALL -unknown_isName(const ENCODING *enc, const char *p) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - int c = uenc->convert(uenc->userData, p); - if (c & ~0xFFFF) - return 0; - return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); -} - -static int PTRFASTCALL -unknown_isNmstrt(const ENCODING *enc, const char *p) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - int c = uenc->convert(uenc->userData, p); - if (c & ~0xFFFF) - return 0; - return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); -} - -static int PTRFASTCALL -unknown_isInvalid(const ENCODING *enc, const char *p) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - int c = uenc->convert(uenc->userData, p); - return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; -} - -static void PTRCALL -unknown_toUtf8(const ENCODING *enc, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - char buf[XML_UTF8_ENCODE_MAX]; - for (;;) { - const char *utf8; - int n; - if (*fromP == fromLim) - break; - utf8 = uenc->utf8[(unsigned char)**fromP]; - n = *utf8++; - if (n == 0) { - int c = uenc->convert(uenc->userData, *fromP); - n = XmlUtf8Encode(c, buf); - if (n > toLim - *toP) - break; - utf8 = buf; - *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - - (BT_LEAD2 - 2)); - } - else { - if (n > toLim - *toP) - break; - (*fromP)++; - } - do { - *(*toP)++ = *utf8++; - } while (--n != 0); - } -} - -static void PTRCALL -unknown_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - while (*fromP != fromLim && *toP != toLim) { - unsigned short c = uenc->utf16[(unsigned char)**fromP]; - if (c == 0) { - c = (unsigned short) - uenc->convert(uenc->userData, *fromP); - *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - - (BT_LEAD2 - 2)); - } - else - (*fromP)++; - *(*toP)++ = c; - } -} - -ENCODING * -XmlInitUnknownEncoding(void *mem, - int *table, - CONVERTER convert, - void *userData) -{ - int i; - struct unknown_encoding *e = (struct unknown_encoding *)mem; - for (i = 0; i < (int)sizeof(struct normal_encoding); i++) - ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; - for (i = 0; i < 128; i++) - if (latin1_encoding.type[i] != BT_OTHER - && latin1_encoding.type[i] != BT_NONXML - && table[i] != i) - return 0; - for (i = 0; i < 256; i++) { - int c = table[i]; - if (c == -1) { - e->normal.type[i] = BT_MALFORM; - /* This shouldn't really get used. */ - e->utf16[i] = 0xFFFF; - e->utf8[i][0] = 1; - e->utf8[i][1] = 0; - } - else if (c < 0) { - if (c < -4) - return 0; - e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); - e->utf8[i][0] = 0; - e->utf16[i] = 0; - } - else if (c < 0x80) { - if (latin1_encoding.type[c] != BT_OTHER - && latin1_encoding.type[c] != BT_NONXML - && c != i) - return 0; - e->normal.type[i] = latin1_encoding.type[c]; - e->utf8[i][0] = 1; - e->utf8[i][1] = (char)c; - e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); - } - else if (checkCharRefNumber(c) < 0) { - e->normal.type[i] = BT_NONXML; - /* This shouldn't really get used. */ - e->utf16[i] = 0xFFFF; - e->utf8[i][0] = 1; - e->utf8[i][1] = 0; - } - else { - if (c > 0xFFFF) - return 0; - if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) - e->normal.type[i] = BT_NMSTRT; - else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) - e->normal.type[i] = BT_NAME; - else - e->normal.type[i] = BT_OTHER; - e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); - e->utf16[i] = (unsigned short)c; - } - } - e->userData = userData; - e->convert = convert; - if (convert) { - e->normal.isName2 = unknown_isName; - e->normal.isName3 = unknown_isName; - e->normal.isName4 = unknown_isName; - e->normal.isNmstrt2 = unknown_isNmstrt; - e->normal.isNmstrt3 = unknown_isNmstrt; - e->normal.isNmstrt4 = unknown_isNmstrt; - e->normal.isInvalid2 = unknown_isInvalid; - e->normal.isInvalid3 = unknown_isInvalid; - e->normal.isInvalid4 = unknown_isInvalid; - } - e->normal.enc.utf8Convert = unknown_toUtf8; - e->normal.enc.utf16Convert = unknown_toUtf16; - return &(e->normal.enc); -} - -/* If this enumeration is changed, getEncodingIndex and encodings -must also be changed. */ -enum { - UNKNOWN_ENC = -1, - ISO_8859_1_ENC = 0, - US_ASCII_ENC, - UTF_8_ENC, - UTF_16_ENC, - UTF_16BE_ENC, - UTF_16LE_ENC, - /* must match encodingNames up to here */ - NO_ENC -}; - -static const char KW_ISO_8859_1[] = { - ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, - ASCII_MINUS, ASCII_1, '\0' -}; -static const char KW_US_ASCII[] = { - ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, - '\0' -}; -static const char KW_UTF_8[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0' -}; -static const char KW_UTF_16[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0' -}; -static const char KW_UTF_16BE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, - '\0' -}; -static const char KW_UTF_16LE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, - '\0' -}; - -static int FASTCALL -getEncodingIndex(const char *name) -{ - static const char * const encodingNames[] = { - KW_ISO_8859_1, - KW_US_ASCII, - KW_UTF_8, - KW_UTF_16, - KW_UTF_16BE, - KW_UTF_16LE, - }; - int i; - if (name == NULL) - return NO_ENC; - for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++) - if (streqci(name, encodingNames[i])) - return i; - return UNKNOWN_ENC; -} - -/* For binary compatibility, we store the index of the encoding - specified at initialization in the isUtf16 member. -*/ - -#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) -#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) - -/* This is what detects the encoding. encodingTable maps from - encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of - the external (protocol) specified encoding; state is - XML_CONTENT_STATE if we're parsing an external text entity, and - XML_PROLOG_STATE otherwise. -*/ - - -static int -initScan(const ENCODING * const *encodingTable, - const INIT_ENCODING *enc, - int state, - const char *ptr, - const char *end, - const char **nextTokPtr) -{ - const ENCODING **encPtr; - - if (ptr == end) - return XML_TOK_NONE; - encPtr = enc->encPtr; - if (ptr + 1 == end) { - /* only a single byte available for auto-detection */ -#ifndef XML_DTD /* FIXME */ - /* a well-formed document entity must have more than one byte */ - if (state != XML_CONTENT_STATE) - return XML_TOK_PARTIAL; -#endif - /* so we're parsing an external text entity... */ - /* if UTF-16 was externally specified, then we need at least 2 bytes */ - switch (INIT_ENC_INDEX(enc)) { - case UTF_16_ENC: - case UTF_16LE_ENC: - case UTF_16BE_ENC: - return XML_TOK_PARTIAL; - } - switch ((unsigned char)*ptr) { - case 0xFE: - case 0xFF: - case 0xEF: /* possibly first byte of UTF-8 BOM */ - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - /* fall through */ - case 0x00: - case 0x3C: - return XML_TOK_PARTIAL; - } - } - else { - switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { - case 0xFEFF: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - *nextTokPtr = ptr + 2; - *encPtr = encodingTable[UTF_16BE_ENC]; - return XML_TOK_BOM; - /* 00 3C is handled in the default case */ - case 0x3C00: - if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC - || INIT_ENC_INDEX(enc) == UTF_16_ENC) - && state == XML_CONTENT_STATE) - break; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - case 0xFFFE: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - *nextTokPtr = ptr + 2; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XML_TOK_BOM; - case 0xEFBB: - /* Maybe a UTF-8 BOM (EF BB BF) */ - /* If there's an explicitly specified (external) encoding - of ISO-8859-1 or some flavour of UTF-16 - and this is an external text entity, - don't look for the BOM, - because it might be a legal data. - */ - if (state == XML_CONTENT_STATE) { - int e = INIT_ENC_INDEX(enc); - if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC - || e == UTF_16LE_ENC || e == UTF_16_ENC) - break; - } - if (ptr + 2 == end) - return XML_TOK_PARTIAL; - if ((unsigned char)ptr[2] == 0xBF) { - *nextTokPtr = ptr + 3; - *encPtr = encodingTable[UTF_8_ENC]; - return XML_TOK_BOM; - } - break; - default: - if (ptr[0] == '\0') { - /* 0 isn't a legal data character. Furthermore a document - entity can only start with ASCII characters. So the only - way this can fail to be big-endian UTF-16 if it it's an - external parsed general entity that's labelled as - UTF-16LE. - */ - if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) - break; - *encPtr = encodingTable[UTF_16BE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - } - else if (ptr[1] == '\0') { - /* We could recover here in the case: - - parsing an external entity - - second byte is 0 - - no externally specified encoding - - no encoding declaration - by assuming UTF-16LE. But we don't, because this would mean when - presented just with a single byte, we couldn't reliably determine - whether we needed further bytes. - */ - if (state == XML_CONTENT_STATE) - break; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - } - break; - } - } - *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); -} - - -#define NS(x) x -#define ns(x) x -#define XML_TOK_NS_C -#include "xmltok_ns.c" -#undef XML_TOK_NS_C -#undef NS -#undef ns - -#ifdef XML_NS - -#define NS(x) x ## NS -#define ns(x) x ## _ns - -#define XML_TOK_NS_C -#include "xmltok_ns.c" -#undef XML_TOK_NS_C - -#undef NS -#undef ns - -ENCODING * -XmlInitUnknownEncodingNS(void *mem, - int *table, - CONVERTER convert, - void *userData) -{ - ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); - if (enc) - ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; - return enc; -} - -#endif /* XML_NS */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok.h deleted file mode 100644 index ca867aa..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok.h +++ /dev/null @@ -1,316 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -#ifndef XmlTok_INCLUDED -#define XmlTok_INCLUDED 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* The following token may be returned by XmlContentTok */ -#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be - start of illegal ]]> sequence */ -/* The following tokens may be returned by both XmlPrologTok and - XmlContentTok. -*/ -#define XML_TOK_NONE -4 /* The string to be scanned is empty */ -#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; - might be part of CRLF sequence */ -#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ -#define XML_TOK_PARTIAL -1 /* only part of a token */ -#define XML_TOK_INVALID 0 - -/* The following tokens are returned by XmlContentTok; some are also - returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. -*/ -#define XML_TOK_START_TAG_WITH_ATTS 1 -#define XML_TOK_START_TAG_NO_ATTS 2 -#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */ -#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 -#define XML_TOK_END_TAG 5 -#define XML_TOK_DATA_CHARS 6 -#define XML_TOK_DATA_NEWLINE 7 -#define XML_TOK_CDATA_SECT_OPEN 8 -#define XML_TOK_ENTITY_REF 9 -#define XML_TOK_CHAR_REF 10 /* numeric character reference */ - -/* The following tokens may be returned by both XmlPrologTok and - XmlContentTok. -*/ -#define XML_TOK_PI 11 /* processing instruction */ -#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ -#define XML_TOK_COMMENT 13 -#define XML_TOK_BOM 14 /* Byte order mark */ - -/* The following tokens are returned only by XmlPrologTok */ -#define XML_TOK_PROLOG_S 15 -#define XML_TOK_DECL_OPEN 16 /* <!foo */ -#define XML_TOK_DECL_CLOSE 17 /* > */ -#define XML_TOK_NAME 18 -#define XML_TOK_NMTOKEN 19 -#define XML_TOK_POUND_NAME 20 /* #name */ -#define XML_TOK_OR 21 /* | */ -#define XML_TOK_PERCENT 22 -#define XML_TOK_OPEN_PAREN 23 -#define XML_TOK_CLOSE_PAREN 24 -#define XML_TOK_OPEN_BRACKET 25 -#define XML_TOK_CLOSE_BRACKET 26 -#define XML_TOK_LITERAL 27 -#define XML_TOK_PARAM_ENTITY_REF 28 -#define XML_TOK_INSTANCE_START 29 - -/* The following occur only in element type declarations */ -#define XML_TOK_NAME_QUESTION 30 /* name? */ -#define XML_TOK_NAME_ASTERISK 31 /* name* */ -#define XML_TOK_NAME_PLUS 32 /* name+ */ -#define XML_TOK_COND_SECT_OPEN 33 /* <![ */ -#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */ -#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ -#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ -#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ -#define XML_TOK_COMMA 38 - -/* The following token is returned only by XmlAttributeValueTok */ -#define XML_TOK_ATTRIBUTE_VALUE_S 39 - -/* The following token is returned only by XmlCdataSectionTok */ -#define XML_TOK_CDATA_SECT_CLOSE 40 - -/* With namespace processing this is returned by XmlPrologTok for a - name with a colon. -*/ -#define XML_TOK_PREFIXED_NAME 41 - -#ifdef XML_DTD -#define XML_TOK_IGNORE_SECT 42 -#endif /* XML_DTD */ - -#ifdef XML_DTD -#define XML_N_STATES 4 -#else /* not XML_DTD */ -#define XML_N_STATES 3 -#endif /* not XML_DTD */ - -#define XML_PROLOG_STATE 0 -#define XML_CONTENT_STATE 1 -#define XML_CDATA_SECTION_STATE 2 -#ifdef XML_DTD -#define XML_IGNORE_SECTION_STATE 3 -#endif /* XML_DTD */ - -#define XML_N_LITERAL_TYPES 2 -#define XML_ATTRIBUTE_VALUE_LITERAL 0 -#define XML_ENTITY_VALUE_LITERAL 1 - -/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ -#define XML_UTF8_ENCODE_MAX 4 -/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ -#define XML_UTF16_ENCODE_MAX 2 - -typedef struct position { - /* first line and first column are 0 not 1 */ - XML_Size lineNumber; - XML_Size columnNumber; -} POSITION; - -typedef struct { - const char *name; - const char *valuePtr; - const char *valueEnd; - char normalized; -} ATTRIBUTE; - -struct encoding; -typedef struct encoding ENCODING; - -typedef int (PTRCALL *SCANNER)(const ENCODING *, - const char *, - const char *, - const char **); - -struct encoding { - SCANNER scanners[XML_N_STATES]; - SCANNER literalScanners[XML_N_LITERAL_TYPES]; - int (PTRCALL *sameName)(const ENCODING *, - const char *, - const char *); - int (PTRCALL *nameMatchesAscii)(const ENCODING *, - const char *, - const char *, - const char *); - int (PTRFASTCALL *nameLength)(const ENCODING *, const char *); - const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); - int (PTRCALL *getAtts)(const ENCODING *enc, - const char *ptr, - int attsMax, - ATTRIBUTE *atts); - int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); - int (PTRCALL *predefinedEntityName)(const ENCODING *, - const char *, - const char *); - void (PTRCALL *updatePosition)(const ENCODING *, - const char *ptr, - const char *end, - POSITION *); - int (PTRCALL *isPublicId)(const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr); - void (PTRCALL *utf8Convert)(const ENCODING *enc, - const char **fromP, - const char *fromLim, - char **toP, - const char *toLim); - void (PTRCALL *utf16Convert)(const ENCODING *enc, - const char **fromP, - const char *fromLim, - unsigned short **toP, - const unsigned short *toLim); - int minBytesPerChar; - char isUtf8; - char isUtf16; -}; - -/* Scan the string starting at ptr until the end of the next complete - token, but do not scan past eptr. Return an integer giving the - type of token. - - Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. - - Return XML_TOK_PARTIAL when the string does not contain a complete - token; nextTokPtr will not be set. - - Return XML_TOK_INVALID when the string does not start a valid - token; nextTokPtr will be set to point to the character which made - the token invalid. - - Otherwise the string starts with a valid token; nextTokPtr will be - set to point to the character following the end of that token. - - Each data character counts as a single token, but adjacent data - characters may be returned together. Similarly for characters in - the prolog outside literals, comments and processing instructions. -*/ - - -#define XmlTok(enc, state, ptr, end, nextTokPtr) \ - (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) - -#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) - -#define XmlContentTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) - -#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) - -#ifdef XML_DTD - -#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) - -#endif /* XML_DTD */ - -/* This is used for performing a 2nd-level tokenization on the content - of a literal that has already been returned by XmlTok. -*/ -#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ - (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) - -#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ - XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) - -#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ - XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) - -#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) - -#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ - (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) - -#define XmlNameLength(enc, ptr) \ - (((enc)->nameLength)(enc, ptr)) - -#define XmlSkipS(enc, ptr) \ - (((enc)->skipS)(enc, ptr)) - -#define XmlGetAttributes(enc, ptr, attsMax, atts) \ - (((enc)->getAtts)(enc, ptr, attsMax, atts)) - -#define XmlCharRefNumber(enc, ptr) \ - (((enc)->charRefNumber)(enc, ptr)) - -#define XmlPredefinedEntityName(enc, ptr, end) \ - (((enc)->predefinedEntityName)(enc, ptr, end)) - -#define XmlUpdatePosition(enc, ptr, end, pos) \ - (((enc)->updatePosition)(enc, ptr, end, pos)) - -#define XmlIsPublicId(enc, ptr, end, badPtr) \ - (((enc)->isPublicId)(enc, ptr, end, badPtr)) - -#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ - (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) - -#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ - (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) - -typedef struct { - ENCODING initEnc; - const ENCODING **encPtr; -} INIT_ENCODING; - -int XmlParseXmlDecl(int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingNamePtr, - const ENCODING **namedEncodingPtr, - int *standalonePtr); - -int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); -const ENCODING *XmlGetUtf8InternalEncoding(void); -const ENCODING *XmlGetUtf16InternalEncoding(void); -int FASTCALL XmlUtf8Encode(int charNumber, char *buf); -int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); -int XmlSizeOfUnknownEncoding(void); - - -typedef int (XMLCALL *CONVERTER) (void *userData, const char *p); - -ENCODING * -XmlInitUnknownEncoding(void *mem, - int *table, - CONVERTER convert, - void *userData); - -int XmlParseXmlDeclNS(int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingNamePtr, - const ENCODING **namedEncodingPtr, - int *standalonePtr); - -int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); -const ENCODING *XmlGetUtf8InternalEncodingNS(void); -const ENCODING *XmlGetUtf16InternalEncodingNS(void); -ENCODING * -XmlInitUnknownEncodingNS(void *mem, - int *table, - CONVERTER convert, - void *userData); -#ifdef __cplusplus -} -#endif - -#endif /* not XmlTok_INCLUDED */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_impl.c b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_impl.c deleted file mode 100644 index 8154c1a..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_impl.c +++ /dev/null @@ -1,1786 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -/* This file is included! */ -#ifdef XML_TOK_IMPL_C - -#ifndef IS_INVALID_CHAR -#define IS_INVALID_CHAR(enc, ptr, n) (0) -#endif - -#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_INVALID_CHAR(enc, ptr, n)) { \ - *(nextTokPtr) = (ptr); \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define INVALID_CASES(ptr, nextTokPtr) \ - INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ - case BT_NONXML: \ - case BT_MALFORM: \ - case BT_TRAIL: \ - *(nextTokPtr) = (ptr); \ - return XML_TOK_INVALID; - -#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NAME_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - case BT_NMSTRT: \ - case BT_HEX: \ - case BT_DIGIT: \ - case BT_NAME: \ - case BT_MINUS: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) - -#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - case BT_NMSTRT: \ - case BT_HEX: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) - -#ifndef PREFIX -#define PREFIX(ident) ident -#endif - -/* ptr points to character following "<!-" */ - -static int PTRCALL -PREFIX(scanComment)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - if (ptr != end) { - if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - ptr += MINBPC(enc); - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr) - case BT_MINUS: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COMMENT; - } - break; - default: - ptr += MINBPC(enc); - break; - } - } - } - return XML_TOK_PARTIAL; -} - -/* ptr points to character following "<!" */ - -static int PTRCALL -PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_MINUS: - return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_LSQB: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COND_SECT_OPEN; - case BT_NMSTRT: - case BT_HEX: - ptr += MINBPC(enc); - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_PERCNT: - if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; - /* don't allow <!ENTITY% foo "whatever"> */ - switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { - case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - /* fall through */ - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return XML_TOK_DECL_OPEN; - case BT_NMSTRT: - case BT_HEX: - ptr += MINBPC(enc); - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, - const char *end, int *tokPtr) -{ - int upper = 0; - *tokPtr = XML_TOK_PI; - if (end - ptr != MINBPC(enc)*3) - return 1; - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_x: - break; - case ASCII_X: - upper = 1; - break; - default: - return 1; - } - ptr += MINBPC(enc); - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_m: - break; - case ASCII_M: - upper = 1; - break; - default: - return 1; - } - ptr += MINBPC(enc); - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_l: - break; - case ASCII_L: - upper = 1; - break; - default: - return 1; - } - if (upper) - return 0; - *tokPtr = XML_TOK_XML_DECL; - return 1; -} - -/* ptr points to character following "<?" */ - -static int PTRCALL -PREFIX(scanPi)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - int tok; - const char *target = ptr; - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_CR: case BT_LF: - if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - ptr += MINBPC(enc); - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr) - case BT_QUEST: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; - } - break; - default: - ptr += MINBPC(enc); - break; - } - } - return XML_TOK_PARTIAL; - case BT_QUEST: - if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; - } - /* fall through */ - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, - ASCII_T, ASCII_A, ASCII_LSQB }; - int i; - /* CDATA[ */ - if (end - ptr < 6 * MINBPC(enc)) - return XML_TOK_PARTIAL; - for (i = 0; i < 6; i++, ptr += MINBPC(enc)) { - if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - *nextTokPtr = ptr; - return XML_TOK_CDATA_SECT_OPEN; -} - -static int PTRCALL -PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_NONE; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_RSQB: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) - break; - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr -= MINBPC(enc); - break; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CDATA_SECT_CLOSE; - case BT_CR: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - case BT_LF: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - INVALID_CASES(ptr, nextTokPtr) - default: - ptr += MINBPC(enc); - break; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONXML: - case BT_MALFORM: - case BT_TRAIL: - case BT_CR: - case BT_LF: - case BT_RSQB: - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -/* ptr points to character following "</" */ - -static int PTRCALL -PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_CR: case BT_LF: - for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - break; - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_END_TAG; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -#ifdef XML_NS - case BT_COLON: - /* no need to check qname syntax here, - since end-tag must match exactly */ - ptr += MINBPC(enc); - break; -#endif - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_END_TAG; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -/* ptr points to character following "&#X" */ - -static int PTRCALL -PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - if (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_DIGIT: - case BT_HEX: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_DIGIT: - case BT_HEX: - break; - case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - } - return XML_TOK_PARTIAL; -} - -/* ptr points to character following "&#" */ - -static int PTRCALL -PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - if (ptr != end) { - if (CHAR_MATCHES(enc, ptr, ASCII_x)) - return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - switch (BYTE_TYPE(enc, ptr)) { - case BT_DIGIT: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_DIGIT: - break; - case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - } - return XML_TOK_PARTIAL; -} - -/* ptr points to character following "&" */ - -static int PTRCALL -PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_NUM: - return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_ENTITY_REF; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -/* ptr points to character following first character of attribute name */ - -static int PTRCALL -PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ -#ifdef XML_NS - int hadColon = 0; -#endif - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) -#ifdef XML_NS - case BT_COLON: - if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - hadColon = 1; - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - break; -#endif - case BT_S: case BT_CR: case BT_LF: - for (;;) { - int t; - - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == BT_EQUALS) - break; - switch (t) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - /* fall through */ - case BT_EQUALS: - { - int open; -#ifdef XML_NS - hadColon = 0; -#endif - for (;;) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - open = BYTE_TYPE(enc, ptr); - if (open == BT_QUOT || open == BT_APOS) - break; - switch (open) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - ptr += MINBPC(enc); - /* in attribute value */ - for (;;) { - int t; - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == open) - break; - switch (t) { - INVALID_CASES(ptr, nextTokPtr) - case BT_AMP: - { - int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); - if (tok <= 0) { - if (tok == XML_TOK_INVALID) - *nextTokPtr = ptr; - return tok; - } - break; - } - case BT_LT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - default: - ptr += MINBPC(enc); - break; - } - } - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: - case BT_CR: - case BT_LF: - break; - case BT_SOL: - goto sol; - case BT_GT: - goto gt; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - /* ptr points to closing quote */ - for (;;) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_CR: case BT_LF: - continue; - case BT_GT: - gt: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_START_TAG_WITH_ATTS; - case BT_SOL: - sol: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - break; - } - break; - } - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -/* ptr points to character following "<" */ - -static int PTRCALL -PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ -#ifdef XML_NS - int hadColon; -#endif - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_EXCL: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_MINUS: - return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_LSQB: - return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), - end, nextTokPtr); - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_SOL: - return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr); - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } -#ifdef XML_NS - hadColon = 0; -#endif - /* we have a start-tag */ - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) -#ifdef XML_NS - case BT_COLON: - if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - hadColon = 1; - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - break; -#endif - case BT_S: case BT_CR: case BT_LF: - { - ptr += MINBPC(enc); - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: - goto gt; - case BT_SOL: - goto sol; - case BT_S: case BT_CR: case BT_LF: - ptr += MINBPC(enc); - continue; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); - } - return XML_TOK_PARTIAL; - } - case BT_GT: - gt: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_START_TAG_NO_ATTS; - case BT_SOL: - sol: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_EMPTY_ELEMENT_NO_ATTS; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_NONE; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_LT: - return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_AMP: - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_CR: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - case BT_LF: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - case BT_RSQB: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) - break; - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr -= MINBPC(enc); - break; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - INVALID_CASES(ptr, nextTokPtr) - default: - ptr += MINBPC(enc); - break; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_RSQB: - if (ptr + MINBPC(enc) != end) { - if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { - ptr += MINBPC(enc); - break; - } - if (ptr + 2*MINBPC(enc) != end) { - if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { - ptr += MINBPC(enc); - break; - } - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_INVALID; - } - } - /* fall through */ - case BT_AMP: - case BT_LT: - case BT_NONXML: - case BT_MALFORM: - case BT_TRAIL: - case BT_CR: - case BT_LF: - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -/* ptr points to character following "%" */ - -static int PTRCALL -PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - if (ptr == end) - return -XML_TOK_PERCENT; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_PERCENT; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_PARAM_ENTITY_REF; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_CR: case BT_LF: case BT_S: - case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: - *nextTokPtr = ptr; - return XML_TOK_POUND_NAME; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return -XML_TOK_POUND_NAME; -} - -static int PTRCALL -PREFIX(scanLit)(int open, const ENCODING *enc, - const char *ptr, const char *end, - const char **nextTokPtr) -{ - while (ptr != end) { - int t = BYTE_TYPE(enc, ptr); - switch (t) { - INVALID_CASES(ptr, nextTokPtr) - case BT_QUOT: - case BT_APOS: - ptr += MINBPC(enc); - if (t != open) - break; - if (ptr == end) - return -XML_TOK_LITERAL; - *nextTokPtr = ptr; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - case BT_GT: case BT_PERCNT: case BT_LSQB: - return XML_TOK_LITERAL; - default: - return XML_TOK_INVALID; - } - default: - ptr += MINBPC(enc); - break; - } - } - return XML_TOK_PARTIAL; -} - -static int PTRCALL -PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - int tok; - if (ptr == end) - return XML_TOK_NONE; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_QUOT: - return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_APOS: - return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_LT: - { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_EXCL: - return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_NMSTRT: - case BT_HEX: - case BT_NONASCII: - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - *nextTokPtr = ptr - MINBPC(enc); - return XML_TOK_INSTANCE_START; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - case BT_CR: - if (ptr + MINBPC(enc) == end) { - *nextTokPtr = end; - /* indicate that this might be part of a CR/LF pair */ - return -XML_TOK_PROLOG_S; - } - /* fall through */ - case BT_S: case BT_LF: - for (;;) { - ptr += MINBPC(enc); - if (ptr == end) - break; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_LF: - break; - case BT_CR: - /* don't split CR/LF pair */ - if (ptr + MINBPC(enc) != end) - break; - /* fall through */ - default: - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; - } - } - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; - case BT_PERCNT: - return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_COMMA: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COMMA; - case BT_LSQB: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OPEN_BRACKET; - case BT_RSQB: - ptr += MINBPC(enc); - if (ptr == end) - return -XML_TOK_CLOSE_BRACKET; - if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_COND_SECT_CLOSE; - } - } - *nextTokPtr = ptr; - return XML_TOK_CLOSE_BRACKET; - case BT_LPAR: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OPEN_PAREN; - case BT_RPAR: - ptr += MINBPC(enc); - if (ptr == end) - return -XML_TOK_CLOSE_PAREN; - switch (BYTE_TYPE(enc, ptr)) { - case BT_AST: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_ASTERISK; - case BT_QUEST: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_QUESTION; - case BT_PLUS: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_PLUS; - case BT_CR: case BT_LF: case BT_S: - case BT_GT: case BT_COMMA: case BT_VERBAR: - case BT_RPAR: - *nextTokPtr = ptr; - return XML_TOK_CLOSE_PAREN; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - case BT_VERBAR: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OR; - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DECL_CLOSE; - case BT_NUM: - return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NAME; \ - break; \ - } \ - if (IS_NAME_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NMTOKEN; \ - break; \ - } \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NMSTRT: - case BT_HEX: - tok = XML_TOK_NAME; - ptr += MINBPC(enc); - break; - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: -#ifdef XML_NS - case BT_COLON: -#endif - tok = XML_TOK_NMTOKEN; - ptr += MINBPC(enc); - break; - case BT_NONASCII: - if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NAME; - break; - } - if (IS_NAME_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NMTOKEN; - break; - } - /* fall through */ - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: case BT_RPAR: case BT_COMMA: - case BT_VERBAR: case BT_LSQB: case BT_PERCNT: - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return tok; -#ifdef XML_NS - case BT_COLON: - ptr += MINBPC(enc); - switch (tok) { - case XML_TOK_NAME: - if (ptr == end) - return XML_TOK_PARTIAL; - tok = XML_TOK_PREFIXED_NAME; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - default: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case XML_TOK_PREFIXED_NAME: - tok = XML_TOK_NMTOKEN; - break; - } - break; -#endif - case BT_PLUS: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_PLUS; - case BT_AST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_ASTERISK; - case BT_QUEST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_QUESTION; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return -tok; -} - -static int PTRCALL -PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - const char *start; - if (ptr == end) - return XML_TOK_NONE; - start = ptr; - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_AMP: - if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_LT: - /* this is for inside entity references */ - *nextTokPtr = ptr; - return XML_TOK_INVALID; - case BT_LF: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_CR: - if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_S: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_ATTRIBUTE_VALUE_S; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -static int PTRCALL -PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - const char *start; - if (ptr == end) - return XML_TOK_NONE; - start = ptr; - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_AMP: - if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_PERCNT: - if (ptr == start) { - int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), - end, nextTokPtr); - return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_LF: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_CR: - if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -#ifdef XML_DTD - -static int PTRCALL -PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, - const char *end, const char **nextTokPtr) -{ - int level = 0; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - end = ptr + n; - } - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr) - case BT_LT: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { - ++level; - ptr += MINBPC(enc); - } - } - break; - case BT_RSQB: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr += MINBPC(enc); - if (level == 0) { - *nextTokPtr = ptr; - return XML_TOK_IGNORE_SECT; - } - --level; - } - } - break; - default: - ptr += MINBPC(enc); - break; - } - } - return XML_TOK_PARTIAL; -} - -#endif /* XML_DTD */ - -static int PTRCALL -PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr) -{ - ptr += MINBPC(enc); - end -= MINBPC(enc); - for (; ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_DIGIT: - case BT_HEX: - case BT_MINUS: - case BT_APOS: - case BT_LPAR: - case BT_RPAR: - case BT_PLUS: - case BT_COMMA: - case BT_SOL: - case BT_EQUALS: - case BT_QUEST: - case BT_CR: - case BT_LF: - case BT_SEMI: - case BT_EXCL: - case BT_AST: - case BT_PERCNT: - case BT_NUM: -#ifdef XML_NS - case BT_COLON: -#endif - break; - case BT_S: - if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { - *badPtr = ptr; - return 0; - } - break; - case BT_NAME: - case BT_NMSTRT: - if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) - break; - default: - switch (BYTE_TO_ASCII(enc, ptr)) { - case 0x24: /* $ */ - case 0x40: /* @ */ - break; - default: - *badPtr = ptr; - return 0; - } - break; - } - } - return 1; -} - -/* This must only be called for a well-formed start-tag or empty - element tag. Returns the number of attributes. Pointers to the - first attsMax attributes are stored in atts. -*/ - -static int PTRCALL -PREFIX(getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts) -{ - enum { other, inName, inValue } state = inName; - int nAtts = 0; - int open = 0; /* defined when state == inValue; - initialization just to shut up compilers */ - - for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { -#define START_NAME \ - if (state == other) { \ - if (nAtts < attsMax) { \ - atts[nAtts].name = ptr; \ - atts[nAtts].normalized = 1; \ - } \ - state = inName; \ - } -#define LEAD_CASE(n) \ - case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONASCII: - case BT_NMSTRT: - case BT_HEX: - START_NAME - break; -#undef START_NAME - case BT_QUOT: - if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); - state = inValue; - open = BT_QUOT; - } - else if (open == BT_QUOT) { - state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; - } - break; - case BT_APOS: - if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); - state = inValue; - open = BT_APOS; - } - else if (open == BT_APOS) { - state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; - } - break; - case BT_AMP: - if (nAtts < attsMax) - atts[nAtts].normalized = 0; - break; - case BT_S: - if (state == inName) - state = other; - else if (state == inValue - && nAtts < attsMax - && atts[nAtts].normalized - && (ptr == atts[nAtts].valuePtr - || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE - || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE - || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) - atts[nAtts].normalized = 0; - break; - case BT_CR: case BT_LF: - /* This case ensures that the first attribute name is counted - Apart from that we could just change state on the quote. */ - if (state == inName) - state = other; - else if (state == inValue && nAtts < attsMax) - atts[nAtts].normalized = 0; - break; - case BT_GT: - case BT_SOL: - if (state != inValue) - return nAtts; - break; - default: - break; - } - } - /* not reached */ -} - -static int PTRFASTCALL -PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) -{ - int result = 0; - /* skip &# */ - ptr += 2*MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_x)) { - for (ptr += MINBPC(enc); - !CHAR_MATCHES(enc, ptr, ASCII_SEMI); - ptr += MINBPC(enc)) { - int c = BYTE_TO_ASCII(enc, ptr); - switch (c) { - case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: - case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: - result <<= 4; - result |= (c - ASCII_0); - break; - case ASCII_A: case ASCII_B: case ASCII_C: - case ASCII_D: case ASCII_E: case ASCII_F: - result <<= 4; - result += 10 + (c - ASCII_A); - break; - case ASCII_a: case ASCII_b: case ASCII_c: - case ASCII_d: case ASCII_e: case ASCII_f: - result <<= 4; - result += 10 + (c - ASCII_a); - break; - } - if (result >= 0x110000) - return -1; - } - } - else { - for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { - int c = BYTE_TO_ASCII(enc, ptr); - result *= 10; - result += (c - ASCII_0); - if (result >= 0x110000) - return -1; - } - } - return checkCharRefNumber(result); -} - -static int PTRCALL -PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, - const char *end) -{ - switch ((end - ptr)/MINBPC(enc)) { - case 2: - if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_l: - return ASCII_LT; - case ASCII_g: - return ASCII_GT; - } - } - break; - case 3: - if (CHAR_MATCHES(enc, ptr, ASCII_a)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_m)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) - return ASCII_AMP; - } - } - break; - case 4: - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_q: - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_u)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_t)) - return ASCII_QUOT; - } - } - break; - case ASCII_a: - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_s)) - return ASCII_APOS; - } - } - break; - } - } - return 0; -} - -static int PTRCALL -PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) -{ - for (;;) { - switch (BYTE_TYPE(enc, ptr1)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (*ptr1++ != *ptr2++) \ - return 0; - LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) -#undef LEAD_CASE - /* fall through */ - if (*ptr1++ != *ptr2++) - return 0; - break; - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 1) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 2) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 3) { - if (*ptr2++ != *ptr1++) - return 0; - } - } - } - break; - default: - if (MINBPC(enc) == 1 && *ptr1 == *ptr2) - return 1; - switch (BYTE_TYPE(enc, ptr2)) { - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - return 0; - default: - return 1; - } - } - } - /* not reached */ -} - -static int PTRCALL -PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, - const char *end1, const char *ptr2) -{ - for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { - if (ptr1 == end1) - return 0; - if (!CHAR_MATCHES(enc, ptr1, *ptr2)) - return 0; - } - return ptr1 == end1; -} - -static int PTRFASTCALL -PREFIX(nameLength)(const ENCODING *enc, const char *ptr) -{ - const char *start = ptr; - for (;;) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONASCII: - case BT_NMSTRT: -#ifdef XML_NS - case BT_COLON: -#endif - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - ptr += MINBPC(enc); - break; - default: - return (int)(ptr - start); - } - } -} - -static const char * PTRFASTCALL -PREFIX(skipS)(const ENCODING *enc, const char *ptr) -{ - for (;;) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_LF: - case BT_CR: - case BT_S: - ptr += MINBPC(enc); - break; - default: - return ptr; - } - } -} - -static void PTRCALL -PREFIX(updatePosition)(const ENCODING *enc, - const char *ptr, - const char *end, - POSITION *pos) -{ - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) { \ - return; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_LF: - pos->columnNumber = (XML_Size)-1; - pos->lineNumber++; - ptr += MINBPC(enc); - break; - case BT_CR: - pos->lineNumber++; - ptr += MINBPC(enc); - if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - pos->columnNumber = (XML_Size)-1; - break; - default: - ptr += MINBPC(enc); - break; - } - pos->columnNumber++; - } -} - -#undef DO_LEAD_CASE -#undef MULTIBYTE_CASES -#undef INVALID_CASES -#undef CHECK_NAME_CASE -#undef CHECK_NAME_CASES -#undef CHECK_NMSTRT_CASE -#undef CHECK_NMSTRT_CASES - -#endif /* XML_TOK_IMPL_C */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_impl.h b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_impl.h deleted file mode 100644 index da0ea60..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_impl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file COPYING for copying permission. -*/ - -enum { - BT_NONXML, - BT_MALFORM, - BT_LT, - BT_AMP, - BT_RSQB, - BT_LEAD2, - BT_LEAD3, - BT_LEAD4, - BT_TRAIL, - BT_CR, - BT_LF, - BT_GT, - BT_QUOT, - BT_APOS, - BT_EQUALS, - BT_QUEST, - BT_EXCL, - BT_SOL, - BT_SEMI, - BT_NUM, - BT_LSQB, - BT_S, - BT_NMSTRT, - BT_COLON, - BT_HEX, - BT_DIGIT, - BT_NAME, - BT_MINUS, - BT_OTHER, /* known not to be a name or name start character */ - BT_NONASCII, /* might be a name or name start character */ - BT_PERCNT, - BT_LPAR, - BT_RPAR, - BT_AST, - BT_PLUS, - BT_COMMA, - BT_VERBAR -}; - -#include <stddef.h> diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_ns.c b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_ns.c deleted file mode 100644 index c3b88fd..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/Source/lib/xmltok_ns.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd - See the file COPYING for copying permission. -*/ - -/* This file is included! */ -#ifdef XML_TOK_NS_C - -const ENCODING * -NS(XmlGetUtf8InternalEncoding)(void) -{ - return &ns(internal_utf8_encoding).enc; -} - -const ENCODING * -NS(XmlGetUtf16InternalEncoding)(void) -{ -#if BYTEORDER == 1234 - return &ns(internal_little2_encoding).enc; -#elif BYTEORDER == 4321 - return &ns(internal_big2_encoding).enc; -#else - const short n = 1; - return (*(const char *)&n - ? &ns(internal_little2_encoding).enc - : &ns(internal_big2_encoding).enc); -#endif -} - -static const ENCODING * const NS(encodings)[] = { - &ns(latin1_encoding).enc, - &ns(ascii_encoding).enc, - &ns(utf8_encoding).enc, - &ns(big2_encoding).enc, - &ns(big2_encoding).enc, - &ns(little2_encoding).enc, - &ns(utf8_encoding).enc /* NO_ENC */ -}; - -static int PTRCALL -NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, - XML_PROLOG_STATE, ptr, end, nextTokPtr); -} - -static int PTRCALL -NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, - XML_CONTENT_STATE, ptr, end, nextTokPtr); -} - -int -NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, - const char *name) -{ - int i = getEncodingIndex(name); - if (i == UNKNOWN_ENC) - return 0; - SET_INIT_ENC_INDEX(p, i); - p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); - p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); - p->initEnc.updatePosition = initUpdatePosition; - p->encPtr = encPtr; - *encPtr = &(p->initEnc); - return 1; -} - -static const ENCODING * -NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) -{ -#define ENCODING_MAX 128 - char buf[ENCODING_MAX]; - char *p = buf; - int i; - XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); - if (ptr != end) - return 0; - *p = 0; - if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) - return enc; - i = getEncodingIndex(buf); - if (i == UNKNOWN_ENC) - return 0; - return NS(encodings)[i]; -} - -int -NS(XmlParseXmlDecl)(int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **versionEndPtr, - const char **encodingName, - const ENCODING **encoding, - int *standalone) -{ - return doParseXmlDecl(NS(findEncoding), - isGeneralTextEntity, - enc, - ptr, - end, - badPtr, - versionPtr, - versionEndPtr, - encodingName, - encoding, - standalone); -} - -#endif /* XML_TOK_NS_C */ diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/expat.scons b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/expat.scons deleted file mode 100644 index 620ba32..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/expat.scons +++ /dev/null @@ -1,24 +0,0 @@ -# SConscript - expat -# Copyright 2009 Google Inc. All Rights Reserved. -# Author: vitalybuka@google.com (Vitaly Buka) - -Import('env') - -expat_env = env.Clone() -expat_env.Append( - CPPDEFINES = [ - "_LIB", - "XML_LARGE_SIZE", - "XML_STATIC", - "COMPILED_FROM_DSP", - ], -) - -expat_env.ComponentLibrary( - 'expat.lib', - source = [ - 'Source/lib/xmlparse.c', - 'Source/lib/xmlrole.c', - 'Source/lib/xmltok.c', - ], -) diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/mk_file b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/mk_file deleted file mode 100644 index b09e3ce..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/mk_file +++ /dev/null @@ -1,16 +0,0 @@ -t = NewTarget() -t.OUTPUTS = ["expat.lib"] -t.INPUTS = ["./Source/lib/xmlparse.c", - "./Source/lib/xmlrole.c", - "./Source/lib/xmltok.c", - ] -t.INC_DIRS += ["."] -t.C_DEFINES += ["_LIB", - "XML_STATIC", - "COMPILED_FROM_DSP", - ] - -# No precompiled headers. -t.PRECOMPILE_STOPFILE = "" -t.PRECOMPILE_BUILDER = "" -DoBuild(t) diff --git a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/setup_env.bat b/third_party/libjingle/source/talk/third_party/expat/v2_0_1/setup_env.bat deleted file mode 100755 index 3fc0798..0000000 --- a/third_party/libjingle/source/talk/third_party/expat/v2_0_1/setup_env.bat +++ /dev/null @@ -1,8 +0,0 @@ -:: This script must not rely on any external tools or PATH values. -@echo OFF - -:: Let advanced users checkout the tools in just one P4 enlistment. -if "%SETUP_ENV_EXPAT%"=="done" goto :EOF -set SETUP_ENV_EXPAT=done - -set INCLUDE=%INCLUDE%;%~dp0Source\lib diff --git a/third_party/libjingle/source/talk/xmpp/constants.cc b/third_party/libjingle/source/talk/xmpp/constants.cc index ce4ed4f..aa581f4 100644 --- a/third_party/libjingle/source/talk/xmpp/constants.cc +++ b/third_party/libjingle/source/talk/xmpp/constants.cc @@ -462,20 +462,6 @@ const QName QN_GOOGLE_MUC_USER_MEDIA(true, NS_GOOGLE_MUC_USER, "media"); const QName QN_GOOGLE_MUC_USER_TYPE(true, NS_GOOGLE_MUC_USER, "type"); const QName QN_GOOGLE_MUC_USER_SRC_ID(true, NS_GOOGLE_MUC_USER, "src-id"); const QName QN_GOOGLE_MUC_USER_STATUS(true, NS_GOOGLE_MUC_USER, "status"); -const std::string NS_JINGLE("google:jingle"); -const QName QN_JINGLE_SRC_ID(true, NS_JINGLE, "src-id"); const QName QN_LABEL(true, STR_EMPTY, "label"); -// Call terminate reasons -const std::string STR_TERMINATE_CALL_ENDED("call-ended"); -const std::string STR_TERMINATE_RECIPIENT_UNAVAILABLE("recipient-unavailable"); -const std::string STR_TERMINATE_RECIPIENT_BUSY("recipient-busy"); -const std::string STR_TERMINATE_INSUFFICIENT_FUNDS("insufficient-funds"); -const std::string STR_TERMINATE_NUMBER_MALFORMED("number-malformed"); -const std::string STR_TERMINATE_NUMBER_DISALLOWED("number-disallowed"); -const std::string STR_TERMINATE_PROTOCOL_ERROR("protocol-error"); -const std::string STR_TERMINATE_INTERNAL_SERVER_ERROR("internal-server-error"); -const std::string STR_TERMINATE_UNKNOWN_ERROR("unknown-error"); - - } diff --git a/third_party/libjingle/source/talk/xmpp/constants.h b/third_party/libjingle/source/talk/xmpp/constants.h index f07dde0..1a626b4 100644 --- a/third_party/libjingle/source/talk/xmpp/constants.h +++ b/third_party/libjingle/source/talk/xmpp/constants.h @@ -429,21 +429,8 @@ extern const QName QN_GOOGLE_MUC_USER_MEDIA; extern const QName QN_GOOGLE_MUC_USER_TYPE; extern const QName QN_GOOGLE_MUC_USER_SRC_ID; extern const QName QN_GOOGLE_MUC_USER_STATUS; -extern const std::string NS_JINGLE; -extern const QName QN_JINGLE_SRC_ID; extern const QName QN_LABEL; -// Call terminate reasons -extern const std::string STR_TERMINATE_CALL_ENDED; -extern const std::string STR_TERMINATE_RECIPIENT_UNAVAILABLE; -extern const std::string STR_TERMINATE_RECIPIENT_BUSY; -extern const std::string STR_TERMINATE_INSUFFICIENT_FUNDS; -extern const std::string STR_TERMINATE_NUMBER_MALFORMED; -extern const std::string STR_TERMINATE_NUMBER_DISALLOWED; -extern const std::string STR_TERMINATE_PROTOCOL_ERROR; -extern const std::string STR_TERMINATE_INTERNAL_SERVER_ERROR; -extern const std::string STR_TERMINATE_UNKNOWN_ERROR; - } // namespace buzz #endif // TALK_XMPP_CONSTANTS_H_ diff --git a/third_party/libjingle/source/talk/xmpp/xmppengineimpl.cc b/third_party/libjingle/source/talk/xmpp/xmppengineimpl.cc index 9918050..262c531 100644 --- a/third_party/libjingle/source/talk/xmpp/xmppengineimpl.cc +++ b/third_party/libjingle/source/talk/xmpp/xmppengineimpl.cc @@ -110,7 +110,7 @@ XmppEngineImpl::HandleInput(const char * bytes, size_t len) { EnterExit ee(this); - // TODO(jliaw): The return value of the xml parser is not checked. + // TODO: The return value of the xml parser is not checked. stanzaParser_.Parse(bytes, len, false); return XMPP_RETURN_OK; |