2005-08-05 19:02:01 +00:00
/ *
server side js functions for encoding / decoding objects into linear strings
Copyright Andrew Tridgell 2005
released under the GNU GPL Version 2 or later
* /
/ *
usage :
enc = encodeObject ( obj ) ;
obj = decodeObject ( enc ) ;
The encoded format of the object is a string that is safe to
use in URLs
Note that only data elements are encoded , not functions
* /
function _ _count _members ( o ) {
var i , count = 0 ;
for ( i in o ) {
count ++ ;
}
2005-08-07 06:19:17 +00:00
if ( o . length != undefined ) {
count ++ ;
}
2005-08-05 19:02:01 +00:00
return count ;
}
function _ _replace ( str , old , rep ) {
var s = string _init ( ) ;
var a = s . split ( old , str ) ;
var j = s . join ( rep , a ) ;
return s . join ( rep , a ) ;
}
2005-08-07 06:19:17 +00:00
function encodeElement ( e , name ) {
var t = typeof ( e ) ;
var r ;
var s = string _init ( ) ;
if ( t == 'object' && e == null ) {
t = 'null' ;
}
if ( t == 'object' ) {
r = s . sprintf ( "%s:%s:%s" , name , t , encodeObject ( e ) ) ;
} else if ( t == "string" ) {
var enc = s . encodeURIComponent ( e ) ;
var rep = _ _replace ( enc , '%' , '#' ) ;
r = s . sprintf ( "%s:%s:%s:" ,
name , t , _ _replace ( s . encodeURIComponent ( e ) , '%' , '#' ) ) ;
} else if ( t == "boolean" || t == "number" ) {
r = s . sprintf ( "%s:%s:%s:" , name , t , "" + e ) ;
} else if ( t == "undefined" || t == "null" ) {
r = s . sprintf ( "%s:%s:" , name , t ) ;
2005-08-22 01:52:22 +00:00
} else if ( t == "pointer" ) {
r = s . sprintf ( "%s:string:(POINTER):" , name ) ;
2005-08-07 06:19:17 +00:00
} else {
println ( "Unable to linearise type " + t ) ;
r = "" ;
}
return r ;
}
2005-08-05 19:02:01 +00:00
function encodeObject ( o ) {
var s = string _init ( ) ;
var i , r = s . sprintf ( "%u:" , _ _count _members ( o ) ) ;
for ( i in o ) {
2005-08-07 06:19:17 +00:00
r = r + encodeElement ( o [ i ] , i ) ;
}
if ( o . length != undefined ) {
r = r + encodeElement ( o . length , 'length' ) ;
2005-08-05 19:02:01 +00:00
}
return r ;
}
function decodeObjectArray ( a ) {
var s = string _init ( ) ;
var o = new Object ( ) ;
var i , count = a [ a . i ] ; a . i ++ ;
for ( i = 0 ; i < count ; i ++ ) {
var name = a [ a . i ] ; a . i ++ ;
var type = a [ a . i ] ; a . i ++ ;
var value ;
if ( type == 'object' ) {
o [ name ] = decodeObjectArray ( a ) ;
} else if ( type == "string" ) {
value = s . decodeURIComponent ( _ _replace ( a [ a . i ] , '#' , '%' ) ) ; a . i ++ ;
o [ name ] = value ;
} else if ( type == "boolean" ) {
value = a [ a . i ] ; a . i ++ ;
if ( value == 'true' ) {
o [ name ] = true ;
} else {
o [ name ] = false ;
}
} else if ( type == "undefined" ) {
o [ name ] = undefined ;
} else if ( type == "null" ) {
o [ name ] = null ;
} else if ( type == "number" ) {
value = a [ a . i ] ; a . i ++ ;
o [ name ] = value + 0 ;
} else {
println ( "Unable to delinearise type " + t ) ;
assert ( t == "supported type" ) ;
}
}
return o ;
}
function decodeObject ( str ) {
var s = string _init ( ) ;
var a = s . split ( ':' , str ) ;
a . i = 0 ;
return decodeObjectArray ( a ) ;
}