1 // Copyright 1999-2005 The RE2 Authors. All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
6 #include "re2/stringpiece.h"
10 // ----------------------------------------------------------------------
12 // Copies 'src' to 'dest', escaping dangerous characters using
13 // C-style escape sequences. 'src' and 'dest' should not overlap.
14 // Returns the number of bytes written to 'dest' (not including the \0)
15 // or -1 if there was insufficient space.
16 // ----------------------------------------------------------------------
17 int CEscapeString(const char* src
, int src_len
, char* dest
,
19 const char* src_end
= src
+ src_len
;
22 for (; src
< src_end
; src
++) {
23 if (dest_len
- used
< 2) // Need space for two letter escape
26 unsigned char c
= *src
;
28 case '\n': dest
[used
++] = '\\'; dest
[used
++] = 'n'; break;
29 case '\r': dest
[used
++] = '\\'; dest
[used
++] = 'r'; break;
30 case '\t': dest
[used
++] = '\\'; dest
[used
++] = 't'; break;
31 case '\"': dest
[used
++] = '\\'; dest
[used
++] = '\"'; break;
32 case '\'': dest
[used
++] = '\\'; dest
[used
++] = '\''; break;
33 case '\\': dest
[used
++] = '\\'; dest
[used
++] = '\\'; break;
35 // Note that if we emit \xNN and the src character after that is a hex
36 // digit then that digit must be escaped too to prevent it being
37 // interpreted as part of the character code by C.
38 if (c
< ' ' || c
> '~') {
39 if (dest_len
- used
< 4) // need space for 4 letter escape
41 sprintf(dest
+ used
, "\\%03o", c
);
44 dest
[used
++] = c
; break;
49 if (dest_len
- used
< 1) // make sure that there is room for \0
52 dest
[used
] = '\0'; // doesn't count towards return value though
57 // ----------------------------------------------------------------------
59 // Copies 'src' to result, escaping dangerous characters using
60 // C-style escape sequences. 'src' and 'dest' should not overlap.
61 // ----------------------------------------------------------------------
62 string
CEscape(const StringPiece
& src
) {
63 const int dest_length
= src
.size() * 4 + 1; // Maximum possible expansion
64 char* dest
= new char[dest_length
];
65 const int len
= CEscapeString(src
.data(), src
.size(),
67 string s
= string(dest
, len
);
72 string
PrefixSuccessor(const StringPiece
& prefix
) {
73 // We can increment the last character in the string and be done
74 // unless that character is 255, in which case we have to erase the
75 // last character and increment the previous character, unless that
76 // is 255, etc. If the string is empty or consists entirely of
77 // 255's, we just return the empty string.
79 string
limit(prefix
.data(), prefix
.size());
80 int index
= limit
.length() - 1;
81 while (!done
&& index
>= 0) {
82 if ((limit
[index
]&255) == 255) {