Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -458,10 +458,26 @@ * * \return A uintmax_t with the value of the string */ - (uintmax_t)hexadecimalValue; +/** + * Returns the float value of the string as a float or throws an + * OFInvalidEncodingException if the string contains any non-number characters. + * + * \return A float with the value of the string + */ +- (float)floatValue; + +/** + * Returns the double value of the string as a float or throws an + * OFInvalidEncodingException if the string contains any non-number characters. + * + * \return A double with the value of the string + */ +- (double)doubleValue; + /** * Returns the string as an array of of_unichar_t. The result needs to be * free()'d by the caller, as the memory is not marked as belonging to the * object. * Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -1350,10 +1350,58 @@ if (!gotNumber) @throw [OFInvalidFormatException newWithClass: isa]; return num; } + +- (float)floatValue +{ + const char *str = string; + char *endptr; + float value; + + /* Don't depend on isspace and thus the used locale */ + while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r') + str++; + + value = strtof(str, &endptr); + + /* Check if there are any invalid chars left */ + if (endptr != NULL) { + for (; *endptr != '\0'; endptr++) + if (*endptr != ' ' && *endptr != '\t' && + *endptr != '\n' && *endptr != '\r') + @throw [OFInvalidFormatException + newWithClass: isa]; + } + + return value; +} + +- (double)doubleValue +{ + const char *str = string; + char *endptr; + double value; + + /* Don't depend on isspace and thus the used locale */ + while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r') + str++; + + value = strtod(str, &endptr); + + /* Check if there are any invalid chars left */ + if (endptr != NULL) { + for (; *endptr != '\0'; endptr++) + if (*endptr != ' ' && *endptr != '\t' && + *endptr != '\n' && *endptr != '\r') + @throw [OFInvalidFormatException + newWithClass: isa]; + } + + return value; +} - (of_unichar_t*)unicodeString { of_unichar_t *ret; size_t i, j, len; Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -16,10 +16,11 @@ #include "config.h" #include #include +#include #import "OFString.h" #import "OFArray.h" #import "OFURL.h" #import "OFAutoreleasePool.h" @@ -293,10 +294,25 @@ [@" xbCDE" hexadecimalValue] == 0xBCDE && [@"$CdEf" hexadecimalValue] == 0xCDEF && [@"\rFeh " hexadecimalValue] == 0xFE && [@"\r\t" hexadecimalValue] == 0) + /* + * These test numbers can be generated without rounding if we have IEEE + * floating point numbers, thus we can use == on then. + */ + TEST(@"-[floatValue]", + [@"\t-0.25 " floatValue] == -0.25 && + [@"\r-INFINITY\n" floatValue] == -INFINITY && + isnan([@" NAN\t\t" floatValue])) + + TEST(@"-[doubleValue]", + [@"\t-0.000000059604644775390625 " doubleValue] == + -0.000000059604644775390625L && + [@"\r-INFINITY\n" doubleValue] == -INFINITY && + isnan([@" NAN\t\t" doubleValue])) + EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #1", OFInvalidFormatException, [@"abc" decimalValue]) EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #2", OFInvalidFormatException, [@"0a" decimalValue]) EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #3", @@ -308,10 +324,24 @@ OFInvalidFormatException, [@"0x" hexadecimalValue]) EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #3", OFInvalidFormatException, [@"$" hexadecimalValue]) EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #4", OFInvalidFormatException, [@"$ " hexadecimalValue]) + + EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #1", + OFInvalidFormatException, [@"0,0" floatValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #2", + OFInvalidFormatException, [@"0.0a" floatValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #3", + OFInvalidFormatException, [@"0 0" floatValue]) + + EXPECT_EXCEPTION(@"Detect invalid chars in -[doubleValue] #1", + OFInvalidFormatException, [@"0,0" floatValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[doubleValue] #2", + OFInvalidFormatException, [@"0.0a" floatValue]) + EXPECT_EXCEPTION(@"Detect invalid chars in -[doubleValue] #3", + OFInvalidFormatException, [@"0 0" floatValue]) EXPECT_EXCEPTION(@"Detect out of range in -[decimalValue]", OFOutOfRangeException, [@"12345678901234567890123456789012345678901234567890" @"12345678901234567890123456789012345678901234567890"