1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495(*
* Copyright (c) 2011-2012 Anil Madhavapeddy <anil@recoil.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openBigarray_compattypet=(char,int8_unsigned_elt,c_layout)Array1.ttypebuf=Cstruct.tletpage_size=1lsl12letpage_alignment=4096letlengtht=Array1.dimtexternalalloc_pages:bool->int->t="caml_mirage_iopage_alloc_pages"externalc_get_addr:t->nativeint="caml_mirage_iopage_get_addr"letget_addrt=c_get_addrtletget_paget=Nativeint.(div(get_addrt)(of_intpage_size))letgetn=ifn<0thenraise(Invalid_argument"Io_page.get cannot allocate a -ve number of pages")elseifn=0thenArray1.createcharc_layout0else(tryalloc_pagesfalsenwithOut_of_memory->Gc.compact();alloc_pagestruen)letget_orderorder=get(1lslorder)letto_pagest=assert(lengthtmodpage_size=0);letrecloopoffacc=ifoff<(lengtht)thenloop(off+page_size)(Bigarray_compat.Array1.subtoffpage_size::acc)elseaccinList.rev(loop0[])letpagesn=letrecinneraccn=ifn>0theninner((get1)::acc)(n-1)elseaccininner[]nletpages_orderorder=pages(1lslorder)letround_to_page_sizen=((n+page_size-1)lsr12)lsl12letto_cstructt=Cstruct.of_bigarraytexceptionBuffer_is_not_page_alignedexceptionBuffer_not_multiple_of_page_sizeletof_cstruct_exnx=letba=Cstruct.to_bigarrayxinifnot(Cstruct.check_alignmentxpage_alignment)thenraiseBuffer_is_not_page_aligned;ifArray1.dimbaland(page_size-1)<>0thenraiseBuffer_not_multiple_of_page_size;baletto_stringt=letresult=Bytes.create(lengtht)infori=0tolengtht-1doBytes.setresultit.{i}done;Bytes.to_stringresultletget_buf?(n=1)()=to_cstruct(getn)letblitsrcdest=Bigarray_compat.Array1.blitsrcdest(* TODO: this is extremely inefficient. Should use a ocp-endian
blit rather than a byte-by-byte *)letstring_blitsrcsrcoffdstdstofflen=fori=0tolen-1dodst.{i+dstoff}<-src.[i+srcoff]done