Author: borisk
Date: Wed Jul 9 09:01:01 2008
New Revision: 675241
URL: http://svn.apache.org/viewvc?rev=675241&view=rev
Log:
Use the ISO8859-1 encoding in net accessors. Add support for httpInfo in the
curl net accessor. Patch by John Snelson (XERCESC-1805).
Modified:
xerces/c/trunk/src/xercesc/util/NetAccessors/BinHTTPInputStreamCommon.cpp
xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.cpp
xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.hpp
xerces/c/trunk/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp
xerces/c/trunk/src/xercesc/util/TransService.cpp
xerces/c/trunk/src/xercesc/util/TransService.hpp
Modified:
xerces/c/trunk/src/xercesc/util/NetAccessors/BinHTTPInputStreamCommon.cpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/util/NetAccessors/BinHTTPInputStreamCommon.cpp?rev=675241&r1=675240&r2=675241&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/NetAccessors/BinHTTPInputStreamCommon.cpp
(original)
+++ xerces/c/trunk/src/xercesc/util/NetAccessors/BinHTTPInputStreamCommon.cpp
Wed Jul 9 09:01:01 2008
@@ -42,64 +42,6 @@
XERCES_CPP_NAMESPACE_BEGIN
-class TranscodeStr
-{
-public:
- TranscodeStr(const XMLCh *in, XMLTranscoder* trans,
- MemoryManager *manager = XMLPlatformUtils::fgMemoryManager)
- : fString(0),
- fBytesWritten(0),
- fMemoryManager(manager)
- {
- if(in) {
- XMLSize_t len = XMLString::stringLen(in) + 1;
-
- XMLSize_t allocSize = len * sizeof(XMLCh);
- fString = (unsigned char*)fMemoryManager->allocate(allocSize);
-
- XMLSize_t charsRead;
-
- XMLSize_t charsDone = 0;
-
- while(true) {
- fBytesWritten += trans->transcodeTo(in + charsDone, len -
charsDone,
- fString + fBytesWritten,
allocSize - fBytesWritten,
- charsRead,
XMLTranscoder::UnRep_Throw);
- charsDone += charsRead;
-
- if(charsDone == len) break;
-
- allocSize *= 2;
- unsigned char *newBuf = (unsigned
char*)fMemoryManager->allocate(allocSize);
- memcpy(newBuf, fString, fBytesWritten);
- fMemoryManager->deallocate(fString);
- fString = newBuf;
- }
- }
- }
-
- ~TranscodeStr()
- {
- if(fString)
- fMemoryManager->deallocate(fString);
- }
-
- const unsigned char *str() const
- {
- return fString;
- }
-
- XMLSize_t len() const
- {
- return fBytesWritten;
- }
-
-private:
- unsigned char *fString;
- XMLSize_t fBytesWritten;
- MemoryManager *fMemoryManager;
-};
-
BinHTTPInputStreamCommon::BinHTTPInputStreamCommon(MemoryManager *manager)
: fBytesProcessed(0)
, fBuffer(1023, manager)
@@ -132,10 +74,10 @@
XMLTranscoder* trans =
XMLPlatformUtils::fgTransService->makeNewTranscoderFor("ISO8859-1", failReason,
blockSize, fMemoryManager);
Janitor<XMLTranscoder> janTrans(trans);
- TranscodeStr hostName(urlSource.getHost(), trans, fMemoryManager);
- TranscodeStr path(urlSource.getPath(), trans, fMemoryManager);
- TranscodeStr fragment(urlSource.getFragment(), trans, fMemoryManager);
- TranscodeStr query(urlSource.getQuery(), trans, fMemoryManager);
+ TranscodeToStr hostName(urlSource.getHost(), trans, fMemoryManager);
+ TranscodeToStr path(urlSource.getPath(), trans, fMemoryManager);
+ TranscodeToStr fragment(urlSource.getFragment(), trans, fMemoryManager);
+ TranscodeToStr query(urlSource.getQuery(), trans, fMemoryManager);
// Build up the http GET command to send to the server.
// To do: We should really support http 1.1. This implementation
@@ -185,10 +127,10 @@
userPassBuf.append(chColon);
userPassBuf.append(password);
- TranscodeStr userPass(userPassBuf.getRawBuffer(), trans,
fMemoryManager);
+ TranscodeToStr userPass(userPassBuf.getRawBuffer(), trans,
fMemoryManager);
XMLSize_t len;
- XMLByte* encodedData = Base64::encode((XMLByte*)userPass.str(),
userPass.len() - 1, &len, fMemoryManager);
+ XMLByte* encodedData = Base64::encode(userPass.str(),
userPass.length(), &len, fMemoryManager);
ArrayJanitor<XMLByte> janBuf2(encodedData, fMemoryManager);
if(encodedData) {
@@ -229,12 +171,9 @@
for(endP = p; *endP != 0; ++endP);
}
- char tmp = *endP;
- *endP = 0;
-
- XMLCh *value = XMLString::transcode(p, fMemoryManager);
- *endP = tmp;
- return value;
+ // Transcode from iso-8859-1
+ TranscodeFromStr value((XMLByte*)p, endP - p, "ISO8859-1",
fMemoryManager);
+ return value.adopt();
}
p = strstr(p + 1, name);
Modified:
xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.cpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.cpp?rev=675241&r1=675240&r2=675241&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.cpp
(original)
+++ xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.cpp
Wed Jul 9 09:01:01 2008
@@ -46,7 +46,6 @@
, fEasy(0)
, fMemoryManager(urlSource.getMemoryManager())
, fURLSource(urlSource)
- , fURL(0)
, fTotalBytesRead(0)
, fWritePtr(0)
, fBytesRead(0)
@@ -54,6 +53,8 @@
, fDataAvailable(false)
, fBufferHeadPtr(fBuffer)
, fBufferTailPtr(fBuffer)
+ , fPayload(0)
+ , fPayloadLen(0)
, fContentType(0)
{
// Allocate the curl multi handle
@@ -62,20 +63,101 @@
// Allocate the curl easy handle
fEasy = curl_easy_init();
- // Get the text of the URL we're going to use
- fURL.reset(XMLString::transcode(fURLSource.getURLText(),
fMemoryManager), fMemoryManager);
-
- //printf("Curl trying to fetch %s\n", fURL.get());
-
// Set URL option
- curl_easy_setopt(fEasy, CURLOPT_URL, fURL.get());
+ TranscodeToStr url(fURLSource.getURLText(), "ISO8859-1", fMemoryManager);
+ curl_easy_setopt(fEasy, CURLOPT_URL, (char*)url.str());
+
+ // Set up a way to recieve the data
curl_easy_setopt(fEasy, CURLOPT_WRITEDATA, this);
// Pass this pointer to write function
curl_easy_setopt(fEasy, CURLOPT_WRITEFUNCTION, staticWriteCallback);
// Our static write function
- curl_easy_setopt(fEasy, CURLOPT_WRITEHEADER, this);
// Pass this pointer to header function
- curl_easy_setopt(fEasy, CURLOPT_HEADERFUNCTION, staticHeaderCallback);
// Our static header function
+ // Do redirects
+ curl_easy_setopt(fEasy, CURLOPT_FOLLOWLOCATION, (long)1);
+ curl_easy_setopt(fEasy, CURLOPT_MAXREDIRS, (long)6);
+
+ // Add username and password if authentication is required
+ const XMLCh *username = urlSource.getUser();
+ const XMLCh *password = urlSource.getPassword();
+ if(username && password) {
+ XMLBuffer userPassBuf(256, fMemoryManager);
+ userPassBuf.append(username);
+ userPassBuf.append(chColon);
+ userPassBuf.append(password);
+
+ TranscodeToStr userPass(userPassBuf.getRawBuffer(), "ISO8859-1",
fMemoryManager);
+
+ curl_easy_setopt(fEasy, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
+ curl_easy_setopt(fEasy, CURLOPT_USERPWD, (char*)userPass.str());
+ }
+
+ if(httpInfo) {
+ // Set the correct HTTP method
+ switch(httpInfo->fHTTPMethod) {
+ case XMLNetHTTPInfo::GET:
+ break;
+ case XMLNetHTTPInfo::PUT:
+ curl_easy_setopt(fEasy, CURLOPT_UPLOAD, (long)1);
+ break;
+ case XMLNetHTTPInfo::POST:
+ curl_easy_setopt(fEasy, CURLOPT_POST, (long)1);
+ break;
+ }
+
+ // Add custom headers
+ if(httpInfo->fHeaders) {
+ struct curl_slist *headersList = 0;
+
+ const char *headersBuf = httpInfo->fHeaders;
+ const char *headersBufEnd = httpInfo->fHeaders +
httpInfo->fHeadersLen;
+
+ const char *headerStart = headersBuf;
+ while(headersBuf < headersBufEnd) {
+ if(*headersBuf == '\r' && (headersBuf + 1) < headersBufEnd &&
+ *(headersBuf + 1) == '\n') {
+
+ XMLSize_t length = headersBuf - headerStart;
+ ArrayJanitor<char>
header((char*)fMemoryManager->allocate((length + 1) * sizeof(char)),
+ fMemoryManager);
+ memcpy(header.get(), headerStart, length);
+ header.get()[length] = 0;
+
+ headersList = curl_slist_append(headersList, header.get());
+
+ headersBuf += 2;
+ headerStart = headersBuf;
+ continue;
+ }
+ ++headersBuf;
+ }
+ curl_easy_setopt(fEasy, CURLOPT_HTTPHEADER, headersList);
+ curl_slist_free_all(headersList);
+ }
+
+ // Set up the payload
+ if(httpInfo->fPayload) {
+ fPayload = httpInfo->fPayload;
+ fPayloadLen = httpInfo->fPayloadLen;
+ curl_easy_setopt(fEasy, CURLOPT_READDATA, this);
+ curl_easy_setopt(fEasy, CURLOPT_READFUNCTION, staticReadCallback);
+ curl_easy_setopt(fEasy, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)fPayloadLen);
+ }
+ }
+
// Add easy handle to the multi stack
curl_multi_add_handle(fMulti, fEasy);
+
+ // Start reading, to get the content type
+ while(fBufferHeadPtr == fBuffer)
+ {
+ int runningHandles = 0;
+ readMore(&runningHandles);
+ if(runningHandles == 0) break;
+ }
+
+ // Find the content type
+ char *contentType8 = 0;
+ curl_easy_getinfo(fEasy, CURLINFO_CONTENT_TYPE, &contentType8);
+ fContentType = TranscodeFromStr((XMLByte*)contentType8,
XMLString::stringLen(contentType8), "ISO8859-1", fMemoryManager).adopt();
}
@@ -96,22 +178,26 @@
size_t
CurlURLInputStream::staticWriteCallback(char *buffer,
- size_t size,
- size_t nitems,
- void *outstream)
+ size_t size,
+ size_t nitems,
+ void *outstream)
{
return ((CurlURLInputStream*)outstream)->writeCallback(buffer, size,
nitems);
}
-size_t CurlURLInputStream::staticHeaderCallback(void *ptr, size_t size, size_t
nmemb, void *stream)
+size_t
+CurlURLInputStream::staticReadCallback(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *stream)
{
- return ((CurlURLInputStream*)stream)->headerCallback((char*)ptr, size,
nmemb);
+ return ((CurlURLInputStream*)stream)->readCallback(buffer, size, nitems);
}
size_t
CurlURLInputStream::writeCallback(char *buffer,
- size_t size,
- size_t nitems)
+ size_t size,
+ size_t nitems)
{
XMLSize_t cnt = size * nitems;
XMLSize_t totalConsumed = 0;
@@ -148,27 +234,93 @@
return totalConsumed;
}
-size_t CurlURLInputStream::headerCallback(char *buffer, size_t size, size_t
nitems)
+size_t
+CurlURLInputStream::readCallback(char *buffer,
+ size_t size,
+ size_t nitems)
{
- static const char *contentType = "Content-Type: ";
- static const size_t contentTypeLen = strlen(contentType);
+ XMLSize_t len = size * nitems;
+ if(len > fPayloadLen) len = fPayloadLen;
- // Calculate the actual length of the buffer
- size *= nitems;
+ memcpy(buffer, fPayload, len);
- if(size > contentTypeLen && strncmp(buffer, contentType, contentTypeLen)
== 0) {
- size_t valueLen = size - contentTypeLen;
+ fPayload += len;
+ fPayloadLen -= len;
- char* value8 = (char*)fMemoryManager->allocate(valueLen + 1);
- ArrayJanitor<char> janValue8(value8, fMemoryManager);
+ return len;
+}
- memcpy(value8, buffer + contentTypeLen, valueLen);
- value8[valueLen] = 0;
+bool CurlURLInputStream::readMore(int *runningHandles)
+{
+ // Ask the curl to do some work
+ CURLMcode curlResult = curl_multi_perform(fMulti, runningHandles);
+
+ // Process messages from curl
+ int msgsInQueue = 0;
+ for (CURLMsg* msg = NULL; (msg = curl_multi_info_read(fMulti,
&msgsInQueue)) != NULL; )
+ {
+ //printf("msg %d, %d from curl\n", msg->msg, msg->data.result);
- fContentType = XMLString::transcode(value8, fMemoryManager);
+ if (msg->msg != CURLMSG_DONE)
+ return true;
+
+ switch (msg->data.result)
+ {
+ case CURLE_OK:
+ // We completed successfully. runningHandles should have dropped
to zero, so we'll bail out below...
+ break;
+
+ case CURLE_UNSUPPORTED_PROTOCOL:
+ ThrowXMLwithMemMgr(MalformedURLException,
XMLExcepts::URL_UnsupportedProto, fMemoryManager);
+ break;
+
+ case CURLE_COULDNT_RESOLVE_HOST:
+ case CURLE_COULDNT_RESOLVE_PROXY:
+ ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_TargetResolution, fURLSource.getHost(), fMemoryManager);
+ break;
+
+ case CURLE_COULDNT_CONNECT:
+ ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_ConnSocket, fURLSource.getURLText(), fMemoryManager);
+ break;
+
+ case CURLE_RECV_ERROR:
+ ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_ReadSocket, fURLSource.getURLText(), fMemoryManager);
+ break;
+
+ default:
+ ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_InternalError, fURLSource.getURLText(), fMemoryManager);
+ break;
+ }
+ }
+
+ // If nothing is running any longer, bail out
+ if(*runningHandles == 0)
+ return false;
+
+ // If there is no further data to read, and we haven't
+ // read any yet on this invocation, call select to wait for data
+ if (curlResult != CURLM_CALL_MULTI_PERFORM && fBytesRead == 0)
+ {
+ fd_set readSet;
+ fd_set writeSet;
+ fd_set exceptSet;
+ int fdcnt=0;
+
+ FD_ZERO(&readSet);
+ FD_ZERO(&writeSet);
+ FD_ZERO(&exceptSet);
+
+ // Ask curl for the file descriptors to wait on
+ curl_multi_fdset(fMulti, &readSet, &writeSet, &exceptSet, &fdcnt);
+
+ // Wait on the file descriptors
+ timeval tv;
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ select(fdcnt+1, &readSet, &writeSet, &exceptSet, &tv);
}
- return size;
+ return curlResult == CURLM_CALL_MULTI_PERFORM;
}
XMLSize_t
@@ -204,74 +356,13 @@
// Ask the curl to do some work
int runningHandles = 0;
- CURLMcode curlResult = curl_multi_perform(fMulti,
&runningHandles);
- tryAgain = (curlResult == CURLM_CALL_MULTI_PERFORM);
-
- // Process messages from curl
- int msgsInQueue = 0;
- for (CURLMsg* msg = NULL; (msg = curl_multi_info_read(fMulti,
&msgsInQueue)) != NULL; )
- {
- //printf("msg %d, %d from curl\n", msg->msg,
msg->data.result);
-
- if (msg->msg != CURLMSG_DONE)
- continue;
-
- switch (msg->data.result)
- {
- case CURLE_OK:
- // We completed successfully. runningHandles
should have dropped to zero, so we'll bail out below...
- break;
-
- case CURLE_UNSUPPORTED_PROTOCOL:
- ThrowXMLwithMemMgr(MalformedURLException,
XMLExcepts::URL_UnsupportedProto, fMemoryManager);
- break;
-
- case CURLE_COULDNT_RESOLVE_HOST:
- case CURLE_COULDNT_RESOLVE_PROXY:
- ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_TargetResolution, fURLSource.getHost(), fMemoryManager);
- break;
-
- case CURLE_COULDNT_CONNECT:
- ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_ConnSocket, fURLSource.getURLText(), fMemoryManager);
-
- case CURLE_RECV_ERROR:
- ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_ReadSocket, fURLSource.getURLText(), fMemoryManager);
- break;
-
- default:
- ThrowXMLwithMemMgr1(NetAccessorException,
XMLExcepts::NetAcc_InternalError, fURLSource.getURLText(), fMemoryManager);
- break;
- }
- }
+ tryAgain = readMore(&runningHandles);
// If nothing is running any longer, bail out
if (runningHandles == 0)
break;
-
- // If there is no further data to read, and we haven't
- // read any yet on this invocation, call select to wait for data
- if (!tryAgain && fBytesRead == 0)
- {
- fd_set readSet;
- fd_set writeSet;
- fd_set exceptSet;
- int fdcnt=0;
-
- FD_ZERO(&readSet);
- FD_ZERO(&writeSet);
- FD_ZERO(&exceptSet);
-
- // Ask curl for the file descriptors to wait on
- curl_multi_fdset(fMulti, &readSet, &writeSet,
&exceptSet, &fdcnt);
-
- // Wait on the file descriptors
- timeval tv;
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- select(fdcnt+1, &readSet, &writeSet, &exceptSet, &tv);
- }
}
-
+
return fBytesRead;
}
Modified:
xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.hpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.hpp?rev=675241&r1=675240&r2=675241&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.hpp
(original)
+++ xerces/c/trunk/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.hpp
Wed Jul 9 09:01:01 2008
@@ -68,14 +68,16 @@
size_t writeCallback( char *buffer,
size_t size,
size_t nitems);
- static size_t staticHeaderCallback(void *ptr,
- size_t size,
- size_t nmemb,
- void *stream);
- size_t headerCallback( char *buffer,
- size_t size,
- size_t nitems);
+ static size_t staticReadCallback(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *stream);
+ size_t readCallback( char *buffer,
+ size_t size,
+ size_t nitems);
+
+ bool readMore(int *runningHandles);
// -----------------------------------------------------------------------
// Private data members
@@ -100,7 +102,6 @@
MemoryManager* fMemoryManager;
XMLURL fURLSource;
- ArrayJanitor<char> fURL;
unsigned long fTotalBytesRead;
XMLByte* fWritePtr;
@@ -114,6 +115,10 @@
XMLByte* fBufferHeadPtr;
XMLByte* fBufferTailPtr;
+ // Upload data
+ const char* fPayload;
+ XMLSize_t fPayloadLen;
+
XMLCh * fContentType;
}; // CurlURLInputStream
Modified:
xerces/c/trunk/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp?rev=675241&r1=675240&r2=675241&view=diff
==============================================================================
---
xerces/c/trunk/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp
(original)
+++
xerces/c/trunk/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp
Wed Jul 9 09:01:01 2008
@@ -204,7 +204,6 @@
if(status == 200) {
// HTTP 200 OK response means we're done.
- // We're done
break;
}
// a 3xx response means there was an HTTP redirect
Modified: xerces/c/trunk/src/xercesc/util/TransService.cpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/util/TransService.cpp?rev=675241&r1=675240&r2=675241&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/TransService.cpp (original)
+++ xerces/c/trunk/src/xercesc/util/TransService.cpp Wed Jul 9 09:01:01 2008
@@ -536,4 +536,184 @@
{
}
+// ---------------------------------------------------------------------------
+// TranscodeToStr: Public constructors and destructor
+// ---------------------------------------------------------------------------
+TranscodeToStr::TranscodeToStr(const XMLCh *in, const char *encoding,
+ MemoryManager *manager)
+ : fString(0),
+ fBytesWritten(0),
+ fMemoryManager(manager)
+{
+ XMLTransService::Codes failReason;
+ const XMLSize_t blockSize = 2048;
+
+ XMLTranscoder* trans =
XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason,
blockSize, fMemoryManager);
+ Janitor<XMLTranscoder> janTrans(trans);
+
+ transcode(in, XMLString::stringLen(in), trans);
+}
+
+TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLSize_t length, const char
*encoding,
+ MemoryManager *manager)
+ : fString(0),
+ fBytesWritten(0),
+ fMemoryManager(manager)
+{
+ XMLTransService::Codes failReason;
+ const XMLSize_t blockSize = 2048;
+
+ XMLTranscoder* trans =
XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason,
blockSize, fMemoryManager);
+ Janitor<XMLTranscoder> janTrans(trans);
+
+ transcode(in, length, trans);
+}
+
+TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLTranscoder* trans,
+ MemoryManager *manager)
+ : fString(0),
+ fBytesWritten(0),
+ fMemoryManager(manager)
+{
+ transcode(in, XMLString::stringLen(in), trans);
+}
+
+TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLSize_t length,
XMLTranscoder* trans,
+ MemoryManager *manager)
+ : fString(0),
+ fBytesWritten(0),
+ fMemoryManager(manager)
+{
+ transcode(in, length, trans);
+}
+
+TranscodeToStr::~TranscodeToStr()
+{
+ if(fString)
+ fMemoryManager->deallocate(fString);
+}
+
+// ---------------------------------------------------------------------------
+// TranscodeToStr: Private helper methods
+// ---------------------------------------------------------------------------
+void TranscodeToStr::transcode(const XMLCh *in, XMLSize_t len, XMLTranscoder*
trans)
+{
+ if(!in) return;
+
+ XMLSize_t allocSize = len * sizeof(XMLCh);
+ fString = (XMLByte*)fMemoryManager->allocate(allocSize);
+
+ XMLSize_t charsRead;
+ XMLSize_t charsDone = 0;
+
+ while(true) {
+ fBytesWritten += trans->transcodeTo(in + charsDone, len - charsDone,
+ fString + fBytesWritten, allocSize
- fBytesWritten,
+ charsRead,
XMLTranscoder::UnRep_Throw);
+ charsDone += charsRead;
+
+ if(charsDone == len) break;
+
+ allocSize *= 2;
+ XMLByte *newBuf = (XMLByte*)fMemoryManager->allocate(allocSize);
+ memcpy(newBuf, fString, fBytesWritten);
+ fMemoryManager->deallocate(fString);
+ fString = newBuf;
+ }
+
+ // null terminate
+ if(fBytesWritten > (allocSize - 4)) {
+ allocSize = fBytesWritten + 4;
+ XMLByte *newBuf = (XMLByte*)fMemoryManager->allocate(allocSize);
+ memcpy(newBuf, fString, fBytesWritten);
+ fMemoryManager->deallocate(fString);
+ fString = newBuf;
+ }
+ fString[fBytesWritten + 0] = 0;
+ fString[fBytesWritten + 1] = 0;
+ fString[fBytesWritten + 2] = 0;
+ fString[fBytesWritten + 3] = 0;
+}
+
+// ---------------------------------------------------------------------------
+// TranscodeFromStr: Public constructors and destructor
+// ---------------------------------------------------------------------------
+TranscodeFromStr::TranscodeFromStr(const XMLByte *data, XMLSize_t length,
const char *encoding,
+ MemoryManager *manager)
+ : fString(0),
+ fCharsWritten(0),
+ fMemoryManager(manager)
+{
+ XMLTransService::Codes failReason;
+ const XMLSize_t blockSize = 2048;
+
+ XMLTranscoder* trans =
XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason,
blockSize, fMemoryManager);
+ Janitor<XMLTranscoder> janTrans(trans);
+
+ transcode(data, length, trans);
+}
+
+TranscodeFromStr::TranscodeFromStr(const XMLByte *data, XMLSize_t length,
XMLTranscoder *trans,
+ MemoryManager *manager)
+ : fString(0),
+ fCharsWritten(0),
+ fMemoryManager(manager)
+{
+ transcode(data, length, trans);
+}
+
+TranscodeFromStr::~TranscodeFromStr()
+{
+ if(fString)
+ fMemoryManager->deallocate(fString);
+}
+
+// ---------------------------------------------------------------------------
+// TranscodeFromStr: Private helper methods
+// ---------------------------------------------------------------------------
+void TranscodeFromStr::transcode(const XMLByte *in, XMLSize_t length,
XMLTranscoder *trans)
+{
+ if(!in) return;
+
+ XMLSize_t allocSize = length;
+ fString = (XMLCh*)fMemoryManager->allocate(allocSize * sizeof(XMLCh));
+
+ XMLSize_t csSize = length;
+ ArrayJanitor<unsigned char> charSizes((unsigned
char*)fMemoryManager->allocate(csSize * sizeof(unsigned char)),
+ fMemoryManager);
+
+ XMLSize_t bytesRead;
+ XMLSize_t bytesDone = 0;
+
+ while(true) {
+ fCharsWritten += trans->transcodeFrom(in + bytesDone, length -
bytesDone,
+ fString + fCharsWritten,
allocSize - fCharsWritten,
+ bytesRead, charSizes.get());
+ bytesDone += bytesRead;
+ if(bytesDone == length) break;
+
+ allocSize *= 2;
+ XMLCh *newBuf = (XMLCh*)fMemoryManager->allocate(allocSize);
+ memcpy(newBuf, fString, fCharsWritten);
+ fMemoryManager->deallocate(fString);
+ fString = newBuf;
+
+ if((allocSize - fCharsWritten) > csSize) {
+ csSize = allocSize - fCharsWritten;
+ charSizes.reset((unsigned char*)fMemoryManager->allocate(csSize *
sizeof(unsigned char)),
+ fMemoryManager);
+ }
+ }
+
+ // null terminate
+ if(fCharsWritten == allocSize) {
+ allocSize += sizeof(XMLCh);
+ XMLCh *newBuf = (XMLCh*)fMemoryManager->allocate(allocSize);
+ memcpy(newBuf, fString, fCharsWritten);
+ fMemoryManager->deallocate(fString);
+ fString = newBuf;
+ }
+ fString[fCharsWritten] = 0;
+}
+
XERCES_CPP_NAMESPACE_END
Modified: xerces/c/trunk/src/xercesc/util/TransService.hpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/util/TransService.hpp?rev=675241&r1=675240&r2=675241&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/TransService.hpp (original)
+++ xerces/c/trunk/src/xercesc/util/TransService.hpp Wed Jul 9 09:01:01 2008
@@ -455,6 +455,187 @@
XMLLCPTranscoder& operator=(const XMLLCPTranscoder&);
};
+//
+// This class can be used to transcode to a target encoding. It manages the
+// memory allocated for the transcode in an exception safe manner,
automatically
+// deleting it when the class goes out of scope.
+//
+class XMLUTIL_EXPORT TranscodeToStr
+{
+public:
+ // -----------------------------------------------------------------------
+ // Public constructors and destructor
+ // -----------------------------------------------------------------------
+
+ /** Converts from the internal XMLCh* encoding to the specified encoding
+ *
+ * @param in the null terminated source buffer to be transcoded
+ * @param encoding the name of the encoding to transcode to
+ * @param manager the memory manager to use
+ */
+ TranscodeToStr(const XMLCh *in, const char *encoding,
+ MemoryManager *manager = XMLPlatformUtils::fgMemoryManager);
+
+ /** Converts from the internal XMLCh* encoding to the specified encoding
+ *
+ * @param in the source buffer to be transcoded
+ * @param length the length of the source buffer
+ * @param encoding the name of the encoding to transcode to
+ * @param manager the memory manager to use
+ */
+ TranscodeToStr(const XMLCh *in, XMLSize_t length, const char *encoding,
+ MemoryManager *manager = XMLPlatformUtils::fgMemoryManager);
+
+ /** Converts from the internal XMLCh* encoding to the specified encoding
+ *
+ * @param in the null terminated source buffer to be transcoded
+ * @param trans the transcoder to use
+ * @param manager the memory manager to use
+ */
+ TranscodeToStr(const XMLCh *in, XMLTranscoder* trans,
+ MemoryManager *manager = XMLPlatformUtils::fgMemoryManager);
+
+ /** Converts from the internal XMLCh* encoding to the specified encoding
+ *
+ * @param in the source buffer to be transcoded
+ * @param length the length of the source buffer
+ * @param trans the transcoder to use
+ * @param manager the memory manager to use
+ */
+ TranscodeToStr(const XMLCh *in, XMLSize_t length, XMLTranscoder* trans,
+ MemoryManager *manager = XMLPlatformUtils::fgMemoryManager);
+
+ ~TranscodeToStr();
+
+ /** @name Getter methods */
+ //@{
+
+ /** Returns the transcoded, null terminated string
+ * @return the transcoded string
+ */
+ const XMLByte *str() const;
+
+ /** Returns the transcoded, null terminated string - adopting
+ * the memory allocated to it from the TranscodeToStr object
+ * @return the transcoded string
+ */
+ XMLByte *adopt();
+
+ /** Returns the length of the transcoded string in bytes. The length
+ * does not include the null terminator.
+ * @return the length of the transcoded string in bytes
+ */
+ XMLSize_t length () const;
+
+ //@}
+
+private:
+ // -----------------------------------------------------------------------
+ // Unimplemented constructors and operators
+ // -----------------------------------------------------------------------
+ TranscodeToStr(const TranscodeToStr &);
+ TranscodeToStr &operator=(const TranscodeToStr &);
+
+ // -----------------------------------------------------------------------
+ // Private helper methods
+ // -----------------------------------------------------------------------
+ void transcode(const XMLCh *in, XMLSize_t len, XMLTranscoder* trans);
+
+ // -----------------------------------------------------------------------
+ // Private data members
+ //
+ // fString
+ // The transcoded string
+ //
+ // fBytesWritten
+ // The length of the transcoded string in bytes
+ // -----------------------------------------------------------------------
+ XMLByte *fString;
+ XMLSize_t fBytesWritten;
+ MemoryManager *fMemoryManager;
+};
+
+//
+// This class can be used to transcode from a source encoding. It manages the
+// memory allocated for the transcode in an exception safe manner,
automatically
+// deleting it when the class goes out of scope.
+//
+class XMLUTIL_EXPORT TranscodeFromStr
+{
+public:
+ // -----------------------------------------------------------------------
+ // Public constructors and destructor
+ // -----------------------------------------------------------------------
+
+ /** Converts from the specified encoding to the internal XMLCh* encoding
+ *
+ * @param in the source buffer to be transcoded
+ * @param length the length of the source buffer
+ * @param encoding the name of the encoding to transcode to
+ * @param manager the memory manager to use
+ */
+ TranscodeFromStr(const XMLByte *data, XMLSize_t length, const char
*encoding,
+ MemoryManager *manager =
XMLPlatformUtils::fgMemoryManager);
+
+ /** Converts from the specified encoding to the internal XMLCh* encoding
+ *
+ * @param in the source buffer to be transcoded
+ * @param length the length of the source buffer
+ * @param trans the transcoder to use
+ * @param manager the memory manager to use
+ */
+ TranscodeFromStr(const XMLByte *data, XMLSize_t length, XMLTranscoder
*trans,
+ MemoryManager *manager =
XMLPlatformUtils::fgMemoryManager);
+
+ ~TranscodeFromStr();
+
+ /** @name Getter methods */
+ //@{
+
+ /** Returns the transcoded, null terminated string
+ * @return the transcoded string
+ */
+ const XMLCh *str() const;
+
+ /** Returns the transcoded, null terminated string - adopting
+ * the memory allocated to it from the TranscodeFromStr object
+ * @return the transcoded string
+ */
+ XMLCh *adopt();
+
+ /** Returns the length of the transcoded string in characters. The length
+ * does not include the null terminator.
+ * @return the length of the transcoded string in characters
+ */
+ XMLSize_t length() const;
+
+ //@}
+
+private:
+ // -----------------------------------------------------------------------
+ // Unimplemented constructors and operators
+ // -----------------------------------------------------------------------
+ TranscodeFromStr(const TranscodeFromStr &);
+ TranscodeFromStr &operator=(const TranscodeFromStr &);
+
+ // -----------------------------------------------------------------------
+ // Private helper methods
+ // -----------------------------------------------------------------------
+ void transcode(const XMLByte *in, XMLSize_t length, XMLTranscoder *trans);
+
+ // -----------------------------------------------------------------------
+ // Private data members
+ //
+ // fString
+ // The transcoded string
+ //
+ // fBytesWritten
+ // The length of the transcoded string in characters
+ // -----------------------------------------------------------------------
+ XMLCh *fString;
+ XMLSize_t fCharsWritten;
+ MemoryManager *fMemoryManager;
+};
// ---------------------------------------------------------------------------
// XMLTranscoder: Getter methods
@@ -477,6 +658,46 @@
return fEncodingName;
}
+// ---------------------------------------------------------------------------
+// TranscodeToStr: Getter methods
+// ---------------------------------------------------------------------------
+inline const XMLByte *TranscodeToStr::str() const
+{
+ return fString;
+}
+
+inline XMLByte *TranscodeToStr::adopt()
+{
+ XMLByte *tmp = fString;
+ fString = 0;
+ return tmp;
+}
+
+inline XMLSize_t TranscodeToStr::length () const
+{
+ return fBytesWritten;
+}
+
+// ---------------------------------------------------------------------------
+// TranscodeFromStr: Getter methods
+// ---------------------------------------------------------------------------
+inline const XMLCh *TranscodeFromStr::str() const
+{
+ return fString;
+}
+
+inline XMLCh *TranscodeFromStr::adopt()
+{
+ XMLCh *tmp = fString;
+ fString = 0;
+ return tmp;
+}
+
+inline XMLSize_t TranscodeFromStr::length() const
+{
+ return fCharsWritten;
+}
+
XERCES_CPP_NAMESPACE_END
#endif
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]