Skip to content

Commit

Permalink
Fixed Issue 1668 std.stream readf can't read int, nan, inf as floats
Browse files Browse the repository at this point in the history
  • Loading branch information
rbanderton committed Feb 16, 2014
1 parent 0e1bd68 commit f476f47
Showing 1 changed file with 87 additions and 11 deletions.
98 changes: 87 additions & 11 deletions std/stream.d
Expand Up @@ -694,8 +694,13 @@ class Stream : InputStream, OutputStream {
string fmt;
int j = 0;
int count = 0, i = 0;
char c = getc();
char c;
bool firstCharacter = true;
while ((j < arguments.length || i < fmt.length) && !eof) {
if(firstCharacter) {
c = getc();
firstCharacter = false;
}
if (fmt.length == 0 || i == fmt.length) {
i = 0;
if (arguments[j] is typeid(char[])) {
Expand Down Expand Up @@ -873,9 +878,9 @@ class Stream : InputStream, OutputStream {
c = getc();
count++;
}
real n = 0;
real r = 0;
while (isDigit(c) && width) {
n = n * 10 + (c - '0');
r = r * 10 + (c - '0');
width--;
c = getc();
count++;
Expand All @@ -886,13 +891,13 @@ class Stream : InputStream, OutputStream {
count++;
double frac = 1;
while (isDigit(c) && width) {
n = n * 10 + (c - '0');
r = r * 10 + (c - '0');
frac *= 10;
width--;
c = getc();
count++;
}
n /= frac;
r /= frac;
}
if (width && (c == 'e' || c == 'E')) {
width--;
Expand All @@ -919,24 +924,56 @@ class Stream : InputStream, OutputStream {
}
if (expneg) {
while (exp--)
n /= 10;
r /= 10;
} else {
while (exp--)
n *= 10;
r *= 10;
}
}
}
if(width && (c == 'n' || c == 'N')) {
width--;
c = getc();
count++;
if(width && (c == 'a' || c == 'A')) {
width--;
c = getc();
count++;
if(width && (c == 'n' || c == 'N')) {
width--;
c = getc();
count++;
r = real.nan;
}
}
}
if(width && (c == 'i' || c == 'I')) {
width--;
c = getc();
count++;
if(width && (c == 'n' || c == 'N')) {
width--;
c = getc();
count++;
if(width && (c == 'f' || c == 'F')) {
width--;
c = getc();
count++;
r = real.infinity;
}
}
}
if (neg)
n = -n;
r = -r;
if (arguments[j] is typeid(float*)) {
float* p = va_arg!(float*)(args);
*p = n;
*p = r;
} else if (arguments[j] is typeid(double*)) {
double* p = va_arg!(double*)(args);
*p = n;
*p = r;
} else if (arguments[j] is typeid(real*)) {
real* p = va_arg!(real*)(args);
*p = n;
*p = r;
}
j++;
i++;
Expand Down Expand Up @@ -1400,6 +1437,45 @@ class Stream : InputStream, OutputStream {
if (!seekable)
throw new SeekException("Stream is not seekable");
}

unittest { //unit tests for Issue 1668
void tryFloatRoundtrip(float x, string fmt = "", string pad = "") {
auto s = new MemoryStream();
s.writef(fmt, x, pad);
s.position = 0;

float f;
assert(s.readf(&f));
assert(x == f || (x != x && f != f)); //either equal or both NaN
}

tryFloatRoundtrip(1.0);
tryFloatRoundtrip(1.0, "%f");
tryFloatRoundtrip(1.0, "", " ");
tryFloatRoundtrip(1.0, "%f", " ");

tryFloatRoundtrip(3.14);
tryFloatRoundtrip(3.14, "%f");
tryFloatRoundtrip(3.14, "", " ");
tryFloatRoundtrip(3.14, "%f", " ");

float nan = float.nan;
tryFloatRoundtrip(nan);
tryFloatRoundtrip(nan, "%f");
tryFloatRoundtrip(nan, "", " ");
tryFloatRoundtrip(nan, "%f", " ");

float inf = 1.0/0.0;
tryFloatRoundtrip(inf);
tryFloatRoundtrip(inf, "%f");
tryFloatRoundtrip(inf, "", " ");
tryFloatRoundtrip(inf, "%f", " ");

tryFloatRoundtrip(-inf);
tryFloatRoundtrip(-inf,"%f");
tryFloatRoundtrip(-inf, "", " ");
tryFloatRoundtrip(-inf, "%f", " ");
}
}

/***
Expand Down

0 comments on commit f476f47

Please sign in to comment.