Changeset 505

Show
Ignore:
Timestamp:
11/19/07 00:00:50 (1 year ago)
Author:
andrei
Message:

Added raw ('r') format specifier for formatted writing

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • candidate/phobos/std/format.d

    r440 r505  
    4848import std.typetuple; 
    4949import std.stdio; // for debugging only 
     50import std.contracts; 
     51import std.system; 
    5052 
    5153version (Windows) 
     
    7880class FormatError : Error 
    7981{ 
    80   private: 
    81  
    8282    this() 
    8383    { 
     
    17741774private void formatIntegral(Writer, D)(ref Writer w, D arg, FormatInfo f) 
    17751775{ 
     1776    if (f.spec == 'r') 
     1777    { 
     1778        // raw write, skip all else and write the thing 
     1779        auto begin = cast(const char*) &arg; 
     1780        if (std.system.endian == Endian.LittleEndian && f.flPlus 
     1781            || std.system.endian == Endian.BigEndian && f.flDash) 
     1782        { 
     1783            // must swap bytes 
     1784            foreach_reverse (i; 0 .. arg.sizeof) 
     1785                w.putchar(begin[i]); 
     1786        } 
     1787        else 
     1788        { 
     1789            foreach (i; 0 .. arg.sizeof) 
     1790                w.putchar(begin[i]); 
     1791        } 
     1792        return; 
     1793    } 
    17761794    if (f.precision == f.precision.max - 1) 
    17771795    { 
     
    18861904private void formatFloat(Writer, D)(ref Writer w, D obj, FormatInfo f) 
    18871905{ 
    1888   if (std.string.find("fgFGaAeEs", f.spec) < 0) { 
    1889     throw new FormatError("floating"); 
    1890   } 
    1891   if (f.spec == 's') f.spec = 'g'; 
    1892   char sprintfSpec[1 /*%*/ + 5 /*flags*/ + 3 /*width.prec*/ + 2 /*format*/ 
    1893       + 1 /*\0*/] = void; 
    1894   sprintfSpec[0] = '%'; 
    1895   uint i = 1; 
    1896   if (f.flDash) sprintfSpec[i++] = '-'; 
    1897   if (f.flPlus) sprintfSpec[i++] = '+'; 
    1898   if (f.flZero) sprintfSpec[i++] = '0'; 
    1899   if (f.flSpace) sprintfSpec[i++] = ' '; 
    1900   if (f.flHash) sprintfSpec[i++] = '#'; 
    1901   sprintfSpec[i .. i + 3] = "*.*"; 
    1902   i += 3; 
    1903   if (is(D == real)) sprintfSpec[i++] = 'L'; 
    1904   sprintfSpec[i++] = f.spec; 
    1905   sprintfSpec[i] = 0; 
    1906   //writeln(sprintfSpec); 
    1907   char[512] buf; 
    1908   final n = snprintf(buf.ptr, buf.length, 
    1909       sprintfSpec.ptr, 
    1910       f.width, 
    1911       // negative precision is same as no precision specified 
    1912       f.precision == f.precision.max - 1 ? -1 : f.precision, 
    1913       obj); 
    1914   if (n < 0) throw new FormatError("floating point formatting failure"); 
    1915   w.write(buf[0 .. strlen(buf.ptr)]); 
     1906    if (f.spec == 'r') 
     1907    { 
     1908        // raw write, skip all else and write the thing 
     1909        auto begin = cast(const char*) &obj; 
     1910        if (std.system.endian == Endian.LittleEndian && f.flPlus 
     1911            || std.system.endian == Endian.BigEndian && f.flDash) 
     1912        { 
     1913            // must swap bytes 
     1914            foreach_reverse (i; 0 .. obj.sizeof) 
     1915                w.putchar(begin[i]); 
     1916        } 
     1917        else 
     1918        { 
     1919            foreach (i; 0 .. obj.sizeof) 
     1920                w.putchar(begin[i]); 
     1921        } 
     1922        return; 
     1923    } 
     1924    if (std.string.find("fgFGaAeEs", f.spec) < 0) { 
     1925        throw new FormatError("floating"); 
     1926    } 
     1927    if (f.spec == 's') f.spec = 'g'; 
     1928    char sprintfSpec[1 /*%*/ + 5 /*flags*/ + 3 /*width.prec*/ + 2 /*format*/ 
     1929                     + 1 /*\0*/] = void; 
     1930    sprintfSpec[0] = '%'; 
     1931    uint i = 1; 
     1932    if (f.flDash) sprintfSpec[i++] = '-'; 
     1933    if (f.flPlus) sprintfSpec[i++] = '+'; 
     1934    if (f.flZero) sprintfSpec[i++] = '0'; 
     1935    if (f.flSpace) sprintfSpec[i++] = ' '; 
     1936    if (f.flHash) sprintfSpec[i++] = '#'; 
     1937    sprintfSpec[i .. i + 3] = "*.*"; 
     1938    i += 3; 
     1939    if (is(D == real)) sprintfSpec[i++] = 'L'; 
     1940    sprintfSpec[i++] = f.spec; 
     1941    sprintfSpec[i] = 0; 
     1942    //writeln(sprintfSpec); 
     1943    char[512] buf; 
     1944    final n = snprintf(buf.ptr, buf.length, 
     1945                       sprintfSpec.ptr, 
     1946                       f.width, 
     1947                       // negative precision is same as no precision specified 
     1948                       f.precision == f.precision.max - 1 ? -1 : f.precision, 
     1949                       obj); 
     1950    if (n < 0) throw new FormatError("floating point formatting failure"); 
     1951    w.write(buf[0 .. strlen(buf.ptr)]); 
    19161952} 
    19171953 
     
    20032039 
    20042040//------------------------------------------------------------------------------- 
     2041// Fix for issue 1591 
    20052042private int getNthInt(A...)(uint index, A args) 
    20062043{ 
    2007     foreach (i, arg; args
    2008     { 
    2009         static if (is(typeof(arg) : long) || is(typeof(arg) : ulong)
     2044    static if (A.length
     2045    { 
     2046        if (index
    20102047        { 
    2011             if (i != index) continue; 
    2012             return to!(int)(arg); 
     2048            return getNthInt(index - 1, args[1 .. $]);  
     2049        } 
     2050        static if (is(typeof(args[0]) : long) || is(typeof(arg) : ulong)) 
     2051        { 
     2052            return to!(int)(args[0]); 
    20132053        } 
    20142054        else 
    20152055        { 
    2016             if (i == index) break
     2056            throw new FormatError("int expected")
    20172057        } 
    20182058    } 
    2019     throw new FormatError("int expected"); 
     2059    else 
     2060    { 
     2061        throw new FormatError("int expected"); 
     2062    } 
    20202063} 
    20212064 
     
    21432186 
    21442187/* ======================== Unit Tests ====================================== */ 
     2188 
     2189unittest 
     2190{ 
     2191    // testing raw writes 
     2192    StringWriter!(char) w; 
     2193    w.backend = null; 
     2194    uint a = 0x02030405; 
     2195    formattedWrite(w, "%+r", a); 
     2196    assert(w.backend.length == 4 && w.backend[0] == 2 && w.backend[1] == 3 
     2197        && w.backend[2] == 4 && w.backend[3] == 5); 
     2198    w.backend = null; 
     2199    formattedWrite(w, "%-r", a); 
     2200    assert(w.backend.length == 4 && w.backend[0] == 5 && w.backend[1] == 4 
     2201        && w.backend[2] == 3 && w.backend[3] == 2); 
     2202} 
    21452203 
    21462204unittest