2010-11-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Replaced HttpHeader::responseStatus_ with HttpHeader::statusCode_.
	statusCode_ is of type int.
	* src/AbstractProxyResponseCommand.cc
	* src/FtpNegotiationCommand.cc
	* src/HttpHeader.cc
	* src/HttpHeader.h
	* src/HttpHeaderProcessor.cc
	* src/HttpResponse.cc
	* src/HttpResponse.h
	* src/HttpResponseCommand.cc
	* src/HttpSkipResponseCommand.cc
	* src/util.cc
	* src/util.h
	* test/HttpHeaderProcessorTest.cc
	* test/HttpHeaderTest.cc
	* test/HttpResponseTest.cc
	* test/UtilTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-11-15 12:52:03 +00:00
parent 6a1fe66975
commit d8d159ccd8
16 changed files with 116 additions and 104 deletions

View File

@ -1,3 +1,23 @@
2010-11-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Replaced HttpHeader::responseStatus_ with HttpHeader::statusCode_.
statusCode_ is of type int.
* src/AbstractProxyResponseCommand.cc
* src/FtpNegotiationCommand.cc
* src/HttpHeader.cc
* src/HttpHeader.h
* src/HttpHeaderProcessor.cc
* src/HttpResponse.cc
* src/HttpResponse.h
* src/HttpResponseCommand.cc
* src/HttpSkipResponseCommand.cc
* src/util.cc
* src/util.h
* test/HttpHeaderProcessorTest.cc
* test/HttpHeaderTest.cc
* test/HttpResponseTest.cc
* test/UtilTest.cc
2010-11-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> 2010-11-15 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Use SharedHandle::swap() in some places. Use SharedHandle::swap() in some places.

View File

@ -69,7 +69,7 @@ bool AbstractProxyResponseCommand::executeInternal() {
getDownloadEngine()->addCommand(this); getDownloadEngine()->addCommand(this);
return false; return false;
} }
if(httpResponse->getResponseStatus() != HttpHeader::S200) { if(httpResponse->getStatusCode() != 200) {
throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED); throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED);
} }
getDownloadEngine()->addCommand(getNextCommand()); getDownloadEngine()->addCommand(getNextCommand());

View File

@ -747,7 +747,7 @@ bool FtpNegotiationCommand::recvTunnelResponse()
if(!httpResponse) { if(!httpResponse) {
return false; return false;
} }
if(httpResponse->getResponseStatus() != HttpHeader::S200) { if(httpResponse->getStatusCode() != 200) {
throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED); throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED);
} }
sequence_ = SEQ_SEND_REST_PASV; sequence_ = SEQ_SEND_REST_PASV;

View File

@ -76,28 +76,6 @@ const std::string HttpHeader::ACCEPT_ENCODING("Accept-Encoding");
const std::string HttpHeader::HTTP_1_1("HTTP/1.1"); const std::string HttpHeader::HTTP_1_1("HTTP/1.1");
const std::string HttpHeader::S200("200");
const std::string HttpHeader::S206("206");
const std::string HttpHeader::S300("300");
const std::string HttpHeader::S301("301");
const std::string HttpHeader::S302("302");
const std::string HttpHeader::S303("303");
const std::string HttpHeader::S304("304");
const std::string HttpHeader::S307("307");
const std::string HttpHeader::S400("400");
const std::string HttpHeader::S401("401");
const std::string HttpHeader::S404("404");
HttpHeader::HttpHeader() {} HttpHeader::HttpHeader() {}
HttpHeader::~HttpHeader() {} HttpHeader::~HttpHeader() {}
@ -201,11 +179,6 @@ RangeHandle HttpHeader::getRange() const
return SharedHandle<Range>(new Range(startByte, endByte, entityLength)); return SharedHandle<Range>(new Range(startByte, endByte, entityLength));
} }
void HttpHeader::setResponseStatus(const std::string& responseStatus)
{
responseStatus_ = responseStatus;
}
void HttpHeader::setVersion(const std::string& version) void HttpHeader::setVersion(const std::string& version)
{ {
version_ = version; version_ = version;

View File

@ -52,9 +52,8 @@ class HttpHeader {
private: private:
std::multimap<std::string, std::string> table_; std::multimap<std::string, std::string> table_;
// for HTTP response header only // HTTP status code, e.g. 200
// response status, e.g. "200" int statusCode_;
std::string responseStatus_;
// HTTP version, e.g. HTTP/1.1 // HTTP version, e.g. HTTP/1.1
std::string version_; std::string version_;
@ -77,12 +76,15 @@ public:
SharedHandle<Range> getRange() const; SharedHandle<Range> getRange() const;
const std::string& getResponseStatus() const int getStatusCode() const
{ {
return responseStatus_; return statusCode_;
} }
void setResponseStatus(const std::string& responseStatus); void setStatusCode(int code)
{
statusCode_ = code;
}
const std::string& getVersion() const const std::string& getVersion() const
{ {
@ -143,28 +145,6 @@ public:
static const std::string ACCEPT_ENCODING; static const std::string ACCEPT_ENCODING;
static const std::string HTTP_1_1; static const std::string HTTP_1_1;
static const std::string S200;
static const std::string S206;
static const std::string S300;
static const std::string S301;
static const std::string S302;
static const std::string S303;
static const std::string S304;
static const std::string S307;
static const std::string S400;
static const std::string S401;
static const std::string S404;
}; };
typedef SharedHandle<HttpHeader> HttpHeaderHandle; typedef SharedHandle<HttpHeader> HttpHeaderHandle;

View File

@ -110,9 +110,13 @@ SharedHandle<HttpHeader> HttpHeaderProcessor::getHttpResponseHeader()
delimpos < 12) { delimpos < 12) {
throw DL_RETRY_EX(EX_NO_STATUS_HEADER); throw DL_RETRY_EX(EX_NO_STATUS_HEADER);
} }
int32_t statusCode;
if(!util::parseIntNoThrow(statusCode, buf_.substr(9, 3))) {
throw DL_RETRY_EX("Status code could not be parsed as integer.");
}
HttpHeaderHandle httpHeader(new HttpHeader()); HttpHeaderHandle httpHeader(new HttpHeader());
httpHeader->setVersion(buf_.substr(0, 8)); httpHeader->setVersion(buf_.substr(0, 8));
httpHeader->setResponseStatus(buf_.substr(9, 3)); httpHeader->setStatusCode(statusCode);
std::istringstream strm(buf_); std::istringstream strm(buf_);
// TODO 1st line(HTTP/1.1 200...) is also send to HttpHeader, but it should // TODO 1st line(HTTP/1.1 200...) is also send to HttpHeader, but it should
// not. // not.

View File

@ -64,26 +64,24 @@ HttpResponse::~HttpResponse() {}
void HttpResponse::validateResponse() const void HttpResponse::validateResponse() const
{ {
const std::string& status = getResponseStatus(); int statusCode = getStatusCode();
if(status >= HttpHeader::S400) { if(statusCode >= 400) {
return; return;
} }
if(status == HttpHeader::S304) { if(statusCode == 304) {
if(httpRequest_->getIfModifiedSinceHeader().empty()) { if(httpRequest_->getIfModifiedSinceHeader().empty()) {
throw DL_ABORT_EX("Got 304 without If-Modified-Since"); throw DL_ABORT_EX("Got 304 without If-Modified-Since");
} }
} else if(status == HttpHeader::S301 || } else if(statusCode == 301 ||
status == HttpHeader::S302 || statusCode == 302 ||
status == HttpHeader::S303 || statusCode == 303 ||
status == HttpHeader::S307) { statusCode == 307) {
if(!httpHeader_->defined(HttpHeader::LOCATION)) { if(!httpHeader_->defined(HttpHeader::LOCATION)) {
throw DL_ABORT_EX throw DL_ABORT_EX
(StringFormat(EX_LOCATION_HEADER_REQUIRED, (StringFormat(EX_LOCATION_HEADER_REQUIRED, statusCode).str());
util::parseUInt(status)).str());
} }
return; return;
} else if(status == HttpHeader::S200 || } else if(statusCode == 200 || statusCode == 206) {
status == HttpHeader::S206) {
if(!httpHeader_->defined(HttpHeader::TRANSFER_ENCODING)) { if(!httpHeader_->defined(HttpHeader::TRANSFER_ENCODING)) {
// compare the received range against the requested range // compare the received range against the requested range
RangeHandle responseRange = httpHeader_->getRange(); RangeHandle responseRange = httpHeader_->getRange();
@ -102,7 +100,7 @@ void HttpResponse::validateResponse() const
} }
} else { } else {
throw DL_ABORT_EX throw DL_ABORT_EX
(StringFormat("Unexpected status %s", status.c_str()).str()); (StringFormat("Unexpected status %d", statusCode).str());
} }
} }
@ -140,11 +138,11 @@ void HttpResponse::retrieveCookie()
bool HttpResponse::isRedirect() const bool HttpResponse::isRedirect() const
{ {
const std::string& status = getResponseStatus(); int statusCode = getStatusCode();
return (HttpHeader::S301 == status || return (301 == statusCode ||
HttpHeader::S302 == status || 302 == statusCode ||
HttpHeader::S303 == status || 303 == statusCode ||
HttpHeader::S307 == status) && 307 == statusCode) &&
httpHeader_->defined(HttpHeader::LOCATION); httpHeader_->defined(HttpHeader::LOCATION);
} }
@ -254,10 +252,9 @@ void HttpResponse::setHttpRequest(const SharedHandle<HttpRequest>& httpRequest)
httpRequest_ = httpRequest; httpRequest_ = httpRequest;
} }
// TODO return std::string int HttpResponse::getStatusCode() const
const std::string& HttpResponse::getResponseStatus() const
{ {
return httpHeader_->getResponseStatus(); return httpHeader_->getStatusCode();
} }
bool HttpResponse::hasRetryAfter() const bool HttpResponse::hasRetryAfter() const

View File

@ -108,7 +108,7 @@ public:
return httpHeader_; return httpHeader_;
} }
const std::string& getResponseStatus() const; int getStatusCode() const;
void setHttpRequest(const SharedHandle<HttpRequest>& httpRequest); void setHttpRequest(const SharedHandle<HttpRequest>& httpRequest);

View File

@ -167,8 +167,9 @@ bool HttpResponseCommand::executeInternal()
(getOption()->getAsInt(PREF_MAX_HTTP_PIPELINING)); (getOption()->getAsInt(PREF_MAX_HTTP_PIPELINING));
} }
int statusCode = httpResponse->getStatusCode();
if(!httpResponse->getHttpRequest()->getIfModifiedSinceHeader().empty()) { if(!httpResponse->getHttpRequest()->getIfModifiedSinceHeader().empty()) {
if(httpResponse->getResponseStatus() == HttpHeader::S304) { if(statusCode == 304) {
uint64_t totalLength = httpResponse->getEntityLength(); uint64_t totalLength = httpResponse->getEntityLength();
getFileEntry()->setLength(totalLength); getFileEntry()->setLength(totalLength);
getRequestGroup()->initPieceStorage(); getRequestGroup()->initPieceStorage();
@ -181,15 +182,13 @@ bool HttpResponseCommand::executeInternal()
poolConnection(); poolConnection();
getFileEntry()->poolRequest(getRequest()); getFileEntry()->poolRequest(getRequest());
return true; return true;
} else if(httpResponse->getResponseStatus() == HttpHeader::S200 || } else if(statusCode == 200 || statusCode == 206) {
httpResponse->getResponseStatus() == HttpHeader::S206) {
// Remote file is newer than local file. We allow overwrite. // Remote file is newer than local file. We allow overwrite.
getOption()->put(PREF_ALLOW_OVERWRITE, A2_V_TRUE); getOption()->put(PREF_ALLOW_OVERWRITE, A2_V_TRUE);
} }
} }
if(httpResponse->getResponseStatus() >= HttpHeader::S300 && if(statusCode != 304 && statusCode >= 300) {
httpResponse->getResponseStatus() != HttpHeader::S304) { if(statusCode == 404) {
if(httpResponse->getResponseStatus() == HttpHeader::S404) {
getRequestGroup()->increaseAndValidateFileNotFoundCount(); getRequestGroup()->increaseAndValidateFileNotFoundCount();
} }
return skipResponseBody(httpResponse); return skipResponseBody(httpResponse);

View File

@ -171,6 +171,7 @@ void HttpSkipResponseCommand::poolConnection() const
bool HttpSkipResponseCommand::processResponse() bool HttpSkipResponseCommand::processResponse()
{ {
int statusCode;
if(httpResponse_->isRedirect()) { if(httpResponse_->isRedirect()) {
unsigned int rnum = unsigned int rnum =
httpResponse_->getHttpRequest()->getRequest()->getRedirectCount(); httpResponse_->getHttpRequest()->getRequest()->getRedirectCount();
@ -180,8 +181,8 @@ bool HttpSkipResponseCommand::processResponse()
} }
httpResponse_->processRedirect(); httpResponse_->processRedirect();
return prepareForRetry(0); return prepareForRetry(0);
} else if(httpResponse_->getResponseStatus() >= HttpHeader::S400) { } else if((statusCode = httpResponse_->getStatusCode()) >= 400) {
if(httpResponse_->getResponseStatus() == HttpHeader::S401) { if(statusCode == 401) {
if(getOption()->getAsBool(PREF_HTTP_AUTH_CHALLENGE) && if(getOption()->getAsBool(PREF_HTTP_AUTH_CHALLENGE) &&
!httpResponse_->getHttpRequest()->authenticationUsed() && !httpResponse_->getHttpRequest()->authenticationUsed() &&
getDownloadEngine()->getAuthConfigFactory()->activateBasicCred getDownloadEngine()->getAuthConfigFactory()->activateBasicCred
@ -190,14 +191,11 @@ bool HttpSkipResponseCommand::processResponse()
} else { } else {
throw DL_ABORT_EX(EX_AUTH_FAILED); throw DL_ABORT_EX(EX_AUTH_FAILED);
} }
}else if(httpResponse_->getResponseStatus() == HttpHeader::S404) { } else if(statusCode == 404) {
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND, throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
downloadresultcode::RESOURCE_NOT_FOUND); downloadresultcode::RESOURCE_NOT_FOUND);
} else { } else {
throw DL_ABORT_EX throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, statusCode).str());
(StringFormat
(EX_BAD_STATUS,
util::parseUInt(httpResponse_->getResponseStatus())).str());
} }
} else { } else {
return prepareForRetry(0); return prepareForRetry(0);

View File

@ -512,6 +512,26 @@ int32_t parseInt(const std::string& s, int32_t base)
return v; return v;
} }
bool parseIntNoThrow(int32_t& result, const std::string& s, int base)
{
// Without trim, strtol(" -1 ",..) emits error.
std::string trimed = strip(s);
if(trimed.empty()) {
return false;
}
char* stop;
errno = 0;
long int v = strtol(trimed.c_str(), &stop, base);
if(*stop != '\0') {
return false;
} else if(((v == LONG_MAX || v == LONG_MIN) && (errno == ERANGE)) ||
v < INT32_MIN || INT32_MAX < v) {
return false;
}
result = v;
return true;
}
uint32_t parseUInt(const std::string& s, int base) uint32_t parseUInt(const std::string& s, int base)
{ {
uint64_t v = parseULLInt(s, base); uint64_t v = parseULLInt(s, base);
@ -524,7 +544,7 @@ uint32_t parseUInt(const std::string& s, int base)
bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base) bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base)
{ {
// TODO what happens when we don't trim s? // Without trim, strtol(" -1 ",..) emits error.
std::string trimed = strip(s); std::string trimed = strip(s);
if(trimed.empty()) { if(trimed.empty()) {
return false; return false;
@ -567,6 +587,7 @@ int64_t parseLLInt(const std::string& s, int32_t base)
bool parseLLIntNoThrow(int64_t& result, const std::string& s, int base) bool parseLLIntNoThrow(int64_t& result, const std::string& s, int base)
{ {
// Without trim, strtol(" -1 ",..) emits error.
std::string trimed = strip(s); std::string trimed = strip(s);
if(trimed.empty()) { if(trimed.empty()) {
return false; return false;

View File

@ -188,6 +188,8 @@ std::string secfmt(time_t sec);
int32_t parseInt(const std::string& s, int32_t base = 10); int32_t parseInt(const std::string& s, int32_t base = 10);
bool parseIntNoThrow(int32_t& result, const std::string& s, int base = 10);
uint32_t parseUInt(const std::string& s, int base = 10); uint32_t parseUInt(const std::string& s, int base = 10);
bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base = 10); bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base = 10);

View File

@ -107,7 +107,7 @@ void HttpHeaderProcessorTest::testGetHttpResponseHeader()
proc.update(hd); proc.update(hd);
SharedHandle<HttpHeader> header = proc.getHttpResponseHeader(); SharedHandle<HttpHeader> header = proc.getHttpResponseHeader();
CPPUNIT_ASSERT_EQUAL(std::string("200"), header->getResponseStatus()); CPPUNIT_ASSERT_EQUAL(200, header->getStatusCode());
CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion()); CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion());
CPPUNIT_ASSERT_EQUAL(std::string("Mon, 25 Jun 2007 16:04:59 GMT"), CPPUNIT_ASSERT_EQUAL(std::string("Mon, 25 Jun 2007 16:04:59 GMT"),
header->getFirst("Date")); header->getFirst("Date"));
@ -138,7 +138,7 @@ void HttpHeaderProcessorTest::testGetHttpResponseHeader_statusOnly()
std::string hd = "HTTP/1.1 200\r\n\r\n"; std::string hd = "HTTP/1.1 200\r\n\r\n";
proc.update(hd); proc.update(hd);
SharedHandle<HttpHeader> header = proc.getHttpResponseHeader(); SharedHandle<HttpHeader> header = proc.getHttpResponseHeader();
CPPUNIT_ASSERT_EQUAL(std::string("200"), header->getResponseStatus()); CPPUNIT_ASSERT_EQUAL(200, header->getStatusCode());
} }
void HttpHeaderProcessorTest::testGetHttpResponseHeader_insufficientStatusLength() void HttpHeaderProcessorTest::testGetHttpResponseHeader_insufficientStatusLength()

View File

@ -83,7 +83,7 @@ void HttpHeaderTest::testGet()
void HttpHeaderTest::testClearField() void HttpHeaderTest::testClearField()
{ {
HttpHeader h; HttpHeader h;
h.setResponseStatus(HttpHeader::S200); h.setStatusCode(200);
h.setVersion(HttpHeader::HTTP_1_1); h.setVersion(HttpHeader::HTTP_1_1);
h.put("Foo", "Bar"); h.put("Foo", "Bar");
@ -92,7 +92,7 @@ void HttpHeaderTest::testClearField()
h.clearField(); h.clearField();
CPPUNIT_ASSERT_EQUAL(std::string(""), h.getFirst("Foo")); CPPUNIT_ASSERT_EQUAL(std::string(""), h.getFirst("Foo"));
CPPUNIT_ASSERT_EQUAL(HttpHeader::S200, h.getResponseStatus()); CPPUNIT_ASSERT_EQUAL(200, h.getStatusCode());
CPPUNIT_ASSERT_EQUAL(HttpHeader::HTTP_1_1, h.getVersion()); CPPUNIT_ASSERT_EQUAL(HttpHeader::HTTP_1_1, h.getVersion());
} }

View File

@ -212,14 +212,14 @@ void HttpResponseTest::testIsRedirect()
{ {
HttpResponse httpResponse; HttpResponse httpResponse;
SharedHandle<HttpHeader> httpHeader(new HttpHeader()); SharedHandle<HttpHeader> httpHeader(new HttpHeader());
httpHeader->setResponseStatus("200"); httpHeader->setStatusCode(200);
httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2"); httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
httpResponse.setHttpHeader(httpHeader); httpResponse.setHttpHeader(httpHeader);
CPPUNIT_ASSERT(!httpResponse.isRedirect()); CPPUNIT_ASSERT(!httpResponse.isRedirect());
httpHeader->setResponseStatus("301"); httpHeader->setStatusCode(301);
CPPUNIT_ASSERT(httpResponse.isRedirect()); CPPUNIT_ASSERT(httpResponse.isRedirect());
} }
@ -340,7 +340,7 @@ void HttpResponseTest::testValidateResponse()
SharedHandle<HttpHeader> httpHeader(new HttpHeader()); SharedHandle<HttpHeader> httpHeader(new HttpHeader());
httpResponse.setHttpHeader(httpHeader); httpResponse.setHttpHeader(httpHeader);
httpHeader->setResponseStatus("301"); httpHeader->setStatusCode(301);
try { try {
httpResponse.validateResponse(); httpResponse.validateResponse();
@ -372,7 +372,7 @@ void HttpResponseTest::testValidateResponse_good_range()
request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2"); request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
httpRequest->setRequest(request); httpRequest->setRequest(request);
httpResponse.setHttpRequest(httpRequest); httpResponse.setHttpRequest(httpRequest);
httpHeader->setResponseStatus("206"); httpHeader->setStatusCode(206);
httpHeader->put("Content-Range", "bytes 1048576-10485760/10485760"); httpHeader->put("Content-Range", "bytes 1048576-10485760/10485760");
try { try {
@ -399,7 +399,7 @@ void HttpResponseTest::testValidateResponse_bad_range()
request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2"); request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
httpRequest->setRequest(request); httpRequest->setRequest(request);
httpResponse.setHttpRequest(httpRequest); httpResponse.setHttpRequest(httpRequest);
httpHeader->setResponseStatus("206"); httpHeader->setStatusCode(206);
httpHeader->put("Content-Range", "bytes 0-10485760/10485761"); httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
try { try {
@ -425,7 +425,7 @@ void HttpResponseTest::testValidateResponse_chunked()
request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2"); request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
httpRequest->setRequest(request); httpRequest->setRequest(request);
httpResponse.setHttpRequest(httpRequest); httpResponse.setHttpRequest(httpRequest);
httpHeader->setResponseStatus("206"); httpHeader->setStatusCode(206);
httpHeader->put("Content-Range", "bytes 0-10485760/10485761"); httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
httpHeader->put("Transfer-Encoding", "chunked"); httpHeader->put("Transfer-Encoding", "chunked");
@ -442,7 +442,7 @@ void HttpResponseTest::testValidateResponse_withIfModifiedSince()
HttpResponse httpResponse; HttpResponse httpResponse;
SharedHandle<HttpHeader> httpHeader(new HttpHeader()); SharedHandle<HttpHeader> httpHeader(new HttpHeader());
httpResponse.setHttpHeader(httpHeader); httpResponse.setHttpHeader(httpHeader);
httpHeader->setResponseStatus("304"); httpHeader->setStatusCode(304);
SharedHandle<HttpRequest> httpRequest(new HttpRequest()); SharedHandle<HttpRequest> httpRequest(new HttpRequest());
httpResponse.setHttpRequest(httpRequest); httpResponse.setHttpRequest(httpRequest);
try { try {

View File

@ -48,6 +48,7 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testParseUInt); CPPUNIT_TEST(testParseUInt);
CPPUNIT_TEST(testParseLLInt); CPPUNIT_TEST(testParseLLInt);
CPPUNIT_TEST(testParseULLInt); CPPUNIT_TEST(testParseULLInt);
CPPUNIT_TEST(testParseIntNoThrow);
CPPUNIT_TEST(testParseUIntNoThrow); CPPUNIT_TEST(testParseUIntNoThrow);
CPPUNIT_TEST(testParseLLIntNoThrow); CPPUNIT_TEST(testParseLLIntNoThrow);
CPPUNIT_TEST(testToString_binaryStream); CPPUNIT_TEST(testToString_binaryStream);
@ -106,6 +107,7 @@ public:
void testParseUInt(); void testParseUInt();
void testParseLLInt(); void testParseLLInt();
void testParseULLInt(); void testParseULLInt();
void testParseIntNoThrow();
void testParseUIntNoThrow(); void testParseUIntNoThrow();
void testParseLLIntNoThrow(); void testParseLLIntNoThrow();
void testToString_binaryStream(); void testToString_binaryStream();
@ -828,6 +830,22 @@ void UtilTest::testParseULLInt()
} }
} }
void UtilTest::testParseIntNoThrow()
{
int32_t n;
CPPUNIT_ASSERT(util::parseIntNoThrow(n, " -1 "));
CPPUNIT_ASSERT_EQUAL((int32_t)-1, n);
CPPUNIT_ASSERT(util::parseIntNoThrow(n, "2147483647"));
CPPUNIT_ASSERT_EQUAL((int32_t)2147483647, n);
CPPUNIT_ASSERT(!util::parseIntNoThrow(n, "2147483648"));
CPPUNIT_ASSERT(!util::parseIntNoThrow(n, "-2147483649"));
CPPUNIT_ASSERT(!util::parseIntNoThrow(n, "12x"));
CPPUNIT_ASSERT(!util::parseIntNoThrow(n, ""));
}
void UtilTest::testParseUIntNoThrow() void UtilTest::testParseUIntNoThrow()
{ {
uint32_t n; uint32_t n;