//////
//
// phpserialize.js version 1.0 
// Functions to emulate php functions: serialize and unserialize for javascript
//
// Copyright © 2003 CNS http://www.schoolportal.co.il/cnse/
// Licensed under the terms of the GNU Lesser General Public License
// (http://www.opensource.org/licenses/lgpl-license.php)
// Email: shimon at schoolportal dot co dot il  
//
// api
// ~~~
// String php_serialize(Mixed)
// Mixed php_unserialize(String)
// Integer object_count(Object) - item count
//
// the research
// ~~~~~~~~~~~~
// object:
// class abc{
//  var $x;
//  function abc(){ this.$x="abc";}
// } $xx=new abc();
// echo serialize($xx);
// serilized object: O:3:"abc":1:{s:1:"x";N;} 
// array:
// echo serialize(array(1=>12,2=>"str","3"=>"str","4"=>45,false=>"test",true=>123,false,$undefinedvar,$undefinedvar=>999));
// a:5:{i:1;i:12;i:2;s:3:"str";i:3;s:3:"str";i:4;i:45;i:5;b:0;i:6;N;s:0:"";i:999;} 
// a:5:{
//       i:1; i:12;
//       i:2; s:3:"str";
//       i:3; s:3:"str";
//       i:4; i:45;
//       i:5; b:0;
//       i:6; N;
//       s:0:""; i:999;
//     }
//
//////

function object_count(o)
{
 var c=0;
 for (i in o)
 c++;
 return c;
}

function string_decode(s)
{
 if(s.indexOf('&')==-1)return s;
 var o="",c="";
 for(var i=0;i<s.length;i++)
 {
  c=s.charAt(i);
  if(c=="&")
  {
   if(s.charAt(i+1)=="#")
   {
    if(s.charAt(i+4)==";")
    {
     c=s.charAt(i+2)+s.charAt(i+3);
     if(c=='gt')o+='>';
     else if(c=='lt')o+='<';
     else o+=String.fromCharCode(parseInt(c));
     i+=4;
    }
    else if(s.charAt(i+5)==";")
    {
     if(c=='amp')o+='&';
     else
     c=s.charAt(i+2)+s.charAt(i+3)+s.charAt(i+4);
     o+=String.fromCharCode(parseInt(c));
     i+=5;
    }
    else if(s.charAt(i+6)==";")
    {
     if(c=='quot')o+='"';
     else
     c=s.charAt(i+2)+s.charAt(i+3)+s.charAt(i+4)+s.charAt(i+5);
     o+=String.fromCharCode(parseInt(c));
     i+=6;
    }
    else if(s.charAt(i+7)==";")
    {
     c=s.charAt(i+2)+s.charAt(i+3)+s.charAt(i+4)+s.charAt(i+5)+s.charAt(i+6);
     o+=String.fromCharCode(parseInt(c));
     i+=7;
    }
    else
     o+=s.charAt(i);
   }
   else
    o+=s.charAt(i);
  }
  else
  o+=s.charAt(i);
 }
 return o;  
}

function string_code(s)
{
 var c='';
 var i=0;
 for (i=0;i<s.length;i++) 
 {
  if(s.charAt(i)=='&')
   c=c+'&#38;';
  else if(s.charCodeAt(i)<256)
   c=c+s.charAt(i);
  else if(s.charCodeAt(i)>1487 && s.charCodeAt(i)<1515)
   c=c+s.charAt(i);
  else
   c=c+'&#'+s.charCodeAt(i)+';';
 }
 return c;
}

function php_serialize(a)
{
 var s='';
 if(typeof a == "object")
 {
  s+='a:'+object_count(a)+':{';
  for (key in a)
  {
   s+=php_serialize(key);
   s+=php_serialize(a[key]);
  }
  s+='}';
 }
 else if(typeof a == "array")
 {
  s+='a:'+a.length+':{';
  for(key=0;key<a.length;key++)
  {
   s+=php_serialize(key);
   s+=php_serialize(a[key]);
  }
  s+='}';
 }
 else if(typeof a == "number")
 {
  s+='i:'+a+';';
 }
 else if(typeof a == "string" || typeof a == "function")
 {
  var re=/^\d+$/;
  if(re.test(a))
   s+='i:'+a+';';
  else
  {
   var t=string_code(a);
   s+='s:'+t.length+':"'+t+'";';
  }
 }
 else if(typeof a == "boolean")
 {
  s+='b:'+(a?'1':'0')+';';
 }
 else if(typeof a == "undefined")
 {
  s+='N;';
 }
 return s;
}

var php_p,php_st;
function php_unserialize(s)
{
 var l=2,r='',e=0;
 php_p=0;
 php_st=s;
 if(php_st.substr(php_p,2) == 'i:') //we have an array
 {
  php_p+=2;
  e=php_st.indexOf(";",php_p);if(e==-1) return false; //error
  r = php_st.substring(php_p,e);
  php_p=e+1;
  return parseInt(r);
 }
 else if(php_st.substr(php_p,2) == 's:') //we have a string
 {
  php_p+=2;
  e=php_st.indexOf(":\"",php_p);if(e==-1) return false; //error
  r = php_st.substring(php_p,e);
  php_p=e+2;
  l=parseInt(r);
  return string_decode(php_st.substr(php_p,l));
  //    php_p=php_p+l+2;
 }
 else if(php_st.substr(php_p,2) == 'b:') //we have a boolean
 {
  php_p+=2;
  e=php_st.indexOf(";",php_p);if(e==-1) return false; //error
  r = php_st.substring(php_p,e);
  //php_p=e+1;
  return (parseInt(r)==1);
 }
 else if(php_st.substr(php_p,2) == 'N;') //we have an undefined value (could make error)
 {
  php_p+=2;
  return undefined;
 }
 //if ii

 return php_unserialize_helper(0);
}

function php_unserialize_helper(c)
{
 //'a:123:{?}';
 var a={},l=2,n=0,ic=0,r='',e=0,ii,dd;
 // l=length,a=array,n=index,ic=new item count,r=temp str,e=pos end ,ii=key,dd=value,c=item count

 if(php_st.substr(php_p,2) == 'a:') //we have an array
 {
  php_p+=2;
  e=php_st.indexOf(":",php_p);if(e==-1) return false; //error
  r = php_st.substring(php_p,e);
  php_p=e+2;
  ic=parseInt(r);
  n=0;
  return php_unserialize_helper(ic);
 }
 else
 {
  for(n=0;n<c;n++)
  {
   if(php_st.substr(php_p,2) == 'i:') //we have an integer
   {
    php_p+=2;
    e=php_st.indexOf(";",php_p);if(e==-1) return false; //error
    r = php_st.substring(php_p,e);
    php_p=e+1;
    ii=parseInt(r);
   }
   else if(php_st.substr(php_p,2) == 's:') //we have a string
   {
    php_p+=2;
    e=php_st.indexOf(":\"",php_p);if(e==-1) return false; //error
    r = php_st.substring(php_p,e);
    php_p=e+2;
    l=parseInt(r);
    ii=string_decode(php_st.substr(php_p,l));
    php_p=php_p+l+2;
   }
   else if(php_st.substr(php_p,2) == 'b:') //we have a boolean
   {
    php_p+=2;
    e=php_st.indexOf(";",php_p);if(e==-1) return false; //error
    r = php_st.substring(php_p,e);
    php_p=e+1;
    ii=(parseInt(r)==1);
   }
   else if(php_st.substr(php_p,2) == 'N;') //we have an undefined key (could make error)
   {
    php_p+=2;
    ii=undefined;
   }
   //if ii
   if(php_st.substr(php_p,2) == 'i:') //we have an integer
   {
    php_p+=2;
    e=php_st.indexOf(";",php_p);if(e==-1) return false; //error
    r = php_st.substring(php_p,e);
    php_p=e+1;
    dd=parseInt(r);
   }
   else if(php_st.substr(php_p,2) == 's:') //we have a string
   {
    php_p+=2;
    e=php_st.indexOf(":\"",php_p);if(e==-1) return false; //error
    r = php_st.substring(php_p,e);
    php_p=e+2;
    l=parseInt(r);
    dd=string_decode(php_st.substr(php_p,l));
    php_p=php_p+l+2;
   }
   else if(php_st.substr(php_p,2) == 'b:') //we have an array
   {
    php_p+=2;
    e=php_st.indexOf(";",php_p);if(e==-1) return false; //error
    r = php_st.substring(php_p,e);
    php_p=e+1;
    dd=(parseInt(r)==1);
   }
   else if(php_st.substr(php_p,2) == 'N;') //we have an undefined value (could make error)
   {
    php_p+=2;
    dd=undefined;
   }
   else if(php_st.substr(php_p,2) == 'a:') //we have an array
   {
    php_p+=2;
    e=php_st.indexOf(":",php_p);if(e==-1) return false; //error
    r = php_st.substring(php_p,e);
    php_p=e+2;
    ic=parseInt(r);
    n=0;
    dd= php_unserialize_helper(ic);
    php_p+=1;
   }//if dd
   a[ii]=dd;
  }//for n to c
  return a;
 }//if a: (array)
}
