text: // Copyright 2006 Google Inc. All Rights Reserved.
  // Authors: Numerous. Principal maintainers are csilvers and zunger.
  //
  // This is a grab-bag file for string utilities involved in escaping and
  // unescaping strings in various ways. Who knew there were so many?
  //
  // There are more escaping functions in:
  //   webutil/html/tagutils.h (Escaping strings for HTML, PRE, JavaScript, etc.)
  //   webutil/url/url.h (Escaping for URL's, both RFC-2396 and other methods)
  //   template/template_modifiers.h (All sorts of stuff)
  //   util/regex/re2/re2.h (Escaping for literals within regular expressions
  //                         - see RE2::QuoteMeta).
  // And probably many more places, as well.
  
  #ifndef STRINGS_ESCAPING_H_
  #define STRINGS_ESCAPING_H_
  
  #include <stddef.h>
  #include <string>
  using std::string;
  #include <vector>
  using std::vector;
  
  
  #include "base/logging.h"
  #include "strings/ascii_ctype.h"
  #include "strings/charset.h"
  #include "strings/stringpiece.h"
  
  namespace strings {
  
  // ----------------------------------------------------------------------
  // EscapeStrForCSV()
  //    Escapes the quotes in 'src' by doubling them. This is necessary
  //    for generating CSV files (see SplitCSVLine).
  //    Returns the number of characters written into dest (not counting
  //    the \0) or -1 if there was insufficient space.
  //
  //    Example: [some "string" to test] --> [some ""string"" to test]
  // ----------------------------------------------------------------------
  int EscapeStrForCSV(const char* src, char* dest, int dest_len);
  
  // ----------------------------------------------------------------------
  // UnescapeCEscapeSequences()
  //    Copies "source" to "dest", rewriting C-style escape sequences
  //    -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII
  //    equivalents.  "dest" must be sufficiently large to hold all
  //    the characters in the rewritten string (i.e. at least as large
  //    as strlen(source) + 1 should be safe, since the replacements
  //    are always shorter than the original escaped sequences).  It's
  //    safe for source and dest to be the same.  RETURNS the length
  //    of dest.
  //
  //    It allows hex sequences \xhh, or generally \xhhhhh with an
  //    arbitrary number of hex digits, but all of them together must
  //    specify a value of a single byte (e.g. \x0045 is equivalent
  //    to \x45, and \x1234 is erroneous). If the value is too large,
  //    it is truncated to 8 bits and an error is set. This is also
  //    true of octal values that exceed 0xff.
  //
  //    It also allows escape sequences of the form \uhhhh (exactly four
  //    hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight
  //    hex digits, upper or lower case) to specify a Unicode code
  //    point. The dest array will contain the UTF8-encoded version of
  //    that code-point (e.g., if source contains \u2019, then dest will
  //    contain the three bytes 0xE2, 0x80, and 0x99). For the inverse
  //    transformation, use UniLib::UTF8EscapeString
  //    (util/utf8/public/unilib.h), not CEscapeString.
  //
  //    Errors: In the first form of the call, errors are reported with
  //    LOG(ERROR). The same is true for the second form of the call if
  //    the pointer to the string vector is NULL; otherwise, error
  //    messages are stored in the vector. In either case, the effect on
  //    the dest array is not defined, but rest of the source will be
  //    processed.
  //
  //    *** DEPRECATED: Use CUnescape() in new code ***
  //    ----------------------------------------------------------------------
  int UnescapeCEscapeSequences(const char* source, char* dest);
  int UnescapeCEscapeSequences(const char* source, char* dest,
                               vector<string>* errors);
  
  // ----------------------------------------------------------------------
  // UnescapeCEscapeString()
  //    This does the same thing as UnescapeCEscapeSequences, but creates
  //    a new string. The caller does not need to worry about allocating
  //    a dest buffer. This should be used for non performance critical
  //    tasks such as printing debug messages. It is safe for src and dest
  //    to be the same.
  //
  //    The second call stores its errors in a supplied string vector.
  //    If the string vector pointer is NULL, it reports the errors with LOG().
  //
  //    In the first and second calls, the length of dest is returned. In the
  //    the third call, the new string is returned.
  //
  //    *** DEPRECATED: Use CUnescape() in new code ***
  // ----------------------------------------------------------------------
  int UnescapeCEscapeString(const string& src, string* dest);
  int UnescapeCEscapeString(const string& src, string* dest,
                            vector<string>* errors);
  string UnescapeCEscapeString(const string& src);
  
  // ----------------------------------------------------------------------
  // CUnescape()
  //    Copies "source" to "dest", rewriting C-style escape sequences
  //    -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII
  //    equivalents.  "dest" must be sufficiently large to hold all
  //    the characters in the rewritten string (i.e. at least as large
  //    as source.size() should be safe, since the replacements
  //    are never longer than the original escaped sequences).  It's
  //    safe for source and dest to be the same.  RETURNS true if
  //    conversion was successful, false otherwise. Stores the size of
  //    the result in 'dest_len'.
  //
  //    It allows hex sequences \xhh, or generally \xhhhhh with an
  //    arbitrary number of hex digits, but all of them together must
  //    specify a value of a single byte (e.g. \x0045 is equivalent
  //    to \x45, and \x1234 is erroneous). If the value is too large,
  //    an error is set. This is also true of octal values that exceed 0xff.
  //
  //    It also allows escape sequences of the form \uhhhh (exactly four
  //    hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight
  //    hex digits, upper or lower case) to specify a Unicode code
  //    point. The dest array will contain the UTF8-encoded version of
  //    that code-point (e.g., if source contains \u2019, then dest will
  //    contain the three bytes 0xE2, 0x80, and 0x99). For the inverse
  //    transformation, use UniLib::UTF8EscapeString
  //    (util/utf8/public/unilib.h), not CEscapeString.
  //
  //    Errors: Sets the description of the first encountered error in
  //    'error'. To disable error reporting, set 'error' to NULL.
  // ----------------------------------------------------------------------
  bool CUnescape(const StringPiece& source, char* dest, int* dest_len,
                 string* error);
  
  bool CUnescape(const StringPiece& source, string* dest, string* error);
  
  // A version with no error reporting.
  inline bool CUnescape(const StringPiece& source, string* dest) {
    return CUnescape(source, dest, NULL);
  }
  
  // ----------------------------------------------------------------------
  // CUnescapeForNullTerminatedString()
  //
  // This has the same behavior as CUnescape, except that each octal, hex,
  // or Unicode escape sequence that resolves to a null character ('\0')
  // is left in its original escaped form.  The result is a
  // display-formatted string that can be interpreted as a null-terminated
  // const char* and will not be cut short if it contains embedded null
  // characters.
  //
  // ----------------------------------------------------------------------
  
  bool CUnescapeForNullTerminatedString(const StringPiece& source,
                                        char* dest,
                                        int* dest_len,
                                        string* error);
  
  bool CUnescapeForNullTerminatedString(const StringPiece& source,
                                        string* dest,
                                        string* error);
  
  // A version with no error reporting.
  inline bool CUnescapeForNullTerminatedString(const StringPiece& source,
                                               string* dest) {
    return CUnescapeForNullTerminatedString(source, dest, NULL);
  }
  
  // ----------------------------------------------------------------------
  // CEscapeString()
  // CHexEscapeString()
  // Utf8SafeCEscapeString()
  // Utf8SafeCHexEscapeString()
  //    Copies 'src' to 'dest', escaping dangerous characters using
  //    C-style escape sequences. This is very useful for preparing query
  //    flags. 'src' and 'dest' should not overlap. The 'Hex' version uses
  //    hexadecimal rather than octal sequences. The 'Utf8Safe' version
  //    doesn't touch UTF-8 bytes.
  //    Returns the number of bytes written to 'dest' (not including the \0)
  //    or -1 if there was insufficient space.
  //
  //    Currently only \n, \r, \t, ", ', \ and !ascii_isprint() chars are escaped.
  // ----------------------------------------------------------------------
  int CEscapeString(const char* src, int src_len, char* dest, int dest_len);
  int CHexEscapeString(const char* src, int src_len, char* dest, int dest_len);
  int Utf8SafeCEscapeString(const char* src, int src_len, char* dest,
                            int dest_len);
  int Utf8SafeCHexEscapeString(const char* src, int src_len, char* dest,
                               int dest_len);
  
  // ----------------------------------------------------------------------
  // CEscape()
  // CHexEscape()
  // Utf8SafeCEscape()
  // Utf8SafeCHexEscape()
  //    More convenient form of CEscapeString: returns result as a "string".
  //    This version is slower than CEscapeString() because it does more
  //    allocation.  However, it is much more convenient to use in
  //    non-speed-critical code like logging messages etc.
  // ----------------------------------------------------------------------
  string CEscape(const StringPiece& src);
  string CHexEscape(const StringPiece& src);
  string Utf8SafeCEscape(const StringPiece& src);
  string Utf8SafeCHexEscape(const StringPiece& src);
  
  // ----------------------------------------------------------------------
  // BackslashEscape()
  //    Given a string and a list of characters to escape, replace any
  //    instance of one of those characters with \ + that character. For
  //    example, when exporting maps to /varz, label values need to have
  //    all dots escaped. Appends the result to dest.
  // BackslashUnescape()
  //    Replace \ + any of the indicated "unescape me" characters with just
  //    that character. Appends the result to dest.
  //
  //    IMPORTANT:
  //    This function does not escape \ by default, so if you do not include
  //    it in the chars to escape you will most certainly get an undesirable
  //    result. That is, it won't be a reversible operation:
  //      string src = "foo\\:bar";
  //      BackslashUnescape(BackslashEscape(src, ":"), ":") == "foo\\\\:bar"
  //    On the other hand, for all strings "src", the following is true:
  //      BackslashUnescape(BackslashEscape(src, ":\\"), ":\\") == src
  // ----------------------------------------------------------------------
  void BackslashEscape(const StringPiece& src,
                       const strings::CharSet& to_escape,
                       string* dest);
  void BackslashUnescape(const StringPiece& src,
                         const strings::CharSet& to_unescape,
                         string* dest);
  
  inline string BackslashEscape(const StringPiece& src,
                                const strings::CharSet& to_escape) {
    string s;
    BackslashEscape(src, to_escape, &s);
    return s;
  }
  
  inline string BackslashUnescape(const StringPiece& src,
                                  const strings::CharSet& to_unescape) {
    string s;
    BackslashUnescape(src, to_unescape, &s);
    return s;
  }
  
  // ----------------------------------------------------------------------
  // QuotedPrintableUnescape()
  //    Check out http://www.ietf.org/rfc/rfc2045.txt for more details,
  //    only briefly implemented. But from the web...
  //    Quoted-printable is an encoding method defined in the MIME
  //    standard. It is used primarily to encode 8-bit text (such as text
  //    that includes foreign characters) into 7-bit US ASCII, creating a
  //    document that is mostly readable by humans, even in its encoded
  //    form. All MIME compliant applications can decode quoted-printable
  //    text, though they may not necessarily be able to properly display the
  //    document as it was originally intended. As quoted-printable encoding
  //    is implemented most commonly, printable ASCII characters (values 33
  //    through 126, excluding 61), tabs and spaces that do not appear at the
  //    end of lines, and end-of-line characters are not encoded. Other
  //    characters are represented by an equal sign (=) immediately followed
  //    by that character's hexadecimal value. Lines that are longer than 76
  //    characters are shortened by line breaks, with the equal sign marking
  //    where the breaks occurred.
  //
  //    Note that QuotedPrintableUnescape is different from 'Q'-encoding as
  //    defined in rfc2047. In particular, This does not treat '_'s as spaces.
  //
  //    See QEncodingUnescape().
  //
  //    Copies "src" to "dest", rewriting quoted printable escape sequences
  //    =XX to their ASCII equivalents. src is not null terminated, instead
  //    specify len. I recommend that slen<szdest, but we honor szdest
  //    anyway.
  //    RETURNS the length of dest.
  // ----------------------------------------------------------------------
  int QuotedPrintableUnescape(const char* src, int slen, char* dest, int szdest);
  
  // ----------------------------------------------------------------------
  // QEncodingUnescape()
  //    This is very similar to QuotedPrintableUnescape except that we convert
  //    '_'s into spaces. (See RFC 2047)
  //    http://www.faqs.org/rfcs/rfc2047.html.
  //
  //    Copies "src" to "dest", rewriting q-encoding escape sequences
  //    =XX to their ASCII equivalents. src is not null terminated, instead
  //    specify len. I recommend that slen<szdest, but we honour szdest
  //    anyway.
  //    RETURNS the length of dest.
  // ----------------------------------------------------------------------
  int QEncodingUnescape(const char* src, int slen, char* dest, int szdest);
  
  // ----------------------------------------------------------------------
  // Base64Unescape()
  // WebSafeBase64Unescape()
  //    Copies "src" to "dest", where src is in base64 and is written to its
  //    ASCII equivalents. src is not null terminated, instead specify len.
  //    I recommend that slen<szdest, but we honor szdest anyway.
  //    RETURNS the length of dest, or -1 if src contains invalid chars.
  //    The WebSafe variation use '-' instead of '+' and '_' instead of '/'.
  //    The variations that store into a string clear the string first, and
  //    return false (with dest empty) if src contains invalid chars; for
  //    these versions src and dest must be different strings.
  // ----------------------------------------------------------------------
  int Base64Unescape(const char* src, int slen, char* dest, int szdest);
  bool Base64Unescape(const char* src, int slen, string* dest);
  inline bool Base64Unescape(const string& src, string* dest) {
    return Base64Unescape(src.data(), src.size(), dest);
  }
  
  int WebSafeBase64Unescape(const char* src, int slen, char* dest, int szdest);
  bool WebSafeBase64Unescape(const char* src, int slen, string* dest);
  inline bool WebSafeBase64Unescape(const string& src, string* dest) {
    return WebSafeBase64Unescape(src.data(), src.size(), dest);
  }
  
  // Return the length to use for the output buffer given to the base64 escape
  // routines. Make sure to use the same value for do_padding in both.
  // This function may return incorrect results if given input_len values that
  // are extremely high, which should happen rarely.
  int CalculateBase64EscapedLen(int input_len, bool do_padding);
  // Use this version when calling Base64Escape without a do_padding arg.
  int CalculateBase64EscapedLen(int input_len);
  
  // ----------------------------------------------------------------------
  // Base64Escape()
  // WebSafeBase64Escape()
  //    Encode "src" to "dest" using base64 encoding.
  //    src is not null terminated, instead specify len.
  //    'dest' should have at least CalculateBase64EscapedLen() length.
  //    RETURNS the length of dest.
  //    The WebSafe variation use '-' instead of '+' and '_' instead of '/'
  //    so that we can place the out in the URL or cookies without having
  //    to escape them.  It also has an extra parameter "do_padding",
  //    which when set to false will prevent padding with "=".
  // ----------------------------------------------------------------------
  int Base64Escape(const unsigned char* src, int slen, char* dest, int szdest);
  int WebSafeBase64Escape(const unsigned char* src, int slen, char* dest,
                          int szdest, bool do_padding);
  // Encode src into dest with padding.
  void Base64Escape(const string& src, string* dest);
  // Encode src into dest web-safely without padding.
  void WebSafeBase64Escape(const string& src, string* dest);
  // Encode src into dest web-safely with padding.
  void WebSafeBase64EscapeWithPadding(const string& src, string* dest);
  
  void Base64Escape(const unsigned char* src, int szsrc,
                    string* dest, bool do_padding);
  void WebSafeBase64Escape(const unsigned char* src, int szsrc,
                           string* dest, bool do_padding);
  
  // ----------------------------------------------------------------------
  // Base32Unescape()
  //    Copies "src" to "dest", where src is in base32 and is written to its
  //    ASCII equivalents. src is not null terminated, instead specify len.
  //    RETURNS the length of dest, or -1 if src contains invalid chars.
  // ----------------------------------------------------------------------
  int Base32Unescape(const char* src, int slen, char* dest, int szdest);
  bool Base32Unescape(const char* src, int slen, string* dest);
  inline bool Base32Unescape(const string& src, string* dest) {
    return Base32Unescape(src.data(), src.size(), dest);
  }
  
  // ----------------------------------------------------------------------
  // Base32Escape()
  //    Encode "src" to "dest" using base32 encoding.
  //    src is not null terminated, instead specify len.
  //    'dest' should have at least CalculateBase32EscapedLen() length.
  //    RETURNS the length of dest. RETURNS 0 if szsrc is zero, or szdest is
  //    too small to fit the fully encoded result.  'dest' is padded with '='.
  //
  //    Note that this is "Base 32 Encoding" from RFC 4648 section 6.
  // ----------------------------------------------------------------------
  int Base32Escape(const unsigned char* src, size_t szsrc,
                   char* dest, size_t szdest);
  bool Base32Escape(const string& src, string* dest);
  
  // ----------------------------------------------------------------------
  // Base32HexEscape()
  //    Encode "src" to "dest" using base32hex encoding.
  //    src is not null terminated, instead specify len.
  //    'dest' should have at least CalculateBase32EscapedLen() length.
  //    RETURNS the length of dest. RETURNS 0 if szsrc is zero, or szdest is
  //    too small to fit the fully encoded result.  'dest' is padded with '='.
  //
  //    Note that this is "Base 32 Encoding with Extended Hex Alphabet"
  //    from RFC 4648 section 7.
  // ----------------------------------------------------------------------
  int Base32HexEscape(const unsigned char* src, size_t szsrc,
                      char* dest, size_t szdest);
  bool Base32HexEscape(const string& src, string* dest);
  
  // Return the length to use for the output buffer given to the base32 escape
  // routines.  This function may return incorrect results if given input_len
  // values that are extremely high, which should happen rarely.
  int CalculateBase32EscapedLen(size_t input_len);
  
  // ----------------------------------------------------------------------
  // EightBase32DigitsToTenHexDigits()
  // TenHexDigitsToEightBase32Digits()
  //    Convert base32 to and from hex.
  //
  //   for EightBase32DigitsToTenHexDigits():
  //     *in must point to 8 base32 digits.
  //     *out must point to 10 bytes.
  //
  //   for TenHexDigitsToEightBase32Digits():
  //     *in must point to 10 hex digits.
  //     *out must point to 8 bytes.
  //
  //   Note that the Base64 functions above are different. They convert base64
  //   to and from binary data. We convert to and from string representations
  //   of hex. They deal with arbitrary lengths and we deal with single,
  //   whole base32 quanta.
  //
  //   See RFC3548 at http://www.ietf.org/rfc/rfc3548.txt
  //   for details on base32.
  // ----------------------------------------------------------------------
  void EightBase32DigitsToTenHexDigits(const char* in, char* out);
  void TenHexDigitsToEightBase32Digits(const char* in, char* out);
  
  // ----------------------------------------------------------------------
  // EightBase32DigitsToFiveBytes()
  // FiveBytesToEightBase32Digits()
  //   Convert base32 to and from binary
  //
  //   for EightBase32DigitsToTenHexDigits():
  //     *in must point to 8 base32 digits.
  //     *out must point to 5 bytes.
  //
  //   for TenHexDigitsToEightBase32Digits():
  //     *in must point to 5 bytes.
  //     *out must point to 8 bytes.
  //
  //   Note that the Base64 functions above are different.  They deal with
  //   arbitrary lengths and we deal with single, whole base32 quanta.
  // ----------------------------------------------------------------------
  void EightBase32DigitsToFiveBytes(const char* in, unsigned char* bytes_out);
  void FiveBytesToEightBase32Digits(const unsigned char* in_bytes, char* out);
  
  // ----------------------------------------------------------------------
  // EscapeFileName()
  // UnescapeFileName()
  //   Utility functions to (un)escape strings to make them suitable for use in
  //   filenames. Characters not in [a-zA-Z0-9-_.] will be escaped into %XX.
  //   E.g: "Hello, world!" will be escaped as "Hello%2c%20world%21"
  //
  //   NB that this function escapes slashes, so the output will be a flat
  //   filename and will not keep the directory structure. Slashes are replaced
  //   with '~', instead of a %XX sequence to make it easier for people to
  //   understand the escaped form when the original string is a file path.
  //
  //   WARNING: filenames produced by these functions may not be compatible with
  //   Colossus FS. In particular, the '%' character has a special meaning in
  //   CFS.
  //
  //   The versions that receive a string for the output will append to it.
  // ----------------------------------------------------------------------
  void EscapeFileName(const StringPiece& src, string* dst);
  void UnescapeFileName(const StringPiece& src, string* dst);
  inline string EscapeFileName(const StringPiece& src) {
    string r;
    EscapeFileName(src, &r);
    return r;
  }
  inline string UnescapeFileName(const StringPiece& src) {
    string r;
    UnescapeFileName(src, &r);
    return r;
  }
  
  // ----------------------------------------------------------------------
  // Here are a couple utility methods to change ints to hex chars & back
  // ----------------------------------------------------------------------
  
  inline int int_to_hex_digit(int i) {
    DCHECK((i >= 0) && (i <= 15));
    return ((i < 10) ? (i + '0') : ((i - 10) + 'A'));
  }
  
  inline int int_to_lower_hex_digit(int i) {
    DCHECK((i >= 0) && (i <= 15));
    return (i < 10) ? (i + '0') : ((i - 10) + 'a');
  }
  
  inline int hex_digit_to_int(char c) {
    /* Assume ASCII. */
    DCHECK('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61);
    DCHECK(ascii_isxdigit(c));
    int x = static_cast<unsigned char>(c);
    if (x > '9') {
      x += 9;
    }
    return x & 0xf;
  }
  
  // ----------------------------------------------------------------------
  // a2b_hex()
  //  Description: Ascii-to-Binary hex conversion.  This converts
  //         2*'num' hexadecimal characters to 'num' binary data.
  //        Return value: 'num' bytes of binary data (via the 'to' argument)
  // ----------------------------------------------------------------------
  void a2b_hex(const char* from, unsigned char* to, int num);
  void a2b_hex(const char* from, char* to, int num);
  void a2b_hex(const char* from, string* to, int num);
  string a2b_hex(const string& a);
  
  // ----------------------------------------------------------------------
  // a2b_bin()
  //  Description: Ascii-to-Binary binary conversion.  This converts
  //        a.size() binary characters (ascii '0' or '1') to
  //        ceil(a.size()/8) bytes of binary data.  The first character is
  //        considered the most significant if byte_order_msb is set.  a is
  //        considered to be padded with trailing 0s if its size is not a
  //        multiple of 8.
  //        Return value: ceil(a.size()/8) bytes of binary data
  // ----------------------------------------------------------------------
  string a2b_bin(const string& a, bool byte_order_msb);
  
  // ----------------------------------------------------------------------
  // b2a_hex()
  //  Description: Binary-to-Ascii hex conversion.  This converts
  //   'num' bytes of binary to a 2*'num'-character hexadecimal representation
  //    Return value: 2*'num' characters of ascii text (via the 'to' argument)
  // ----------------------------------------------------------------------
  void b2a_hex(const unsigned char* from, char* to, int num);
  void b2a_hex(const unsigned char* from, string* to, int num);
  
  // ----------------------------------------------------------------------
  // b2a_hex()
  //  Description: Binary-to-Ascii hex conversion.  This converts
  //   'num' bytes of binary to a 2*'num'-character hexadecimal representation
  //    Return value: 2*'num' characters of ascii string
  // ----------------------------------------------------------------------
  string b2a_hex(const char* from, int num);
  string b2a_hex(const StringPiece& b);
  
  // ----------------------------------------------------------------------
  // b2a_bin()
  //  Description: Binary-to-Ascii binary conversion.  This converts
  //   b.size() bytes of binary to a 8*b.size() character representation
  //   (ascii '0' or '1').  The highest order bit in each byte is returned
  //   first in the string if byte_order_msb is set.
  //   Return value: 8*b.size() characters of ascii text
  // ----------------------------------------------------------------------
  string b2a_bin(const string& b, bool byte_order_msb);
  
  // ----------------------------------------------------------------------
  // ShellEscape
  //   Make a shell command argument from a string.
  //   Returns a Bourne shell string literal such that, once the shell finishes
  //   expanding the argument, the argument passed on to the program being
  //   run will be the same as whatever you passed in.
  //   NOTE: This is "ported" from python2.2's commands.mkarg(); it should be
  //         safe for Bourne shell syntax (i.e. sh, bash), but mileage may vary
  //         with other shells.
  // ----------------------------------------------------------------------
  string ShellEscape(StringPiece src);
  
  // Runs ShellEscape() on the arguments, concatenates them with a space, and
  // returns the resulting string.
  template <class InputIterator>
  string ShellEscapeCommandLine(InputIterator begin, const InputIterator& end) {
    string result;
    for (; begin != end; ++begin) {
      if (!result.empty()) result.append(" ");
      result.append(ShellEscape(*begin));
    }
    return result;
  }
  
  // Reads at most bytes_to_read from binary_string and writes it to
  // ascii_string in lower case hex.
  void ByteStringToAscii(const string& binary_string, size_t bytes_to_read,
                         string* ascii_string);
  
  inline string ByteStringToAscii(const string& binary_string,
                                  int bytes_to_read) {
    string result;
    ByteStringToAscii(binary_string, bytes_to_read, &result);
    return result;
  }
  
  // Converts the hex from ascii_string into binary data and
  // writes the binary data into binary_string.
  // Empty input successfully converts to empty output.
  // Returns false and may modify output if it is
  // unable to parse the hex string.
  bool ByteStringFromAscii(const string& ascii_string, string* binary_string);
  
  // Clean up a multi-line string to conform to Unix line endings.
  // Reads from src and appends to dst, so usually dst should be empty.
  // If there is no line ending at the end of a non-empty string, it can
  // be added automatically.
  //
  // Four different types of input are correctly handled:
  //
  //   - Unix/Linux files: line ending is LF, pass through unchanged
  //
  //   - DOS/Windows files: line ending is CRLF: convert to LF
  //
  //   - Legacy Mac files: line ending is CR: convert to LF
  //
  //   - Garbled files: random line endings, covert gracefully
  //                    lonely CR, lonely LF, CRLF: convert to LF
  //
  //   @param src The multi-line string to convert
  //   @param dst The converted string is appended to this string
  //   @param auto_end_last_line Automatically terminate the last line
  //
  //   Limitations:
  //
  //     This does not do the right thing for CRCRLF files created by
  //     broken programs that do another Unix->DOS conversion on files
  //     that are already in CRLF format.
  void CleanStringLineEndings(const string& src, string* dst,
                              bool auto_end_last_line);
  
  // Same as above, but transforms the argument in place.
  void CleanStringLineEndings(string* str, bool auto_end_last_line);
  
  inline string SQLEscape(StringPiece src) {
    return BackslashEscape(src, "\\'\n\r\"\x1a");
  }
  
  inline std::string JSonDecode(StringPiece str) {
    return strings::BackslashUnescape(str, "\\/\"");
  }
  
  }  // namespace strings
  
  #endif  // STRINGS_ESCAPING_H_
  