1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798(* adapted from ocaml-protoc from code by c-cube *)moduleByte_slice=CCByte_slicemoduleByte_buffer=CCByte_buffermoduleDecode=structletskip(sl:Byte_slice.t)off:int=letshift=ref0inletcontinue=reftrueinletoff=refoffinletn_consumed=ref0inwhile!continuedoifsl.len<=0theninvalid_arg"out of bound";incrn_consumed;letb=Char.code(Bytes.getsl.bs!off)inletcur=bland0x7finifcur<>bthen((* at least one byte follows this one *)incroff;shift:=!shift+7)elseif!shift<63||bland0x7f<=1thencontinue:=falseelseinvalid_arg"leb128 varint is too long"done;!n_consumedletu64(sl:Byte_slice.t)(off:int):int64*int=letshift=ref0inletres=ref0Linletcontinue=reftrueinletoff=refoffinletn_consumed=ref0inwhile!continuedoifsl.len<=0theninvalid_arg"out of bound";incrn_consumed;letb=Char.code(Bytes.getsl.bs!off)inletcur=bland0x7finifcur<>bthen((* at least one byte follows this one *)(res:=Int64.(logor!res(shift_left(of_intcur)!shift)));incroff;shift:=!shift+7)elseif!shift<63||bland0x7f<=1then((res:=Int64.(logor!res(shift_left(of_intb)!shift)));continue:=false)elseinvalid_arg"leb128 varint is too long"done;!res,!n_consumedlet[@inline]uint_truncatesloff=letv,n_consumed=u64sloffinInt64.to_intv,n_consumedlet[@inline]decode_zigzag(v:int64):int64=Int64.(logxor(shift_rightv1)(neg(logandvInt64.one)))let[@inline]i64sloff:int64*int=letv,n_consumed=u64sloffindecode_zigzagv,n_consumedlet[@inline]int_truncatesloff=letv,n_consumed=u64sloffinInt64.to_int(decode_zigzagv),n_consumedendmoduleEncode=structlet[@inline]encode_zigzag(i:int64):int64=Int64.(logxor(shift_lefti1)(shift_righti63))externalvarint_size:(int64[@unboxed])->int="caml_cc_leb128_varint_size_byte""caml_cc_leb128_varint_size"[@@noalloc](** Compute how many bytes this int would occupy as varint *)externalvarint_slice:bytes->(int[@untagged])->(int64[@unboxed])->unit="caml_cc_leb128_varint_byte""caml_cc_leb128_varint"[@@noalloc](** Write this int as varint into the given slice *)let[@inline]u64(buf:Byte_buffer.t)(i:int64)=letn=varint_sizeiinByte_buffer.ensure_freebufn;assert(buf.len+n<=Bytes.lengthbuf.bs);varint_slicebuf.bsbuf.leni;buf.len<-buf.len+nlet[@inline]i64bufi:unit=u64buf(encode_zigzagi)let[@inline]uintbufi:unit=u64buf(Int64.of_inti)let[@inline]intbufi:unit=u64buf(encode_zigzag(Int64.of_inti))end