2018-09-24 22:47:00 +02:00
/ * *
* @ author edouard hinard [ ]
* @ copyright Crown Copyright 2018
* @ license Apache - 2.0
* /
import Operation from "../Operation" ;
2018-09-27 23:17:57 +02:00
const LANGUAGES = {
"Python" : "python" ,
} ;
2018-09-24 22:47:00 +02:00
/ * *
2018-09-27 23:17:57 +02:00
* To Byte String Literal operation
2018-09-24 22:47:00 +02:00
* /
2018-09-27 23:17:57 +02:00
class ToByteStringLiteral extends Operation {
2018-09-24 22:47:00 +02:00
/ * *
2018-09-27 23:17:57 +02:00
* ToByteStringLiteral constructor
2018-09-24 22:47:00 +02:00
* /
constructor ( ) {
super ( ) ;
2018-09-27 23:17:57 +02:00
this . name = "To Byte String Literal" ;
2018-09-24 22:47:00 +02:00
this . module = "Default" ;
2018-09-27 23:17:57 +02:00
this . description = "Converts the input data to byte string literal in common languages.<br><br>e.g. for python, the UTF-8 encoded string <code>ça ma couté 20€</code> becomes <code>b'\\xc3\\xa7a ma cout\\xc3\\xa9 20\\xe2\\x82\\xac'</code>" ;
2018-09-24 22:47:00 +02:00
this . infoURL = "https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals" ;
this . inputType = "ArrayBuffer" ;
this . outputType = "string" ;
2018-09-27 23:17:57 +02:00
this . args = [
{
"name" : "Language" ,
"type" : "option" ,
"value" : Object . keys ( LANGUAGES )
} ,
] ;
2018-09-24 22:47:00 +02:00
}
/ * *
* @ param { ArrayBuffer } input
* @ param { Object [ ] } args
* @ returns { string }
* /
run ( input , args ) {
2018-09-25 21:55:43 +02:00
const data = new Uint8Array ( input ) ;
2018-09-27 23:17:57 +02:00
const language = args [ 0 ] ;
if ( language === "python" ) {
return this . python ( data ) ;
}
return "" ;
}
/ * *
* @ param { Uint8Array } data
* @ returns { string }
* /
python ( data ) {
2018-09-25 21:55:43 +02:00
if ( ! data ) return "b''" ;
2018-09-24 22:47:00 +02:00
// First pass to decide which quote to use
// single quote is prefered
let onlySingleQuote = false ;
2018-09-25 21:55:43 +02:00
for ( let i = 0 ; i < data . length ; i ++ ) {
if ( data [ i ] === 0x22 ) { // 0x22 <-> "
2018-09-24 22:47:00 +02:00
onlySingleQuote = false ;
break ;
}
2018-09-25 21:55:43 +02:00
if ( data [ i ] === 0x27 ) { // 0x27 <-> '
2018-09-24 22:47:00 +02:00
onlySingleQuote = true ;
}
}
let singleQuoted = true ;
2018-09-25 21:55:43 +02:00
if ( onlySingleQuote ) {
2018-09-24 22:47:00 +02:00
singleQuoted = false ;
}
// Second pass to convert byte array in Python bytes literal
let output = "" ;
2018-09-25 21:55:43 +02:00
for ( let i = 0 ; i < data . length ; i ++ ) {
if ( data [ i ] === 0x09 ) {
output += "\\t" ;
} else if ( data [ i ] === 0x0a ) {
output += "\\n" ;
} else if ( data [ i ] === 0x0d ) {
output += "\\r" ;
} else if ( data [ i ] === 0x22 && ! singleQuoted ) {
2018-09-24 22:47:00 +02:00
output += '\\"' ;
2018-09-25 21:55:43 +02:00
} else if ( data [ i ] === 0x27 && singleQuoted ) {
2018-09-24 22:47:00 +02:00
output += "\\'" ;
2018-09-25 21:55:43 +02:00
} else if ( data [ i ] === 0x5c ) {
output += "\\" ;
} else if ( data [ i ] < 0x20 || data [ i ] > 0x7e ) {
output += "\\x" + data [ i ] . toString ( 16 ) . padStart ( 2 , 0 ) ;
2018-09-24 22:47:00 +02:00
} else {
output += String . fromCharCode ( data [ i ] ) ;
}
}
2018-09-25 21:55:43 +02:00
if ( singleQuoted ) {
2018-09-24 22:47:00 +02:00
return "b'" + output + "'" ;
} else {
return 'b"' + output + '"' ;
}
}
}
2018-09-27 23:17:57 +02:00
export default ToByteStringLiteral ;