mirror of
https://github.com/dlang/phobos.git
synced 2025-05-06 11:07:39 +03:00
Issue 5236 - [patch] std.format.formattedRead/unformatValue does not support the raw reading of integer types
This commit is contained in:
parent
f6b4e89d64
commit
17d13e2066
1 changed files with 68 additions and 36 deletions
104
std/format.d
104
std/format.d
|
@ -4302,7 +4302,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
|||
import std.conv : parse, text;
|
||||
if (spec.spec == 's')
|
||||
{
|
||||
return parse!T(input);
|
||||
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
|
||||
}
|
||||
enforce(find(acceptedSpecs!long, spec.spec).length,
|
||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
||||
|
@ -4359,7 +4359,38 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
|||
enforce(spec.spec == 's',
|
||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
||||
|
||||
return parse!T(input);
|
||||
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
|
||||
}
|
||||
|
||||
private T rawReadWrapper(T, Range)(ref Range input)
|
||||
{
|
||||
enforce(
|
||||
isSomeString!Range || ElementType!(Range).sizeof == 1,
|
||||
"Cannot parse input of type %s".format(Range.stringof)
|
||||
);
|
||||
union X
|
||||
{
|
||||
ubyte[T.sizeof] raw;
|
||||
T typed;
|
||||
}
|
||||
X x;
|
||||
foreach (i; 0 .. T.sizeof)
|
||||
{
|
||||
static if (isSomeString!Range)
|
||||
{
|
||||
x.raw[i] = input[0];
|
||||
input = input[1 .. $];
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: recheck this
|
||||
x.raw[i] = cast(ubyte) input.front;
|
||||
input.popFront();
|
||||
}
|
||||
}
|
||||
|
||||
return x.typed;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4368,6 +4399,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
|||
T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
||||
if (isInputRange!Range && isIntegral!T && !is(T == enum))
|
||||
{
|
||||
|
||||
import std.algorithm.searching : find;
|
||||
import std.conv : parse, text;
|
||||
enforce(find(acceptedSpecs!T, spec.spec).length,
|
||||
|
@ -4381,7 +4413,31 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
|||
spec.spec == 'b' ? 2 :
|
||||
spec.spec == 's' || spec.spec == 'd' || spec.spec == 'u' ? 10 : 0;
|
||||
assert(base != 0);
|
||||
return parse!T(input, base);
|
||||
|
||||
// raw read
|
||||
//enforce(input.length >= T.sizeof);
|
||||
if (spec.spec == 'r') return rawReadWrapper!T(input);
|
||||
|
||||
enforce(find(acceptedSpecs!T, spec.spec).length,
|
||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
||||
|
||||
static if(__traits(compiles, parse!T(input, base)) ) return parse!T(input, base);
|
||||
|
||||
}
|
||||
|
||||
version(none)unittest
|
||||
{
|
||||
union B
|
||||
{
|
||||
char[int.sizeof] untyped;
|
||||
int typed;
|
||||
}
|
||||
B b;
|
||||
b.typed = 5;
|
||||
char[] input = b.untyped[];
|
||||
int witness;
|
||||
formattedRead(input, "%r", &witness);
|
||||
assert(witness == b.typed);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4392,40 +4448,16 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
|||
{
|
||||
import std.algorithm.searching : find;
|
||||
import std.conv : parse, text;
|
||||
if (spec.spec == 'r')
|
||||
{
|
||||
// raw read
|
||||
//enforce(input.length >= T.sizeof);
|
||||
enforce(
|
||||
isSomeString!Range || ElementType!(Range).sizeof == 1,
|
||||
"Cannot parse input of type %s".format(Range.stringof)
|
||||
);
|
||||
union X
|
||||
{
|
||||
ubyte[T.sizeof] raw;
|
||||
T typed;
|
||||
}
|
||||
X x;
|
||||
foreach (i; 0 .. T.sizeof)
|
||||
{
|
||||
static if (isSomeString!Range)
|
||||
{
|
||||
x.raw[i] = input[0];
|
||||
input = input[1 .. $];
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: recheck this
|
||||
x.raw[i] = cast(ubyte) input.front;
|
||||
input.popFront();
|
||||
}
|
||||
}
|
||||
return x.typed;
|
||||
}
|
||||
|
||||
|
||||
// raw read
|
||||
//enforce(input.length >= T.sizeof);
|
||||
if (spec.spec == 'r') return rawReadWrapper!T(input);
|
||||
|
||||
enforce(find(acceptedSpecs!T, spec.spec).length,
|
||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
||||
|
||||
return parse!T(input);
|
||||
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
|
||||
}
|
||||
|
||||
version(none)unittest
|
||||
|
@ -4600,7 +4632,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
|||
enforce(spec.spec == 's',
|
||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
||||
|
||||
return parse!T(input);
|
||||
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
|
||||
}
|
||||
|
||||
@system pure unittest
|
||||
|
@ -4694,7 +4726,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
|||
enforce(spec.spec == 's',
|
||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
||||
|
||||
return parse!T(input);
|
||||
static if(__traits(compiles, parse!T(input)) ) return parse!T(input);
|
||||
}
|
||||
|
||||
@system pure unittest
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue