mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-14 13:15:14 +03:00
Added String::escape and String::unescape.
This commit is contained in:
@@ -69,6 +69,12 @@ class EE_API String {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Escape string sequence */
|
||||
static String escape( const String& str );
|
||||
|
||||
/** Unescape string sequence */
|
||||
static String unescape( const String& str );
|
||||
|
||||
/** @return string hash */
|
||||
static String::HashType hash( const std::string& str );
|
||||
|
||||
@@ -776,6 +782,10 @@ class EE_API String {
|
||||
|
||||
String& toUpper();
|
||||
|
||||
String& escape();
|
||||
|
||||
String& unescape();
|
||||
|
||||
StringBaseType lastChar() const;
|
||||
|
||||
std::vector<String> split( const StringBaseType& delim = '\n',
|
||||
|
||||
@@ -112,6 +112,154 @@ Int64 String::BMH::find( const std::string& haystack, const std::string& needle,
|
||||
return find( haystack, needle, haystackOffset, occ );
|
||||
}
|
||||
|
||||
String String::escape( const String& str ) {
|
||||
String output;
|
||||
for ( size_t i = 0; i < str.size(); i++ ) {
|
||||
switch ( str[i] ) {
|
||||
case '\r':
|
||||
output += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
output += "\\t";
|
||||
break;
|
||||
case '\n':
|
||||
output += "\\n";
|
||||
break;
|
||||
case '\a':
|
||||
output += "\\a";
|
||||
break;
|
||||
case '\b':
|
||||
output += "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
output += "\\f";
|
||||
break;
|
||||
case '\v':
|
||||
output += "\\v";
|
||||
break;
|
||||
default: {
|
||||
output += str[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
String String::unescape( const String& str ) {
|
||||
String output;
|
||||
for ( size_t i = 0; i < str.size(); i++ ) {
|
||||
if ( i > 0 && str[i - 1] == '\\' ) {
|
||||
switch ( str[i] ) {
|
||||
case '\\':
|
||||
output.push_back( '\\' );
|
||||
break;
|
||||
case 'r':
|
||||
output.push_back( '\r' );
|
||||
break;
|
||||
case 't':
|
||||
output.push_back( '\t' );
|
||||
break;
|
||||
case 'n':
|
||||
output.push_back( '\n' );
|
||||
break;
|
||||
case '\'':
|
||||
output.push_back( '\'' );
|
||||
break;
|
||||
case '"':
|
||||
output.push_back( '"' );
|
||||
break;
|
||||
case '?':
|
||||
output.push_back( '\?' );
|
||||
break;
|
||||
case 'a':
|
||||
output.push_back( '\a' );
|
||||
break;
|
||||
case 'b':
|
||||
output.push_back( '\b' );
|
||||
break;
|
||||
case 'f':
|
||||
output.push_back( '\f' );
|
||||
break;
|
||||
case 'v':
|
||||
output.push_back( '\v' );
|
||||
break;
|
||||
case 'x': {
|
||||
size_t len = 2;
|
||||
if ( i + len < str.size() ) {
|
||||
std::string buffer;
|
||||
for ( i = i + 1; i < str.size(); i++ )
|
||||
if ( std::isdigit( str[i] ) || ( str[i] >= 'a' && str[i] <= 'f' ) ||
|
||||
( str[i] >= 'A' && str[i] <= 'F' ) ) {
|
||||
buffer.push_back( str[i] );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if ( buffer.size() >= len ) {
|
||||
Uint32 value;
|
||||
if ( String::fromString( value, buffer, std::hex ) )
|
||||
output.push_back( value );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
case 'U': {
|
||||
size_t len = str[i] == 'u' ? 4 : 8;
|
||||
if ( i + len < str.size() ) {
|
||||
size_t to = i + len;
|
||||
std::string buffer;
|
||||
for ( i = i + 1; i <= to; i++ ) {
|
||||
if ( std::isdigit( str[i] ) || ( str[i] >= 'a' && str[i] <= 'f' ) ||
|
||||
( str[i] >= 'A' && str[i] <= 'F' ) ) {
|
||||
buffer.push_back( str[i] );
|
||||
}
|
||||
}
|
||||
if ( buffer.size() == len ) {
|
||||
Uint32 value;
|
||||
if ( String::fromString( value, buffer, std::hex ) )
|
||||
output.push_back( value );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8': {
|
||||
size_t to = eemin( (size_t)i + 3, str.size() );
|
||||
std::string buffer;
|
||||
for ( ; i < to; i++ ) {
|
||||
if ( ( str[i] >= '0' && str[i] <= '8' ) ) {
|
||||
buffer.push_back( str[i] );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( buffer.size() <= 3 ) {
|
||||
Uint32 value;
|
||||
if ( String::fromString( value, buffer, std::oct ) )
|
||||
output.push_back( value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Undefined behavior
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ( str[i] != '\\' ) {
|
||||
output.push_back( str[i] );
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
String::HashType String::hash( const std::string& str ) {
|
||||
return String::hash( str.c_str() );
|
||||
}
|
||||
@@ -400,6 +548,16 @@ String& String::toUpper() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::escape() {
|
||||
this->assign( String::escape( *this ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::unescape() {
|
||||
this->assign( String::unescape( *this ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
String::StringBaseType String::lastChar() const {
|
||||
return mString.empty() ? std::numeric_limits<StringBaseType>::max()
|
||||
: mString[mString.size() - 1];
|
||||
|
||||
@@ -1,26 +1,6 @@
|
||||
#include "docsearchcontroller.hpp"
|
||||
#include "codeeditor.hpp"
|
||||
|
||||
static void replaceAllEscapedSequences( String& target, const String& that, const String& with ) {
|
||||
std::string::size_type pos = 0;
|
||||
while ( ( pos = target.find( that, pos ) ) != String::InvalidPos ) {
|
||||
if ( pos > 0 && target[pos - 1] == '\\' ) {
|
||||
target.erase( pos, 1 );
|
||||
} else {
|
||||
target.erase( pos, that.length() );
|
||||
target.insert( pos, with );
|
||||
}
|
||||
pos += with.length();
|
||||
}
|
||||
}
|
||||
|
||||
static void unescapeSequences( String& txt ) {
|
||||
replaceAllEscapedSequences( txt, "\\n", String( '\n' ) );
|
||||
replaceAllEscapedSequences( txt, "\\t", String( '\t' ) );
|
||||
replaceAllEscapedSequences( txt, "\\r", String( '\r' ) );
|
||||
replaceAllEscapedSequences( txt, "\\\\", String( '\\' ) );
|
||||
}
|
||||
|
||||
DocSearchController::DocSearchController( UICodeEditorSplitter* editorSplitter, App* app ) :
|
||||
mEditorSplitter( editorSplitter ), mApp( app ) {}
|
||||
|
||||
@@ -165,8 +145,14 @@ void DocSearchController::showFindView() {
|
||||
|
||||
const TextDocument& doc = editor->getDocument();
|
||||
|
||||
if ( doc.getSelection().hasSelection() && doc.getSelection().inSameLine() ) {
|
||||
if ( doc.getSelection().hasSelection() ) {
|
||||
String text = doc.getSelectedText();
|
||||
if ( !doc.getSelection().inSameLine() ) {
|
||||
text.escape();
|
||||
UICheckBox* escapeSequenceChk = mSearchBarLayout->find<UICheckBox>( "escape_sequence" );
|
||||
if ( !escapeSequenceChk->isChecked() )
|
||||
escapeSequenceChk->setChecked( true );
|
||||
}
|
||||
if ( !text.empty() ) {
|
||||
findInput->setText( text );
|
||||
findInput->getDocument().selectAll();
|
||||
@@ -203,17 +189,17 @@ bool DocSearchController::findPrevText( SearchState& search ) {
|
||||
|
||||
String txt( search.text );
|
||||
if ( search.escapeSequences )
|
||||
unescapeSequences( txt );
|
||||
txt.unescape();
|
||||
|
||||
TextRange found = doc.findLast( txt, from, search.caseSensitive, search.wholeWord,
|
||||
search.type, search.range );
|
||||
TextRange found = doc.findLast( txt, from, search.caseSensitive, search.wholeWord, search.type,
|
||||
search.range );
|
||||
if ( found.isValid() ) {
|
||||
doc.setSelection( found );
|
||||
findInput->removeClass( "error" );
|
||||
return true;
|
||||
} else {
|
||||
found = doc.findLast( txt, range.end(), search.caseSensitive, search.wholeWord,
|
||||
search.type, range );
|
||||
found = doc.findLast( txt, range.end(), search.caseSensitive, search.wholeWord, search.type,
|
||||
range );
|
||||
if ( found.isValid() ) {
|
||||
doc.setSelection( found );
|
||||
findInput->removeClass( "error" );
|
||||
@@ -243,7 +229,7 @@ bool DocSearchController::findNextText( SearchState& search ) {
|
||||
|
||||
String txt( search.text );
|
||||
if ( search.escapeSequences )
|
||||
unescapeSequences( txt );
|
||||
txt.unescape();
|
||||
|
||||
TextRange found =
|
||||
doc.find( txt, from, search.caseSensitive, search.wholeWord, search.type, range );
|
||||
@@ -252,8 +238,8 @@ bool DocSearchController::findNextText( SearchState& search ) {
|
||||
findInput->removeClass( "error" );
|
||||
return true;
|
||||
} else {
|
||||
found = doc.find( txt, range.start(), search.caseSensitive, search.wholeWord,
|
||||
search.type, range );
|
||||
found = doc.find( txt, range.start(), search.caseSensitive, search.wholeWord, search.type,
|
||||
range );
|
||||
if ( found.isValid() ) {
|
||||
doc.setSelection( found.reversed() );
|
||||
findInput->removeClass( "error" );
|
||||
@@ -288,8 +274,8 @@ int DocSearchController::replaceAll( SearchState& search, const String& replace
|
||||
String txt( search.text );
|
||||
String repl( replace );
|
||||
if ( search.escapeSequences ) {
|
||||
unescapeSequences( txt );
|
||||
unescapeSequences( repl );
|
||||
txt.unescape();
|
||||
repl.unescape();
|
||||
}
|
||||
|
||||
int count = doc.replaceAll( txt, repl, search.caseSensitive, search.wholeWord, search.type,
|
||||
@@ -312,8 +298,8 @@ bool DocSearchController::findAndReplace( SearchState& search, const String& rep
|
||||
String txt( search.text );
|
||||
String repl( replace );
|
||||
if ( search.escapeSequences ) {
|
||||
unescapeSequences( txt );
|
||||
unescapeSequences( repl );
|
||||
txt.unescape();
|
||||
repl.unescape();
|
||||
}
|
||||
|
||||
if ( doc.hasSelection() && doc.getSelectedText() == txt ) {
|
||||
|
||||
Reference in New Issue
Block a user