ligo/lib_stdlib/mBytes_buffer.ml
2017-12-14 18:10:50 +01:00

90 lines
3.0 KiB
OCaml

(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2017. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
type t = { mutable buffer : MBytes.t ;
mutable offset : int }
let create ?(initial_size=4096) () =
if initial_size <= 0
then invalid_arg "MBytes_buffer size must be greater than zero" ;
{ buffer = MBytes.create initial_size ;
offset = 0 }
let resize ?at_least_size buf =
let new_buf =
MBytes.create
(2 * (MBytes.length buf.buffer + Option.unopt ~default:0 at_least_size)) in
MBytes.blit buf.buffer 0 new_buf 0 buf.offset ;
buf.buffer <- new_buf
let resize_if_necessary buf bytes =
if buf.offset + bytes > MBytes.length buf.buffer
then resize ~at_least_size:bytes buf
else ()
let write_mbytes dst src srcoff len =
resize_if_necessary dst len ;
MBytes.blit src srcoff dst.buffer dst.offset len ;
dst.offset <- dst.offset + len
let write_char buf char =
resize_if_necessary buf 1 ;
MBytes.set_char buf.buffer buf.offset char ;
buf.offset <- buf.offset + 1
let write_int8 buf int =
resize_if_necessary buf 1 ;
MBytes.set_int8 buf.buffer buf.offset int ;
buf.offset <- buf.offset + 1
let write_int16 buf int =
resize_if_necessary buf 2 ;
MBytes.set_int16 buf.buffer buf.offset int ;
buf.offset <- buf.offset + 2
let write_int32 buf int =
resize_if_necessary buf 4 ;
MBytes.set_int32 buf.buffer buf.offset int ;
buf.offset <- buf.offset + 4
let write_int64 buf int =
resize_if_necessary buf 8 ;
MBytes.set_int64 buf.buffer buf.offset int ;
buf.offset <- buf.offset + 8
let write_float buf float =
resize_if_necessary buf 4 ;
MBytes.set_float buf.buffer buf.offset float ;
buf.offset <- buf.offset + 4
let write_double buf float =
resize_if_necessary buf 8 ;
MBytes.set_double buf.buffer buf.offset float ;
buf.offset <- buf.offset + 8
let write_string_data buf str =
let len = String.length str in
resize_if_necessary buf len ;
MBytes.blit_from_string str 0 buf.buffer buf.offset len ;
buf.offset <- buf.offset + len
let write_sized buffer (writer : unit -> unit) =
let initial_offset = buffer.offset in
write_int32 buffer Int32.zero ;
writer () ;
let ending_offset = buffer.offset in
let size = ending_offset - initial_offset - 4 in
let size32 = Int32.of_int size in
if (Int32.to_int size32) <> size
then failwith "Tried to write more than [Int32.max_int] bytes in sized location"
else MBytes.set_int32 buffer.buffer initial_offset size32
let to_mbytes buf =
MBytes.sub buf.buffer 0 buf.offset