123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134openTablesopenCtypesopenPosixTypesopenForeignopenOpsmoduleBigstring=Core_kernel.Bigstringtypebigstring=Bigstring.tletadd(a:char)(b:char):char=((int_of_chara)lxor(int_of_charb))|>char_of_intletsub(a:char)(b:char):char=((int_of_chara)lxor(int_of_charb))|>char_of_intletmul(a:char)(b:char):char=mul_table.(int_of_chara).[int_of_charb]letdiv(a:char)(b:char):char=if(int_of_chara)=0thenchar_of_int0elseif(int_of_charb)=0thenfailwith"Divisor is 0"else(letlog_a=log_table.[a|>int_of_char]|>int_of_charinletlog_b=log_table.[b|>int_of_char]|>int_of_charinletlog_result=ref(log_a-log_b)inif!log_result<0thenlog_result:=!log_result+255;exp_table.[!log_result])letexp(a:char)(n:int):char=ifn=0then1|>char_of_intelseif(int_of_chara)=0then0|>char_of_intelse(letlog_a=log_table.[a|>int_of_char]|>int_of_charinletlog_result=ref(log_a*n)inwhile255<=!log_resultdolog_result:=!log_result-255;done;exp_table.[!log_result])letmul_slice_pure_ocaml?(skip_to:int=0)(c:char)(input:bigstring)(out:bigstring):unit=letmt=mul_table.(c|>int_of_char)inassert(Bigstring.lengthinput=Bigstring.lengthout);letlen=Bigstring.lengthinputinforn=skip_toto(len)-1doout.&{n}<-mt.%[input.&{n}]|>int_of_char;doneletmul_slice_xor_pure_ocaml?(skip_to:int=0)(c:char)(input:bigstring)(out:bigstring):unit=letmt=mul_table.(c|>int_of_char)inassert(Bigstring.lengthinput=Bigstring.lengthout);letlen=Bigstring.lengthinputinforn=skip_toto(len)-1doout.&{n}<-(mt.%[input.&{n}]|>int_of_char)lxorout.&{n};doneletslice_xor(input:bigstring)(out:bigstring):unit=assert(Bigstring.lengthinput=Bigstring.lengthout);letlen=Bigstring.lengthinputinforn=0to(len)-1doout.&{n}<-input.&{n}lxorout.&{n};doneletreedsolomon_gal_mul=foreign~release_runtime_lock:true"reedsolomon_gal_mul"(ptruint8_t@->ptruint8_t@->ptruint8_t@->ptruint8_t@->size_t@->returningsize_t)letreedsolomon_gal_mul_xor=foreign~release_runtime_lock:true"reedsolomon_gal_mul_xor"(ptruint8_t@->ptruint8_t@->ptruint8_t@->ptruint8_t@->size_t@->returningsize_t)letmul_slice(c:char)(input:bigstring)(out:bigstring)=letlow=Bigarray.Array2.slice_leftmul_table_low(c|>int_of_char)inlethigh=Bigarray.Array2.slice_leftmul_table_high(c|>int_of_char)inassert(Bigstring.lengthinput=Bigstring.lengthout);letsize=Bigstring.lengthinputinletbytes_done=(Unsigned.Size_t.to_int(reedsolomon_gal_mul(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1low))(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1high))(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1input))(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1out))(Unsigned.Size_t.of_intsize)))inmul_slice_pure_ocaml~skip_to:bytes_donecinputoutletmul_slice_xor(c:char)(input:bigstring)(out:bigstring)=letlow=Bigarray.Array2.slice_leftmul_table_low(c|>int_of_char)inlethigh=Bigarray.Array2.slice_leftmul_table_high(c|>int_of_char)inassert(Bigstring.lengthinput=Bigstring.lengthout);letsize=Bigstring.lengthinputinletbytes_done=(Unsigned.Size_t.to_int(reedsolomon_gal_mul_xor(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1low))(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1high))(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1input))(coerce(ptrchar)(ptruint8_t)(bigarray_startarray1out))(Unsigned.Size_t.of_intsize)))inmul_slice_xor_pure_ocaml~skip_to:bytes_donecinputout