2023-04-06 20:32:50 +00:00
/ * *
* @ author brun0ne [ brunonblok @ gmail . com ]
* @ copyright Crown Copyright 2023
* @ license Apache - 2.0
* /
import Operation from "../Operation.mjs" ;
import OperationError from "../errors/OperationError.mjs" ;
/ * *
* PHP Serialize operation
* /
class PHPSerialize extends Operation {
/ * *
* PHPSerialize constructor
* /
constructor ( ) {
super ( ) ;
this . name = "PHP Serialize" ;
this . module = "Default" ;
this . description = "Performs PHP serialization on JSON data.<br><br>This function does not support <code>object</code> tags.<br><br>Since PHP doesn't distinguish dicts and arrays, this operation is not always symmetric to <code>PHP Deserialize</code>.<br><br>Example:<br><code>[5,"abc",true]</code><br>becomes<br><code>a:3:{i:0;i:5;i:1;s:3:"abc";i:2;b:1;}<code>" ;
this . infoURL = "https://www.phpinternalsbook.com/php5/classes_objects/serialization.html" ;
this . inputType = "JSON" ;
this . outputType = "string" ;
this . args = [ ] ;
}
/ * *
* @ param { JSON } input
* @ param { Object [ ] } args
* @ returns { string }
* /
run ( input , args ) {
/ * *
* Determines if a number is an integer
2023-04-06 21:03:46 +00:00
* @ param { number } value
2023-04-06 20:32:50 +00:00
* @ returns { boolean }
* /
function isInteger ( value ) {
return typeof value === "number" && parseInt ( value . toString ( ) , 10 ) === value ;
}
/ * *
* Serialize basic types
2023-04-06 21:03:46 +00:00
* @ param { string | number | boolean } content
2023-04-06 20:32:50 +00:00
* @ returns { string }
* /
function serializeBasicTypes ( content ) {
const basicTypes = {
"string" : "s" ,
"integer" : "i" ,
"float" : "d" ,
"boolean" : "b"
} ;
/ * *
* Booleans
* cast to 0 or 1
* /
2023-04-06 21:03:46 +00:00
if ( typeof content === "boolean" ) {
return ` ${ basicTypes . boolean } : ${ content ? 1 : 0 } ` ;
2023-04-06 20:32:50 +00:00
}
2023-04-09 19:06:59 +00:00
/* Numbers */
2023-04-06 21:03:46 +00:00
if ( typeof content === "number" ) {
if ( isInteger ( content ) ) {
return ` ${ basicTypes . integer } : ${ content . toString ( ) } ` ;
} else {
return ` ${ basicTypes . float } : ${ content . toString ( ) } ` ;
2023-04-06 20:32:50 +00:00
}
}
2023-04-09 19:06:59 +00:00
/* Strings */
2023-04-06 20:32:50 +00:00
if ( typeof content === "string" )
2023-04-06 21:03:46 +00:00
return ` ${ basicTypes . string } : ${ content . length } :" ${ content } " ` ;
2023-04-06 20:32:50 +00:00
/** This should be unreachable */
throw new OperationError ( ` Encountered a non-implemented type: ${ typeof content } ` ) ;
}
/ * *
* Recursively serialize
2023-04-06 21:03:46 +00:00
* @ param { * } object
2023-04-06 20:32:50 +00:00
* @ returns { string }
* /
function serialize ( object ) {
2023-04-09 19:06:59 +00:00
/* Null */
2023-04-06 20:32:50 +00:00
if ( object == null ) {
2023-04-06 21:03:46 +00:00
return ` N; ` ;
2023-04-06 20:32:50 +00:00
}
2023-04-06 21:03:46 +00:00
if ( typeof object !== "object" ) {
2023-04-09 19:06:59 +00:00
/* Basic types */
2023-04-06 20:32:50 +00:00
return ` ${ serializeBasicTypes ( object ) } ; ` ;
2023-04-06 21:03:46 +00:00
} else if ( object instanceof Array ) {
2023-04-09 19:06:59 +00:00
/* Arrays */
2023-04-06 20:32:50 +00:00
const serializedElements = [ ] ;
2023-04-06 21:03:46 +00:00
2023-04-06 20:32:50 +00:00
for ( let i = 0 ; i < object . length ; i ++ ) {
serializedElements . push ( ` ${ serialize ( i ) } ${ serialize ( object [ i ] ) } ` ) ;
}
2023-04-06 21:03:46 +00:00
return ` a: ${ object . length } :{ ${ serializedElements . join ( "" ) } } ` ;
} else if ( object instanceof Object ) {
/ * *
* Objects
* Note : the output cannot be guaranteed to be in the same order as the input
* /
2023-04-06 20:32:50 +00:00
const serializedElements = [ ] ;
const keys = Object . keys ( object ) ;
2023-04-06 21:03:46 +00:00
2023-04-06 20:32:50 +00:00
for ( const key of keys ) {
serializedElements . push ( ` ${ serialize ( key ) } ${ serialize ( object [ key ] ) } ` ) ;
}
2023-04-06 21:03:46 +00:00
return ` a: ${ keys . length } :{ ${ serializedElements . join ( "" ) } } ` ;
2023-04-06 20:32:50 +00:00
}
/** This should be unreachable */
throw new OperationError ( ` Encountered a non-implemented type: ${ typeof object } ` ) ;
}
return serialize ( input ) ;
}
}
export default PHPSerialize ;