Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 1733

Show
Ignore:
Timestamp:
07/06/10 05:34:59 (14 years ago)
Author:
andrei
Message:

Fixed issue in Appender

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/phobos/std/array.d

    r1725 r1733  
    5555            else 
    5656            { 
    5757                e = r.front; 
    5858            } 
    5959            r.popFront; 
    6060        } 
    6161        return result; 
    6262    } 
    6363    else 
    6464    { 
    65         auto a = Appender!(E[])(); 
     65        auto a = appender!(E[])(); 
    6666        foreach (e; r) 
    6767        { 
    6868            a.put(e); 
    6969        } 
    7070        return a.data; 
    7171    } 
    7272    // // 2. Initialize the memory 
    7373    // size_t constructedElements = 0; 
    7474    // scope(failure) 
    7575    // { 
     
    694694        allocateCapacity(); 
    695695    } 
    696696 
    697697    /** 
    698698       Returns the capacity of the array (the maximum number of 
    699699       elements the managed array can accommodate before triggering a 
    700700       reallocation). 
    701701    */ 
    702702    @property ref size_t capacity() 
    703703    { 
    704         enforce(pArray); 
     704        enforce(pArray, "You must initialize Appender by calling the" 
     705                " appender function before using it"); 
    705706        auto p = cast(ubyte*) (pArray.ptr + pArray.length); 
    706707        while (cast(size_t) p & 3) ++p; 
    707708        return *cast(size_t *) p; 
    708709    } 
    709710 
    710711/** 
    711712Returns the managed array. 
    712713 */ 
    713     T[] data() 
     714    @property T[] data() 
    714715    { 
    715716        return cast(typeof(return)) (pArray ? *pArray : null); 
    716717    } 
    717718 
    718719/** 
    719720Appends one item to the managed array. 
    720721 */ 
    721722    void put(U)(U item) if (isImplicitlyConvertible!(U, T) || 
    722723            isSomeChar!T && isSomeChar!U) 
    723724    { 
     725        enforce(pArray, "You must initialize Appender by calling the" 
     726                " appender function before using it"); 
    724727        static if (isSomeChar!T && isSomeChar!U && T.sizeof < U.sizeof) 
    725728        { 
    726729            // must do some transcoding around here 
    727730            Unqual!T[T.sizeof == 1 ? 4 : 2] encoded; 
    728731            auto len = std.utf.encode(encoded, item); 
    729732            put(encoded[0 .. len]); 
    730733        } 
    731734        else 
    732735        { 
    733736            if (!pArray) 
     
    751754            } 
    752755        } 
    753756    } 
    754757 
    755758/** 
    756759Appends an entire range to the managed array. 
    757760 */ 
    758761    void put(Range)(Range items) if (isForwardRange!Range 
    759762            && is(typeof(Appender.init.put(items.front)))) 
    760763    { 
     764        enforce(pArray, "You must initialize Appender by calling the" 
     765                " appender function before using it"); 
    761766        static if (is(typeof(*pArray ~= items))) 
    762767        { 
    763768            if (!pArray) pArray = (new typeof(*pArray)[1]).ptr; 
    764769            *pArray ~= items; 
    765770            allocateCapacity(); 
    766771        } 
    767772        else 
    768773        { 
    769774            //pragma(msg, Range.stringof); 
    770775            // Generic input range 
  • trunk/phobos/std/complex.d

    r1532 r1733  
    502502    auto c = Complex!float(2.0, 2.0); 
    503503    z = c; 
    504504    assert (z == c); 
    505505    assert (z.re == 2.0  &&  z.im == 2.0); 
    506506} 
    507507 
    508508unittest 
    509509{ 
    510510    // Convert to string. 
    511511    auto z1 = Complex!real(0.123456789, 0.123456789); 
    512     Appender!string s1
     512    auto s1 = appender!string()
    513513    z1.toString(s1, "s"); 
    514514    assert (s1.data == "0.123457+0.123457i"); 
    515515 
    516516    auto z2 = z1.conj; 
    517     Appender!string s2
     517    auto s2 = appender!string()
    518518    z2.toString(s2, ".8e"); 
    519519    assert (s2.data == "1.23456789e-01-1.23456789e-01i"); 
    520520} 
    521521 
    522522 
    523523 
    524524 
    525525/*  Fold Complex!(Complex!T) to Complex!T. 
    526526     
    527527    The rationale for this is that just like the real line is a 
  • trunk/phobos/std/conv.d

    r1717 r1733  
    167167    // array-to-string conversion 
    168168    static if (is(S == void[]) 
    169169            || is(S == const(void)[]) || is(S == immutable(void)[])) { 
    170170        auto raw = cast(const(ubyte)[]) s; 
    171171        enforce(raw.length % Char.sizeof == 0, "Alignment mismatch" 
    172172                " in converting a " ~ S.stringof ~ " to a " ~ T.stringof); 
    173173        auto result = new Char[raw.length / Char.sizeof]; 
    174174        memcpy(result.ptr, s.ptr, s.length); 
    175175        return cast(T) result; 
    176176    } else { 
    177         Appender!(Char[]) result
     177        auto result = appender!(Char[])()
    178178        result.put(leftBracket); 
    179179        foreach (i, e; s) { 
    180180            if (i) result.put(separator); 
    181181            result.put(to!T(e)); 
    182182        } 
    183183        result.put(rightBracket); 
    184184        return cast(T) result.data; 
    185185    } 
    186186} 
    187187 
     
    199199/** 
    200200Associative array to string conversion. The left bracket, key-value 
    201201separator, element separator, and right bracket are configurable. 
    202202Each element is printed by calling $(D to!T). 
    203203 */ 
    204204T to(T, S)(S s, in T leftBracket = "[", in T keyval = ":", 
    205205        in T separator = ", ", in T rightBracket = "]") 
    206206if (isAssociativeArray!(S) && isSomeString!(T)) 
    207207{ 
    208208    alias Unqual!(typeof(T.init[0])) Char; 
    209     Appender!(Char[]) result
     209    auto result = appender!(Char[])()
    210210    // hash-to-string conversion 
    211211    result.put(leftBracket); 
    212212    bool first = true; 
    213213    foreach (k, v; s) { 
    214214        if (!first) result.put(separator); 
    215215        else first = false; 
    216216        result.put(to!(T)(k)); 
    217217        result.put(keyval); 
    218218        result.put(to!(T)(v)); 
    219219    } 
     
    264264T to(T, S)(S s, in T left = S.stringof~"(", in T separator = ", ", 
    265265        in T right = ")") 
    266266if (is(S == struct) && isSomeString!(T) && !is(typeof(&S.init.toString))) 
    267267{ 
    268268    Tuple!(FieldTypeTuple!(S)) * t = void; 
    269269    static if ((*t).sizeof == S.sizeof) 
    270270    { 
    271271        // ok, attempt to forge the tuple 
    272272        t = cast(typeof(t)) &s; 
    273273        alias Unqual!(typeof(T.init[0])) Char; 
    274         Appender!(Char[]) app
     274        auto app = appender!(Char[])()
    275275        app.put(left); 
    276276        foreach (i, e; t.field) 
    277277        { 
    278278            if (i > 0) app.put(to!(T)(separator)); 
    279279            app.put(to!(T)(e)); 
    280280        } 
    281281        app.put(right); 
    282282        return cast(T) app.data; 
    283283    } 
    284284    else 
  • trunk/phobos/std/file.d

    r1725 r1733  
    14491449 *    auto dirs = std.file.listdir(args[1]); 
    14501450 * 
    14511451 *    foreach (d; dirs) 
    14521452 *        writefln(d); 
    14531453 * } 
    14541454 * ---- 
    14551455 */ 
    14561456 
    14571457string[] listdir(in char[] pathname) 
    14581458{ 
    1459     Appender!(string[]) result
     1459    auto result = appender!(string[])()
    14601460 
    14611461    bool listing(string filename) 
    14621462    { 
    14631463        result.put(filename); 
    14641464        return true; // continue 
    14651465    } 
    14661466 
    14671467    listdir(pathname, &listing); 
    14681468    return result.data; 
    14691469} 
     
    15091509 *    auto d_source_files = std.file.listdir(args[1], RegExp(r"\.(d|obj)$")); 
    15101510 * 
    15111511 *    foreach (d; d_source_files) 
    15121512 *        writefln(d); 
    15131513 * } 
    15141514 * ---- 
    15151515 */ 
    15161516 
    15171517string[] listdir(in char[] pathname, in char[] pattern) 
    15181518{ 
    1519     Appender!(string[]) result
     1519    auto result = appender!(string[])()
    15201520 
    15211521    bool callback(DirEntry* de) 
    15221522    { 
    15231523        if (de.isdir) 
    15241524            listdir(de.name, &callback); 
    15251525        else 
    15261526        { 
    15271527            if (std.path.fnmatch(de.name, pattern)) 
    15281528                result.put(de.name); 
    15291529        } 
     
    15311531    } 
    15321532 
    15331533    listdir(pathname, &callback); 
    15341534    return result.data; 
    15351535} 
    15361536 
    15371537/** Ditto */ 
    15381538 
    15391539string[] listdir(in char[] pathname, RegExp r) 
    15401540{ 
    1541     Appender!(string[]) result
     1541    auto result = appender!(string[])()
    15421542 
    15431543    bool callback(DirEntry* de) 
    15441544    { 
    15451545        if (de.isdir) 
    15461546            listdir(de.name, &callback); 
    15471547        else 
    15481548        { 
    15491549            if (r.test(de.name)) 
    15501550                result.put(de.name); 
    15511551        } 
  • trunk/phobos/std/format.d

    r1732 r1733  
    16991699            } // end switch 
    17001700        } // end for 
    17011701        enforce(false, text("Incorrect format specifier: ", fmt)); 
    17021702    } 
    17031703} 
    17041704 
    17051705//------------------------------------------------------------------------------ 
    17061706// Writes characters in the format strings up to the first format 
    17071707// specifier and updates the format specifier to remove the written 
    17081708// portion The updated format fmt does not include the '%' 
    1709 private void writeUpToFormatSpec(OutRange, S)(ref OutRange w, ref S fmt) 
     1709private void writeUpToFormatSpec(OutRange, S)(OutRange w, ref S fmt) 
    17101710{ 
    17111711    for (size_t i = 0; i < fmt.length; ++i) 
    17121712    { 
    17131713        if (fmt[i] != '%') continue; 
    17141714        if (fmt[++i] != '%') 
    17151715        { 
    17161716            // spec found, print and bailout 
    17171717            w.put(fmt[0 .. i - 1]); 
    17181718            fmt = fmt[i .. $]; 
    17191719            return; 
     
    17451745    writeUpToFormatSpec(w, fmt); 
    17461746    assert(w.data == "ab%cd%ef" && fmt == "sg%%h%sij"); 
    17471747    writeUpToFormatSpec(w, fmt); 
    17481748    assert(w.data == "ab%cd%efsg%h" && fmt == "sij"); 
    17491749} 
    17501750 
    17511751/* 
    17521752 * Formats an integral number 'arg' according to 'f' and writes it to 
    17531753 * 'w'. 
    17541754 */ 
    1755 private void formatImpl(Writer, D)(ref Writer w, D argx, FormatInfo f) 
     1755private void formatImpl(Writer, D)(Writer w, D argx, FormatInfo f) 
    17561756if (isIntegral!(D)) 
    17571757{ 
    17581758    Unqual!(D) arg = argx; 
    17591759    if (f.spec == 'r') 
    17601760    { 
    17611761        // raw write, skip all else and write the thing 
    17621762        auto begin = cast(const char*) &arg; 
    17631763        if (std.system.endian == Endian.LittleEndian && f.flPlus 
    17641764            || std.system.endian == Endian.BigEndian && f.flDash) 
    17651765        { 
     
    18771877        w.put(digits); 
    18781878    } 
    18791879    // write the spaces to the right if left-align 
    18801880    if (!leftPad) foreach (i ; 0 .. spacesToPrint) w.put(' '); 
    18811881} 
    18821882 
    18831883/* 
    18841884 * Formats a floating point number 'arg' according to 'f' and writes 
    18851885 * it to 'w'. 
    18861886 */ 
    1887 private void formatImpl(Writer, D)(ref Writer w, D obj, FormatInfo f) 
     1887private void formatImpl(Writer, D)(Writer w, D obj, FormatInfo f) 
    18881888if (isFloatingPoint!(D)) 
    18891889{ 
    18901890    if (f.spec == 'r') 
    18911891    { 
    18921892        // raw write, skip all else and write the thing 
    18931893        auto begin = cast(const char*) &obj; 
    18941894        if (std.system.endian == Endian.LittleEndian && f.flPlus 
    18951895            || std.system.endian == Endian.BigEndian && f.flDash) 
    18961896        { 
    18971897            // must swap bytes 
     
    19311931            f.width, 
    19321932            // negative precision is same as no precision specified 
    19331933            f.precision == FormatInfo.UNSPECIFIED ? -1 : f.precision, 
    19341934            obj); 
    19351935    if (n < 0) throw new FormatError("floating point formatting failure"); 
    19361936    w.put(buf[0 .. strlen(buf.ptr)]); 
    19371937} 
    19381938 
    19391939unittest 
    19401940{ 
    1941     Appender!(string) a
     1941    auto a = appender!(string)()
    19421942    immutable real x = 5.5; 
    19431943    FormatInfo f; 
    19441944    formatImpl(a, x, f); 
    19451945    assert(a.data == "5.5"); 
    19461946} 
    19471947 
    19481948/* 
    19491949 * Formats an object of type 'D' according to 'f' and writes it to 
    19501950 * 'w'. The pointer 'arg' is assumed to point to an object of type 
    19511951 * 'D'. 
    19521952 */ 
    1953 private void formatGeneric(Writer, D)(ref Writer w, const(void)* arg, 
     1953private void formatGeneric(Writer, D)(Writer w, const(void)* arg, 
    19541954    FormatInfo f) 
    19551955{ 
    19561956    auto obj = *cast(D*) arg; 
    19571957    static if (is(const(D) == const(void[]))) { 
    19581958        auto s = cast(const char[]) obj; 
    19591959        w.put(s); 
    19601960    } else static if (is(D Original == enum)) { 
    19611961        formatGeneric!(Writer, Original)(w, arg, f); 
    19621962    } else static if (is(D Original == typedef)) { 
    19631963        formatGeneric!(Writer, Original)(w, arg, f); 
     
    21372137string $(D fmt) and writes the result to $(D w). $(D F) must be $(D 
    21382138char), $(D wchar), or $(D dchar). 
    21392139 
    21402140Example: 
    21412141------------------------- 
    21422142import std.c.stdio; 
    21432143import std.format; 
    21442144 
    21452145string myFormat(A...)(A args) 
    21462146{ 
    2147     Appender!(string) writer
     2147    auto writer = appender!string()
    21482148    std.format.formattedWrite(writer, 
    21492149        "%s et %s numeris romanis non sunt", args); 
    21502150    return writer.data; 
    21512151} 
    21522152... 
    21532153int x = 42; 
    21542154assert(myFormat(x, 0) == "42 et 0 numeris romanis non sunt"); 
    21552155------------------------ 
    21562156 
    21572157$(D formattedWrite) supports positional parameter syntax in $(WEB 
    21582158opengroup.org/onlinepubs/009695399/functions/printf.html, POSIX) 
    21592159style.  Example: 
    21602160 
    21612161------------------------- 
    2162 Appender!(string) writer
     2162auto writer = appender!string()
    21632163std.format.formattedWrite(writer, "Date: %2$s %1$s", "October", 5); 
    21642164assert(writer.data == "Date: 5 October"); 
    21652165------------------------ 
    21662166 
    21672167The positional and non-positional styles can be mixed in the same 
    21682168format string. (POSIX leaves this behavior undefined.) The internal 
    21692169counter for non-positional parameters tracks the next parameter after 
    21702170the largest positional parameter already used. 
    21712171 
    21722172Warning: 
    21732173This is the function internally used by writef* but it's still 
    21742174undergoing active development. Do not rely on it. 
    21752175 */ 
    21762176 
    2177 void formattedWrite(Writer, F, A...)(ref Writer w, const(F)[] fmt, A args) 
     2177void formattedWrite(Writer, F, A...)(Writer w, const(F)[] fmt, A args) 
    21782178{ 
    21792179    enum len = args.length; 
    2180     void function(ref Writer, const(void)*, FormatInfo) funs[len] = void; 
     2180    void function(Writer, const(void)*, FormatInfo) funs[len] = void; 
    21812181    const(void)* argsAddresses[len] = void; 
    21822182    foreach (i, arg; args) 
    21832183    { 
    21842184        funs[i] = &formatGeneric!(Writer, typeof(arg)); 
    21852185        argsAddresses[i] = &arg; 
    21862186    } 
    21872187    // Are we already done with formats? Then just dump each parameter in turn 
    21882188    uint currentArg = 0; 
    21892189    for (;;) 
    21902190    { 
     
    22592259            funs[currentArg](w, argsAddresses[currentArg], spec); 
    22602260            ++currentArg; 
    22612261        } 
    22622262    } 
    22632263} 
    22642264 
    22652265/* ======================== Unit Tests ====================================== */ 
    22662266 
    22672267unittest 
    22682268{ 
    2269     auto stream = appender((string*).init); 
     2269    auto stream = appender!string(); 
    22702270    formattedWrite(stream, "%s", 1.1); 
    22712271    assert(stream.data == "1.1", stream.data); 
    22722272} 
    22732273 
    22742274unittest 
    22752275{ 
    2276     auto stream = appender((string*).init); 
     2276    auto stream = appender!string(); 
    22772277    formattedWrite(stream, "%u", 42); 
    22782278    assert(stream.data == "42", stream.data); 
    22792279} 
    22802280 
    22812281unittest 
    22822282{ 
    22832283    // testing raw writes 
    22842284    string s; 
    22852285    auto w = appender(&s); 
    22862286    uint a = 0x02030405; 
  • trunk/phobos/std/json.d

    r1480 r1733  
    123123        auto c2 = peekChar(); 
    124124        static if (!CaseSensitive) c2 = tolower(c2); 
    125125 
    126126        if(c2 != c) return false; 
    127127 
    128128        getChar(); 
    129129        return true; 
    130130    } 
    131131 
    132132    string parseString() { 
    133         Appender!string str
     133        auto str = appender!string()
    134134 
    135135    Next: 
    136136        switch(peekChar()) { 
    137137        case '"': 
    138138            getChar(); 
    139139            break; 
    140140 
    141141        case '\\': 
    142142            getChar(); 
    143143            auto c = getChar(); 
     
    216216            checkChar(']'); 
    217217            break; 
    218218 
    219219        case '"': 
    220220            value.type = JSON_TYPE.STRING; 
    221221            value.str = parseString(); 
    222222            break; 
    223223 
    224224        case '0': .. case '9': 
    225225        case '-': 
    226             Appender!string number
     226            auto number = appender!string()
    227227            bool isFloat; 
    228228 
    229229            void readInteger() { 
    230230                if(!isdigit(c)) error("Digit expected"); 
    231231 
    232232                Next: number.put(c); 
    233233 
    234234                if(isdigit(peekChar())) { 
    235235                    c = getChar(); 
    236236                    goto Next; 
     
    303303    } 
    304304 
    305305    parseValue(&root); 
    306306    return root; 
    307307} 
    308308 
    309309/** 
    310310 Takes a tree of JSON values and returns the serialized string. 
    311311*/ 
    312312string toJSON(in JSONValue* root) { 
    313     Appender!string json
     313    auto json = appender!string()
    314314 
    315315    void toString(string str) { 
    316316        json.put('"'); 
    317317 
    318318        foreach (dchar c; str) { 
    319319            switch(c) { 
    320320            case '"':   json.put("\\\"");   break; 
    321321            case '\\':  json.put("\\\\");   break; 
    322322            case '/':   json.put("\\/");    break; 
    323323            case '\b':  json.put("\\b");    break; 
  • trunk/phobos/std/process.d

    r1725 r1733  
    309309    { 
    310310        result ~= line; 
    311311    } 
    312312    f.close; 
    313313    return result; 
    314314} 
    315315 
    316316version (Windows) string shell(string cmd) 
    317317{ 
    318318    // Generate a random filename 
    319     Appender!string a
     319    auto a = appender!string()
    320320    foreach (ref e; 0 .. 8) 
    321321    { 
    322322        formattedWrite(a, "%x", rndGen.front); 
    323323        rndGen.popFront; 
    324324    } 
    325325    auto filename = a.data; 
    326326    scope(exit) if (exists(filename)) remove(filename); 
    327327    errnoEnforce(system(cmd ~ "> " ~ filename) == 0); 
    328328    return readText(filename); 
    329329} 
  • trunk/phobos/std/regex.d

    r1596 r1733  
    17101710---- 
    17111711 */ 
    17121712    public Captures captures() 
    17131713    { 
    17141714        return Captures(input, pmatch); 
    17151715    } 
    17161716 
    17171717    unittest 
    17181718    { 
    17191719        // @@@BUG@@@ This doesn't work if a client module uses -unittest 
    1720         // Appender!(char[]) app
     1720        // auto app = appender!string()
    17211721        // foreach (m; match("abracadabra", "(.)a(.)")) 
    17221722        // { 
    17231723        //     assert(m.captures.length == 3); 
    17241724        //     foreach (c; m.captures) 
    17251725        //         app.put(c), app.put(';'); 
    17261726        // } 
    17271727        // assert(app.data == "rac;r;c;dab;d;b;"); 
    17281728    } 
    17291729 
    17301730/******************* 
     
    29972997} 
    29982998 
    29992999unittest 
    30003000{ 
    30013001    char[] s1 = ", abc, de,  fg, hi, ".dup; 
    30023002    auto sp2 = splitter(s1, regex(", *")); 
    30033003} 
    30043004 
    30053005String[] split(String)(String input, Regex!(char) rx) 
    30063006{ 
    3007     Appender!(String[]) a
     3007    auto a = appender!(String[])()
    30083008    foreach (e; splitter(input, rx)) 
    30093009    { 
    30103010        a.put(e); 
    30113011    } 
    30123012    return a.data; 
    30133013} 
    30143014 
    30153015unittest 
    30163016{ 
    30173017    auto s1 = ", abc, de,  fg, hi, "; 
     
    33173317        assert(!match(to!(String)("a.B"), r).empty); 
    33183318        assert(!match(to!(String)("A.B"), r).empty); 
    33193319        assert(!match(to!(String)("a.b"), r).empty); 
    33203320    } 
    33213321} 
    33223322 
    33233323template loadFile(Types...) 
    33243324{ 
    33253325    Tuple!(Types)[] loadFile(Char)(string filename, Regex!(Char) rx) 
    33263326    { 
    3327         Appender!(typeof(return)) result
     3327        auto result = appender!(typeof(return))
    33283328        auto f = File(filename); 
    33293329        scope(exit) f.close; 
    33303330        RegexMatch!(Char[]) match; 
    33313331        foreach (line; f.byLine()) 
    33323332        { 
    33333333            match = .match(line, rx); 
    33343334            Tuple!(Types) t; 
    33353335            foreach (i, unused; t.field) 
    33363336            { 
    33373337                t.field[i] = to!(typeof(t.field[i]))(match.captures[i + 1]); 
  • trunk/phobos/std/string.d

    r1725 r1733  
    13171317 
    13181318/************************************** 
    13191319 * Split s[] into an array of words, 
    13201320 * using delim[] as the delimiter. 
    13211321 */ 
    13221322 
    13231323Unqual!(S1)[] split(S1, S2)(S1 s, S2 delim) 
    13241324        if (isSomeString!S1 && isSomeString!S2) 
    13251325{ 
    13261326    Unqual!(S1) us = s; 
    1327     auto app = Appender!(Unqual!(S1)[])(); 
     1327    auto app = appender!(Unqual!(S1)[])(); 
    13281328    foreach (word; std.algorithm.splitter(us, delim)) 
    13291329    { 
    13301330        app.put(word); 
    13311331    } 
    13321332    return app.data; 
    13331333} 
    13341334 
    13351335unittest 
    13361336{ 
    13371337    debug(string) printf("string.split2\n"); 
     
    14011401 
    14021402/************************************** 
    14031403 * Split s[] into an array of lines, 
    14041404 * using CR, LF, or CR-LF as the delimiter. 
    14051405 * The delimiter is not included in the line. 
    14061406 */ 
    14071407 
    14081408S[] splitlines(S)(S s) 
    14091409{ 
    14101410    size_t istart; 
    1411     auto result = Appender!(S[])(); 
     1411    auto result = appender!(S[])(); 
    14121412 
    14131413    foreach (i; 0 .. s.length) 
    14141414    { 
    14151415        immutable c = s[i]; 
    14161416        if (c == '\r' || c == '\n') 
    14171417        { 
    14181418            result.put(s[istart .. i]); 
    14191419            istart = i + 1; 
    14201420            if (c == '\r' && i + 1 < s.length && s[i + 1] == '\n') 
    14211421            { 
  • trunk/phobos/std/xml.d

    r1552 r1733  
    342342 * 
    343343 * Examples: 
    344344 * -------------- 
    345345 * writefln(encode("a > b")); // writes "a &gt; b" 
    346346 * -------------- 
    347347 */ 
    348348S encode(S)(S s, S buffer = null) 
    349349{ 
    350350    string r; 
    351351    size_t lastI; 
    352     if (buffer) buffer.length = 0; 
    353     auto result = appender(&buffer)
     352    if (buffer.length) buffer.length = 0; 
     353    Appender!S result
    354354 
    355355    foreach (i, c; s) 
    356356    { 
    357357        switch (c) 
    358358        { 
    359359        case '&':  r = "&amp;"; break; 
    360360        case '"':  r = "&quot;"; break; 
    361361        case '\'': r = "&apos;"; break; 
    362362        case '<':  r = "&lt;"; break; 
    363363        case '>':  r = "&gt;"; break; 
    364364        default: continue; 
    365365        } 
    366366        // Replace with r 
     367        if (!result.data) 
     368        { 
     369            result = appender(&buffer); 
     370        } 
    367371        result.put(s[lastI .. i]); 
    368372        result.put(r); 
    369373        lastI = i + 1; 
    370374    } 
    371375 
    372376    if (!result.data) return s; 
    373377    result.put(s[lastI .. $]); 
    374378    return result.data; 
    375379} 
    376380