1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253letbytes_conversion_table=[["B";"bytes"],1L]letreclong_power(l:int64)(n:int):int64=ifn=0then1LelseInt64.mull@@long_powerl(n-1);;letdecimal_conversion_table=[["kB";"KB";"kilobytes"],1_000L;["MB";"megabytes"],long_power1_000L2;["GB";"gigabytes"],long_power1_000L3;["TB";"terabytes"],long_power1_000L4];;letbinary_conversion_table=[["KiB";"KiB";"kibibytes"],1024L;["MiB";"mebibytes"],long_power1024L2;["GiB";"gibibytes"],long_power1024L3;["TiB";"tebibytes"],long_power1024L4];;(* When printing we only use this conversion table *)letconversion_table=bytes_conversion_table@decimal_conversion_tableletppx=(* We go through the list to find the first unit that is greater than the
number of bytes and take the predecessor as the units for printing. For the
special base case where no conversion is necessary we don't print as a
float. *)letsuffix,value=letrecloop=function|[]->assertfalse|[(units,value)]->List.hdunits,value|(units,value)::((_,value')::_asl)->ifx=0LthenList.hdunits,valueelseifvalue<=x&&x<value'thenList.hdunits,valueelselooplinloop@@conversion_tableinifvalue=1LthenPrintf.sprintf"%Ld%s"xsuffixelsePrintf.sprintf"%.2f%s"(Int64.to_floatx/.Int64.to_floatvalue)suffix;;(* When parsing we accept all units *)letconversion_table=bytes_conversion_table@decimal_conversion_table@binary_conversion_table|>List.sort~compare:(fun(_,x)(_,y)->Ordering.of_int@@Int64.comparexy);;