mirror of
https://github.com/dlang/phobos.git
synced 2025-05-07 19:49:36 +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;
|
import std.conv : parse, text;
|
||||||
if (spec.spec == 's')
|
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,
|
enforce(find(acceptedSpecs!long, spec.spec).length,
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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',
|
enforce(spec.spec == 's',
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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)
|
T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
||||||
if (isInputRange!Range && isIntegral!T && !is(T == enum))
|
if (isInputRange!Range && isIntegral!T && !is(T == enum))
|
||||||
{
|
{
|
||||||
|
|
||||||
import std.algorithm.searching : find;
|
import std.algorithm.searching : find;
|
||||||
import std.conv : parse, text;
|
import std.conv : parse, text;
|
||||||
enforce(find(acceptedSpecs!T, spec.spec).length,
|
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 == 'b' ? 2 :
|
||||||
spec.spec == 's' || spec.spec == 'd' || spec.spec == 'u' ? 10 : 0;
|
spec.spec == 's' || spec.spec == 'd' || spec.spec == 'u' ? 10 : 0;
|
||||||
assert(base != 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.algorithm.searching : find;
|
||||||
import std.conv : parse, text;
|
import std.conv : parse, text;
|
||||||
if (spec.spec == 'r')
|
|
||||||
{
|
|
||||||
// raw read
|
// raw read
|
||||||
//enforce(input.length >= T.sizeof);
|
//enforce(input.length >= T.sizeof);
|
||||||
enforce(
|
if (spec.spec == 'r') return rawReadWrapper!T(input);
|
||||||
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;
|
|
||||||
}
|
|
||||||
enforce(find(acceptedSpecs!T, spec.spec).length,
|
enforce(find(acceptedSpecs!T, spec.spec).length,
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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
|
version(none)unittest
|
||||||
|
@ -4600,7 +4632,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
||||||
enforce(spec.spec == 's',
|
enforce(spec.spec == 's',
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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
|
@system pure unittest
|
||||||
|
@ -4694,7 +4726,7 @@ T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!Char spec)
|
||||||
enforce(spec.spec == 's',
|
enforce(spec.spec == 's',
|
||||||
text("Wrong unformat specifier '%", spec.spec , "' for ", T.stringof));
|
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
|
@system pure unittest
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue