Use nothrow version of parseInt, parseUInt and parseLLInt

pull/28/head
Tatsuhiro Tsujikawa 2012-09-27 00:45:32 +09:00
parent a879d75aaa
commit 89f18dde85
8 changed files with 51 additions and 167 deletions

View File

@ -406,9 +406,10 @@ int FtpConnection::receiveSizeResponse(int64_t& size)
if(response.first == 213) {
std::pair<Sip, Sip> rp;
util::divide(rp, response.second.begin(), response.second.end(), ' ');
size = util::parseLLInt(std::string(rp.second.first, rp.second.second));
if(size < 0) {
throw DL_ABORT_EX("Size must be positive");
if(!util::parseLLIntNoThrow(size, std::string(rp.second.first,
rp.second.second)) ||
size < 0) {
throw DL_ABORT_EX("Size must be positive integer");
}
}
return response.first;

View File

@ -93,9 +93,10 @@ RangeHandle HttpHeader::getRange() const
if(clenStr.empty()) {
return SharedHandle<Range>(new Range());
} else {
int64_t contentLength = util::parseLLInt(clenStr);
if(contentLength < 0) {
throw DL_ABORT_EX("Content-Length must be positive");
int64_t contentLength;
if(!util::parseLLIntNoThrow(contentLength, clenStr) ||
contentLength < 0) {
throw DL_ABORT_EX("Content-Length must be positive integer");
} else if(contentLength > std::numeric_limits<off_t>::max()) {
throw DOWNLOAD_FAILURE_EXCEPTION
(fmt(EX_TOO_LARGE_FILE, contentLength));
@ -135,11 +136,12 @@ RangeHandle HttpHeader::getRange() const
if(minus == slash) {
return SharedHandle<Range>(new Range());
}
int64_t startByte = util::parseLLInt(std::string(byteRangeSpec, minus));
int64_t endByte = util::parseLLInt(std::string(minus+1, slash));
int64_t entityLength =
util::parseLLInt(std::string(slash+1, rangeStr.end()));
if(startByte < 0 || endByte < 0 || entityLength < 0) {
int64_t startByte, endByte, entityLength;
if(!util::parseLLIntNoThrow(startByte, std::string(byteRangeSpec, minus)) ||
!util::parseLLIntNoThrow(endByte, std::string(minus+1, slash)) ||
!util::parseLLIntNoThrow(entityLength,
std::string(slash+1, rangeStr.end())) ||
startByte < 0 || endByte < 0 || entityLength < 0) {
throw DL_ABORT_EX("byte-range-spec must be positive");
}
if(startByte > std::numeric_limits<off_t>::max()) {

View File

@ -154,7 +154,12 @@ NumberOptionHandler::~NumberOptionHandler() {}
void NumberOptionHandler::parseArg(Option& option, const std::string& optarg)
{
parseArg(option, util::parseLLInt(optarg));
int64_t number;
if(util::parseLLIntNoThrow(number, optarg)) {
parseArg(option, number);
} else {
throw DL_ABORT_EX(fmt("Bad number %s", optarg.c_str()));
}
}
void NumberOptionHandler::parseArg(Option& option, int64_t number)

View File

@ -185,7 +185,12 @@ namespace {
a2_gid_t str2Gid(const String* str)
{
assert(str);
return util::parseLLInt(str->s());
int64_t gid;
if(util::parseLLIntNoThrow(gid, str->s())) {
return gid;
} else {
throw DL_ABORT_EX(fmt("Bad GID %s", str->s().c_str()));
}
}
} // namespace

View File

@ -458,7 +458,7 @@ std::string percentDecode
if(*first == '%') {
if(first+1 != last && first+2 != last &&
isHexDigit(*(first+1)) && isHexDigit(*(first+2))) {
result += parseInt(std::string(first+1, first+3), 16);
result += hexCharToUInt(*(first+1))*16+hexCharToUInt(*(first+2));
first += 2;
} else {
result += *first;
@ -596,18 +596,6 @@ bool parseIntNoThrow(int32_t& res, const std::string& s, int base)
}
}
int32_t parseInt(const std::string& s, int base)
{
int32_t res;
if(parseIntNoThrow(res, s, base)) {
return res;
} else {
throw DL_ABORT_EX
(fmt("Failed to convert string into 32bit signed integer. '%s'",
s.c_str()));
}
}
bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base)
{
long int t;
@ -621,18 +609,6 @@ bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base)
}
}
uint32_t parseUInt(const std::string& s, int base)
{
uint32_t res;
if(parseUIntNoThrow(res, s, base)) {
return res;
} else {
throw DL_ABORT_EX
(fmt("Failed to convert string into 32bit unsigned integer. '%s'",
s.c_str()));
}
}
bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base)
{
long long int t;
@ -646,18 +622,6 @@ bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base)
}
}
int64_t parseLLInt(const std::string& s, int base)
{
int64_t res;
if(parseLLIntNoThrow(res, s, base)) {
return res;
} else {
throw DL_ABORT_EX
(fmt("Failed to convert string into 64bit signed integer. '%s'",
s.c_str()));
}
}
void parseIntSegments(SegList<int>& sgl, const std::string& src)
{
for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;) {
@ -668,14 +632,22 @@ void parseIntSegments(SegList<int>& sgl, const std::string& src)
}
std::string::const_iterator p = std::find(i, j, '-');
if(p == j) {
int a = parseInt(std::string(i, j));
sgl.add(a, a+1);
int a;
if(parseIntNoThrow(a, std::string(i, j))) {
sgl.add(a, a+1);
} else {
throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str()));
}
} else if(p == i || p+1 == j) {
throw DL_ABORT_EX(fmt(MSG_INCOMPLETE_RANGE, std::string(i, j).c_str()));
} else {
int a = parseInt(std::string(i, p));
int b = parseInt(std::string(p+1, j));
sgl.add(a, b+1);
int a, b;
if(parseIntNoThrow(a, std::string(i, p)) &&
parseIntNoThrow(b, (std::string(p+1, j)))) {
sgl.add(a, b+1);
} else {
throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str()));
}
}
if(j == eoi) {
break;
@ -1062,10 +1034,10 @@ int64_t getRealSize(const std::string& sizeWithUnit)
}
size.assign(sizeWithUnit.begin(), sizeWithUnit.begin()+p);
}
int64_t v = parseLLInt(size);
if(v < 0) {
throw DL_ABORT_EX(fmt("Negative value detected: %s", sizeWithUnit.c_str()));
int64_t v;
if(!parseLLIntNoThrow(v, size) || v < 0) {
throw DL_ABORT_EX(fmt("Bad or negative value detected: %s",
sizeWithUnit.c_str()));
} else if(INT64_MAX/mult < v) {
throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"overflow/underflow"));
@ -1260,10 +1232,12 @@ parseIndexPath(const std::string& line)
{
std::pair<Scip, Scip> p;
divide(p, line.begin(), line.end(), '=');
size_t index = parseUInt(std::string(p.first.first, p.first.second));
uint32_t index;
if(!parseUIntNoThrow(index, std::string(p.first.first, p.first.second))) {
throw DL_ABORT_EX("Bad path index");
}
if(p.second.first == p.second.second) {
throw DL_ABORT_EX(fmt("Path with index=%u is empty.",
static_cast<unsigned int>(index)));
throw DL_ABORT_EX(fmt("Path with index=%u is empty.", index));
}
return std::make_pair(index, std::string(p.second.first, p.second.second));
}

View File

@ -262,14 +262,11 @@ bool isPowerOf(int num, int base);
std::string secfmt(time_t sec);
bool parseIntNoThrow(int32_t& res, const std::string& s, int base = 10);
int32_t parseInt(const std::string& s, int base = 10);
// Valid range: [0, INT32_MAX]
bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10);
uint32_t parseUInt(const std::string& s, int base = 10);
bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10);
int64_t parseLLInt(const std::string& s, int base = 10);
void parseIntSegments(SegList<int>& sgl, const std::string& src);

View File

@ -28,9 +28,9 @@ void GZipEncoderTest::testEncode()
inputs.push_back("Hello World");
inputs.push_back("9223372036854775807");
inputs.push_back("Fox");
encoder << inputs[0];
encoder << util::parseLLInt(inputs[1]);
encoder << (int64_t)9223372036854775807LL;
encoder << inputs[2].c_str();
std::string gzippedData = encoder.str();

View File

@ -57,9 +57,6 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testConvertBitfield);
CPPUNIT_TEST(testParseIntSegments);
CPPUNIT_TEST(testParseIntSegments_invalidRange);
CPPUNIT_TEST(testParseInt);
CPPUNIT_TEST(testParseUInt);
CPPUNIT_TEST(testParseLLInt);
CPPUNIT_TEST(testParseIntNoThrow);
CPPUNIT_TEST(testParseUIntNoThrow);
CPPUNIT_TEST(testParseLLIntNoThrow);
@ -129,9 +126,6 @@ public:
void testConvertBitfield();
void testParseIntSegments();
void testParseIntSegments_invalidRange();
void testParseInt();
void testParseUInt();
void testParseLLInt();
void testParseIntNoThrow();
void testParseUIntNoThrow();
void testParseLLIntNoThrow();
@ -1259,100 +1253,6 @@ void UtilTest::testParseIntSegments_invalidRange()
}
}
void UtilTest::testParseInt()
{
std::string s;
s = " -1 ";
CPPUNIT_ASSERT_EQUAL(-1, util::parseInt(s));
s = "2147483647";
CPPUNIT_ASSERT_EQUAL(2147483647, util::parseInt(s));
try {
s = "2147483648";
util::parseInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
s = "-2147483649";
util::parseInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
s = "12x";
util::parseInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
s = "";
util::parseInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
}
void UtilTest::testParseUInt()
{
std::string s;
s = " 2147483647 ";
CPPUNIT_ASSERT_EQUAL(2147483647U, util::parseUInt(s));
try {
s = "-1";
util::parseUInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
try {
s = "2147483648";
util::parseUInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
}
}
void UtilTest::testParseLLInt()
{
std::string s;
{
s = " -1 ";
CPPUNIT_ASSERT_EQUAL((int64_t)-1LL, util::parseLLInt(s));
}
{
s = "9223372036854775807";
CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL,
util::parseLLInt(s));
}
try {
s = "9223372036854775808";
util::parseLLInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
std::cerr << e.stackTrace();
}
try {
s = "-9223372036854775809";
util::parseLLInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
std::cerr << e.stackTrace();
}
try {
s = "12x";
util::parseLLInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
std::cerr << e.stackTrace();
}
try {
s = "";
util::parseLLInt(s);
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception& e) {
std::cerr << e.stackTrace();
}
}
void UtilTest::testParseIntNoThrow()
{
std::string s;