12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394# 1 "src/lib/eliom_unwrap.client.ml"(* Ocsigen
* http://www.ocsigen.org
* Copyright (C) 2011 Pierre Chambart
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)(* TODO: implement with WeakMap when standardised:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/WeakMap
class type ['a,'b] weakMap = object
method get : 'a -> 'b Js.optdef Js.meth
method set : 'a -> 'b -> unit Js.meth
method has : 'a -> bool Js.t Js.meth
end
let weakMap : ('a,'b) weakMap Js.t Js.constr = Js.Unsafe.global##_WeakMap
let map : (Obj.t,Obj.t) weakMap Js.t = jsnew weakMap ()
*)openJs_of_ocamlopenEliom_libmoduleMark:sigtypetend=structtypet=stringend(* XXX must be the same as in Ocsigen_wrap *)typeunwrap_id=intletid_of_intx=xtypeunwrapper={id:unwrap_id;mutableumark:Mark.t}letunwrap_table:(Obj.t->Obj.toption)Js.js_arrayJs.t=new%jsJs.array_empty(* table containing all the unwrapping functions referenced by their id *)typeoccurrence={parent:Obj.t;field:int}letregister_unwrapper'idf=ifJs.Optdef.test(Js.array_getunwrap_tableid)thenfailwith(Printf.sprintf">> the unwrapper id %i is already registered"id);letfx=Ocsigen_lib_base.Option.mapObj.repr(f(Obj.objx))in(* Store unwrapper *)Js.array_setunwrap_tableidfletregister_unwrapperidf=register_unwrapper'id(funx->Some(fx))letapply_unwrapperunwrapperv=Js.Optdef.case(Js.array_getunwrap_tableunwrapper.id)(fun()->None)(* Use late unwrapping! *)(funf->fv)letlate_unwrap_valueold_valuenew_value=letold_value=Obj.reprold_valueinList.iter(fun{parent;field}->Js.Unsafe.setparentfieldnew_value)(Obj.obj(Obj.field(Obj.fieldold_value(Obj.sizeold_value-1))2))externalraw_unmarshal_and_unwrap:(unit,unwrapper->_->_option)Js.meth_callback->string->int->_="caml_unwrap_value_from_string"letunwrapsi=if!Eliom_config.debug_timingsthenFirebug.console##(time(Js.string"unwrap"));letres=raw_unmarshal_and_unwrap(Js.wrap_callbackapply_unwrapper)siinif!Eliom_config.debug_timingsthenFirebug.console##(timeEnd(Js.string"unwrap"));resletunwrap_jss=unwrap(Js.to_bytestrings)0