1Bytes(3)                         OCaml library                        Bytes(3)
2
3
4

NAME

6       Bytes - Byte sequence operations.
7

Module

9       Module   Bytes
10

Documentation

12       Module Bytes
13        : sig end
14
15
16       Byte sequence operations.
17
18       A   byte   sequence  is  a  mutable  data  structure  that  contains  a
19       fixed-length sequence of bytes. Each byte can be  indexed  in  constant
20       time for reading or writing.
21
22       Given a byte sequence s of length l , we can access each of the l bytes
23       of s via its index in the sequence. Indexes start at 0 ,  and  we  will
24       call an index valid in s if it falls within the range [0...l-1] (inclu‐
25       sive). A position is the point between two bytes or at the beginning or
26       end  of the sequence.  We call a position valid in s if it falls within
27       the range [0...l] (inclusive). Note that the byte at index n is between
28       positions n and n+1 .
29
30       Two  parameters  start and len are said to designate a valid range of s
31       if len >= 0 and start and start+len are valid positions in s .
32
33       Byte sequences can be modified in place, for instance via the  set  and
34       blit  functions  described  below.   See also strings (module String ),
35       which are almost the same data structure, but  cannot  be  modified  in
36       place.
37
38       Bytes are represented by the OCaml type char .
39
40       The labeled version of this module can be used as described in the Std‐
41       Labels module.
42
43
44       Since 4.02.0
45
46
47
48
49
50
51       val length : bytes -> int
52
53       Return the length (number of bytes) of the argument.
54
55
56
57       val get : bytes -> int -> char
58
59
60       get s n returns the byte at index n in argument s .
61
62
63       Raises Invalid_argument if n is not a valid index in s .
64
65
66
67       val set : bytes -> int -> char -> unit
68
69
70       set s n c modifies s in place, replacing the byte at index n with c .
71
72
73       Raises Invalid_argument if n is not a valid index in s .
74
75
76
77       val create : int -> bytes
78
79
80       create n returns a new byte sequence of length  n  .  The  sequence  is
81       uninitialized and contains arbitrary bytes.
82
83
84       Raises Invalid_argument if n < 0 or n > Sys.max_string_length .
85
86
87
88       val make : int -> char -> bytes
89
90
91       make n c returns a new byte sequence of length n , filled with the byte
92       c .
93
94
95       Raises Invalid_argument if n < 0 or n > Sys.max_string_length .
96
97
98
99       val init : int -> (int -> char) -> bytes
100
101
102       init n f returns a fresh byte sequence of length n , with  character  i
103       initialized to the result of f i (in increasing index order).
104
105
106       Raises Invalid_argument if n < 0 or n > Sys.max_string_length .
107
108
109
110       val empty : bytes
111
112       A byte sequence of size 0.
113
114
115
116       val copy : bytes -> bytes
117
118       Return  a  new  byte sequence that contains the same bytes as the argu‐
119       ment.
120
121
122
123       val of_string : string -> bytes
124
125       Return a new byte sequence that contains the same bytes  as  the  given
126       string.
127
128
129
130       val to_string : bytes -> string
131
132       Return  a new string that contains the same bytes as the given byte se‐
133       quence.
134
135
136
137       val sub : bytes -> int -> int -> bytes
138
139
140       sub s pos len returns a new byte sequence of length  len  ,  containing
141       the subsequence of s that starts at position pos and has length len .
142
143
144       Raises  Invalid_argument  if pos and len do not designate a valid range
145       of s .
146
147
148
149       val sub_string : bytes -> int -> int -> string
150
151       Same as Bytes.sub but return a string instead of a byte sequence.
152
153
154
155       val extend : bytes -> int -> int -> bytes
156
157
158       extend s left right returns a new byte sequence that contains the bytes
159       of  s , with left uninitialized bytes prepended and right uninitialized
160       bytes appended to it. If left or right is negative, then bytes are  re‐
161       moved (instead of appended) from the corresponding side of s .
162
163
164       Since 4.05.0 in BytesLabels
165
166
167       Raises Invalid_argument if the result length is negative or longer than
168       Sys.max_string_length bytes.
169
170
171
172       val fill : bytes -> int -> int -> char -> unit
173
174
175       fill s pos len c modifies s in place, replacing len characters with c ,
176       starting at pos .
177
178
179       Raises  Invalid_argument  if pos and len do not designate a valid range
180       of s .
181
182
183
184       val blit : bytes -> int -> bytes -> int -> int -> unit
185
186
187       blit src src_pos dst dst_pos len copies len bytes from sequence  src  ,
188       starting at index src_pos , to sequence dst , starting at index dst_pos
189       . It works correctly even if src and dst are the  same  byte  sequence,
190       and the source and destination intervals overlap.
191
192
193       Raises  Invalid_argument  if  src_pos  and len do not designate a valid
194       range of src , or if dst_pos and len do not designate a valid range  of
195       dst .
196
197
198
199       val blit_string : string -> int -> bytes -> int -> int -> unit
200
201
202       blit  src  src_pos  dst  dst_pos len copies len bytes from string src ,
203       starting at index src_pos , to byte sequence dst ,  starting  at  index
204       dst_pos .
205
206
207       Since 4.05.0 in BytesLabels
208
209
210       Raises  Invalid_argument  if  src_pos  and len do not designate a valid
211       range of src , or if dst_pos and len do not designate a valid range  of
212       dst .
213
214
215
216       val concat : bytes -> bytes list -> bytes
217
218
219       concat  sep  sl  concatenates the list of byte sequences sl , inserting
220       the separator byte sequence sep between each, and returns the result as
221       a new byte sequence.
222
223
224       Raises    Invalid_argument    if    the    result    is   longer   than
225       Sys.max_string_length bytes.
226
227
228
229       val cat : bytes -> bytes -> bytes
230
231
232       cat s1 s2 concatenates s1 and s2 and returns the result as a  new  byte
233       sequence.
234
235
236       Since 4.05.0 in BytesLabels
237
238
239       Raises    Invalid_argument    if    the    result    is   longer   than
240       Sys.max_string_length bytes.
241
242
243
244       val iter : (char -> unit) -> bytes -> unit
245
246
247       iter f s applies function f in turn to all the bytes  of  s  .   It  is
248       equivalent to f (get s 0); f (get s 1); ...; f (get s
249           (length s - 1)); () .
250
251
252
253       val iteri : (int -> char -> unit) -> bytes -> unit
254
255       Same  as  Bytes.iter  , but the function is applied to the index of the
256       byte as first argument and the byte itself as second argument.
257
258
259
260       val map : (char -> char) -> bytes -> bytes
261
262
263       map f s applies function f in turn to all the bytes of s (in increasing
264       index  order)  and stores the resulting bytes in a new sequence that is
265       returned as the result.
266
267
268
269       val mapi : (int -> char -> char) -> bytes -> bytes
270
271
272       mapi f s calls f with each character of s and its index (in  increasing
273       index  order)  and stores the resulting bytes in a new sequence that is
274       returned as the result.
275
276
277
278       val fold_left : ('a -> char -> 'a) -> 'a -> bytes -> 'a
279
280
281       fold_left f x s computes f (... (f (f x (get s 0)) (get s 1)) ...) (get
282       s (n-1)) , where n is the length of s .
283
284
285       Since 4.13.0
286
287
288
289       val fold_right : (char -> 'a -> 'a) -> bytes -> 'a -> 'a
290
291
292       fold_right  f  s  x  computes  f (get s 0) (f (get s 1) ( ... (f (get s
293       (n-1)) x) ...))  , where n is the length of s .
294
295
296       Since 4.13.0
297
298
299
300       val for_all : (char -> bool) -> bytes -> bool
301
302
303       for_all p s checks if all characters in s satisfy the predicate p .
304
305
306       Since 4.13.0
307
308
309
310       val exists : (char -> bool) -> bytes -> bool
311
312
313       exists p s checks if at least one character of s satisfies  the  predi‐
314       cate p .
315
316
317       Since 4.13.0
318
319
320
321       val trim : bytes -> bytes
322
323       Return a copy of the argument, without leading and trailing whitespace.
324       The bytes regarded as whitespace are the ASCII characters ' ' ,  '\012'
325       , '\n' , '\r' , and '\t' .
326
327
328
329       val escaped : bytes -> bytes
330
331       Return  a  copy of the argument, with special characters represented by
332       escape sequences, following the  lexical  conventions  of  OCaml.   All
333       characters  outside the ASCII printable range (32..126) are escaped, as
334       well as backslash and double-quote.
335
336
337       Raises   Invalid_argument   if    the    result    is    longer    than
338       Sys.max_string_length bytes.
339
340
341
342       val index : bytes -> char -> int
343
344
345       index s c returns the index of the first occurrence of byte c in s .
346
347
348       Raises Not_found if c does not occur in s .
349
350
351
352       val index_opt : bytes -> char -> int option
353
354
355       index_opt  s c returns the index of the first occurrence of byte c in s
356       or None if c does not occur in s .
357
358
359       Since 4.05
360
361
362
363       val rindex : bytes -> char -> int
364
365
366       rindex s c returns the index of the last occurrence of byte c in s .
367
368
369       Raises Not_found if c does not occur in s .
370
371
372
373       val rindex_opt : bytes -> char -> int option
374
375
376       rindex_opt s c returns the index of the last occurrence of byte c in  s
377       or None if c does not occur in s .
378
379
380       Since 4.05
381
382
383
384       val index_from : bytes -> int -> char -> int
385
386
387       index_from s i c returns the index of the first occurrence of byte c in
388       s after position i .  index s c is equivalent to index_from s 0 c .
389
390
391       Raises Invalid_argument if i is not a valid position in s .
392
393
394       Raises Not_found if c does not occur in s after position i .
395
396
397
398       val index_from_opt : bytes -> int -> char -> int option
399
400
401       index_from_opt s i c returns the index of the first occurrence of  byte
402       c in s after position i or None if c does not occur in s after position
403       i .  index_opt s c is equivalent to index_from_opt s 0 c .
404
405
406       Since 4.05
407
408
409       Raises Invalid_argument if i is not a valid position in s .
410
411
412
413       val rindex_from : bytes -> int -> char -> int
414
415
416       rindex_from s i c returns the index of the last occurrence of byte c in
417       s  before  position  i+1  .   rindex s c is equivalent to rindex_from s
418       (length s - 1) c .
419
420
421       Raises Invalid_argument if i+1 is not a valid position in s .
422
423
424       Raises Not_found if c does not occur in s before position i+1 .
425
426
427
428       val rindex_from_opt : bytes -> int -> char -> int option
429
430
431       rindex_from_opt s i c returns the index of the last occurrence of  byte
432       c  in s before position i+1 or None if c does not occur in s before po‐
433       sition i+1 .  rindex_opt s c is equivalent to rindex_from s (length s -
434       1) c .
435
436
437       Since 4.05
438
439
440       Raises Invalid_argument if i+1 is not a valid position in s .
441
442
443
444       val contains : bytes -> char -> bool
445
446
447       contains s c tests if byte c appears in s .
448
449
450
451       val contains_from : bytes -> int -> char -> bool
452
453
454       contains_from  s  start  c  tests if byte c appears in s after position
455       start .  contains s c is equivalent to contains_from
456           s 0 c .
457
458
459       Raises Invalid_argument if start is not a valid position in s .
460
461
462
463       val rcontains_from : bytes -> int -> char -> bool
464
465
466       rcontains_from s stop c tests if byte c appears in  s  before  position
467       stop+1 .
468
469
470       Raises  Invalid_argument  if stop < 0 or stop+1 is not a valid position
471       in s .
472
473
474
475       val uppercase_ascii : bytes -> bytes
476
477       Return a copy of the argument, with all lowercase letters translated to
478       uppercase, using the US-ASCII character set.
479
480
481       Since 4.03.0 (4.05.0 in BytesLabels)
482
483
484
485       val lowercase_ascii : bytes -> bytes
486
487       Return a copy of the argument, with all uppercase letters translated to
488       lowercase, using the US-ASCII character set.
489
490
491       Since 4.03.0 (4.05.0 in BytesLabels)
492
493
494
495       val capitalize_ascii : bytes -> bytes
496
497       Return a copy of the argument, with the first character set  to  upper‐
498       case, using the US-ASCII character set.
499
500
501       Since 4.03.0 (4.05.0 in BytesLabels)
502
503
504
505       val uncapitalize_ascii : bytes -> bytes
506
507       Return  a  copy of the argument, with the first character set to lower‐
508       case, using the US-ASCII character set.
509
510
511       Since 4.03.0 (4.05.0 in BytesLabels)
512
513
514       type t = bytes
515
516
517       An alias for the type of byte sequences.
518
519
520
521       val compare : t -> t -> int
522
523       The comparison function for byte sequences, with the same specification
524       as  compare .  Along with the type t , this function compare allows the
525       module Bytes to be passed as argument  to  the  functors  Set.Make  and
526       Map.Make .
527
528
529
530       val equal : t -> t -> bool
531
532       The equality function for byte sequences.
533
534
535       Since 4.03.0 (4.05.0 in BytesLabels)
536
537
538
539       val starts_with : prefix:bytes -> bytes -> bool
540
541
542       starts_with ~prefix s is true if and only if s starts with prefix .
543
544
545       Since 4.13.0
546
547
548
549       val ends_with : suffix:bytes -> bytes -> bool
550
551
552       ends_with ~suffix s is true if and only if s ends with suffix .
553
554
555       Since 4.13.0
556
557
558
559
560   Unsafe conversions (for advanced users)
561       This  section  describes unsafe, low-level conversion functions between
562       bytes and string . They do not copy the internal data; used improperly,
563       they  can  break  the immutability invariant on strings provided by the
564       -safe-string option. They are available for expert library authors, but
565       for most purposes you should use the always-correct Bytes.to_string and
566       Bytes.of_string instead.
567
568       val unsafe_to_string : bytes -> string
569
570       Unsafely convert a byte sequence into a string.
571
572       To reason about the use of unsafe_to_string , it is convenient to  con‐
573       sider  an "ownership" discipline. A piece of code that manipulates some
574       data "owns" it; there are several disjoint ownership modes, including:
575
576       -Unique ownership: the data may be accessed and mutated
577
578       -Shared ownership: the data has several owners, that  may  only  access
579       it, not mutate it.
580
581       Unique  ownership  is linear: passing the data to another piece of code
582       means giving up ownership (we cannot write the data  again).  A  unique
583       owner  may decide to make the data shared (giving up mutation rights on
584       it), but shared data may not become uniquely-owned again.
585
586
587       unsafe_to_string s can only be used when the caller owns the  byte  se‐
588       quence  s  --  either  uniquely or as shared immutable data. The caller
589       gives up ownership of s , and gains ownership of the returned string.
590
591       There are two valid use-cases that respect this ownership discipline:
592
593       1. Creating a string by initializing and mutating a byte sequence  that
594       is never changed after initialization is performed.
595
596
597       let string_init len f : string =
598         let s = Bytes.create len in
599         for i = 0 to len - 1 do Bytes.set s i (f i) done;
600         Bytes.unsafe_to_string s
601
602
603       This  function  is  safe  because the byte sequence s will never be ac‐
604       cessed or mutated after unsafe_to_string  is  called.  The  string_init
605       code gives up ownership of s , and returns the ownership of the result‐
606       ing string to its caller.
607
608       Note that it would be unsafe if s was passed as an additional parameter
609       to the function f as it could escape this way and be mutated in the fu‐
610       ture -- string_init would give up ownership of s to pass it to f ,  and
611       could not call unsafe_to_string safely.
612
613       We have provided the String.init , String.map and String.mapi functions
614       to cover most cases of building new strings. You  should  prefer  those
615       over to_string or unsafe_to_string whenever applicable.
616
617       2.  Temporarily  giving ownership of a byte sequence to a function that
618       expects a uniquely owned string and returns ownership back, so that  we
619       can mutate the sequence again after the call ended.
620
621
622       let bytes_length (s : bytes) =
623         String.length (Bytes.unsafe_to_string s)
624
625
626       In  this use-case, we do not promise that s will never be mutated after
627       the call to bytes_length s .  The  String.length  function  temporarily
628       borrows  unique ownership of the byte sequence (and sees it as a string
629       ), but returns this ownership back to the caller, which may assume that
630       s is still a valid byte sequence after the call. Note that this is only
631       correct because we know that String.length does not capture  its  argu‐
632       ment  -- it could escape by a side-channel such as a memoization combi‐
633       nator.
634
635       The caller may not mutate s while the string is borrowed (it has tempo‐
636       rarily  given up ownership). This affects concurrent programs, but also
637       higher-order functions: if  String.length  returned  a  closure  to  be
638       called  later,  s should not be mutated until this closure is fully ap‐
639       plied and returns ownership.
640
641
642
643       val unsafe_of_string : string -> bytes
644
645       Unsafely convert a shared string to a byte sequence that should not  be
646       mutated.
647
648       The  same  ownership discipline that makes unsafe_to_string correct ap‐
649       plies to unsafe_of_string : you may use it if you were the owner of the
650       string value, and you will own the return bytes in the same mode.
651
652       In  practice,  unique ownership of string values is extremely difficult
653       to reason about correctly. You should always assume strings are shared,
654       never uniquely owned.
655
656       For  example, string literals are implicitly shared by the compiler, so
657       you never uniquely own them.
658
659
660       let incorrect = Bytes.unsafe_of_string "hello"
661       let s = Bytes.of_string "hello"
662
663
664       The first declaration is incorrect, because the string literal  "hello"
665       could  be  shared  by the compiler with other parts of the program, and
666       mutating incorrect is a bug. You must always use  the  second  version,
667       which performs a copy and is thus correct.
668
669       Assuming  unique ownership of strings that are not string literals, but
670       are (partly) built from string literals, is also incorrect.  For  exam‐
671       ple,  mutating  unsafe_of_string  ("foo"  ^  s) could mutate the shared
672       string "foo" -- assuming a rope-like representation  of  strings.  More
673       generally, functions operating on strings will assume shared ownership,
674       they do not preserve unique ownership. It is thus incorrect  to  assume
675       unique ownership of the result of unsafe_of_string .
676
677       The  only case we have reasonable confidence is safe is if the produced
678       bytes is shared -- used as an immutable byte sequence. This is possibly
679       useful  for incremental migration of low-level programs that manipulate
680       immutable sequences of bytes (for example Marshal.from_bytes ) and pre‐
681       viously used the string type for this purpose.
682
683
684
685       val split_on_char : char -> bytes -> bytes list
686
687
688       split_on_char  sep  s  returns  the list of all (possibly empty) subse‐
689       quences of s that are delimited by the sep character.
690
691       The function's output is specified by the following invariants:
692
693
694       -The list is not empty.
695
696       -Concatenating its elements using sep as a separator returns a byte se‐
697       quence equal to the input ( Bytes.concat (Bytes.make 1 sep)
698             (Bytes.split_on_char sep s) = s ).
699
700       -No byte sequence in the result contains the sep character.
701
702
703
704       Since 4.13.0
705
706
707
708
709   Iterators
710       val to_seq : t -> char Seq.t
711
712       Iterate  on the string, in increasing index order. Modifications of the
713       string during iteration will be reflected in the sequence.
714
715
716       Since 4.07
717
718
719
720       val to_seqi : t -> (int * char) Seq.t
721
722       Iterate on the string, in  increasing  order,  yielding  indices  along
723       chars
724
725
726       Since 4.07
727
728
729
730       val of_seq : char Seq.t -> t
731
732       Create a string from the generator
733
734
735       Since 4.07
736
737
738
739
740   UTF codecs and validations
741   UTF-8
742       val get_utf_8_uchar : t -> int -> Uchar.utf_decode
743
744
745       get_utf_8_uchar b i decodes an UTF-8 character at index i in b .
746
747
748
749       val set_utf_8_uchar : t -> int -> Uchar.t -> int
750
751
752       set_utf_8_uchar  b  i u UTF-8 encodes u at index i in b and returns the
753       number of bytes n that were written starting at i . If n is 0 there was
754       not enough space to encode u at i and b was left untouched. Otherwise a
755       new character can be encoded at i + n .
756
757
758
759       val is_valid_utf_8 : t -> bool
760
761
762       is_valid_utf_8 b is true if and only if b contains valid UTF-8 data.
763
764
765
766
767   UTF-16BE
768       val get_utf_16be_uchar : t -> int -> Uchar.utf_decode
769
770
771       get_utf_16be_uchar b i decodes an UTF-16BE character at index i in b .
772
773
774
775       val set_utf_16be_uchar : t -> int -> Uchar.t -> int
776
777
778       set_utf_16be_uchar b i u UTF-16BE encodes u at index i in b and returns
779       the number of bytes n that were written starting at i . If n is 0 there
780       was not enough space to encode u at i and b was left untouched.  Other‐
781       wise a new character can be encoded at i + n .
782
783
784
785       val is_valid_utf_16be : t -> bool
786
787
788       is_valid_utf_16be  b  is  true if and only if b contains valid UTF-16BE
789       data.
790
791
792
793
794   UTF-16LE
795       val get_utf_16le_uchar : t -> int -> Uchar.utf_decode
796
797
798       get_utf_16le_uchar b i decodes an UTF-16LE character at index i in b .
799
800
801
802       val set_utf_16le_uchar : t -> int -> Uchar.t -> int
803
804
805       set_utf_16le_uchar b i u UTF-16LE encodes u at index i in b and returns
806       the number of bytes n that were written starting at i . If n is 0 there
807       was not enough space to encode u at i and b was left untouched.  Other‐
808       wise a new character can be encoded at i + n .
809
810
811
812       val is_valid_utf_16le : t -> bool
813
814
815       is_valid_utf_16le  b  is  true if and only if b contains valid UTF-16LE
816       data.
817
818
819
820
821   Binary encoding/decoding of integers
822       The functions in this section binary encode and decode integers to  and
823       from byte sequences.
824
825       All  following  functions raise Invalid_argument if the space needed at
826       index i to decode or encode the integer is not available.
827
828       Little-endian (resp. big-endian) encoding means that least (resp. most)
829       significant  bytes  are stored first.  Big-endian is also known as net‐
830       work byte order.  Native-endian encoding  is  either  little-endian  or
831       big-endian depending on Sys.big_endian .
832
833       32-bit  and  64-bit  integers  are  represented  by the int32 and int64
834       types, which can be interpreted either as signed or unsigned numbers.
835
836       8-bit and 16-bit integers are represented by the int  type,  which  has
837       more  bits  than  the binary encoding.  These extra bits are handled as
838       follows:
839
840       -Functions that decode signed (resp. unsigned) 8-bit or 16-bit integers
841       represented by int values sign-extend (resp. zero-extend) their result.
842
843       -Functions that encode 8-bit or 16-bit integers represented by int val‐
844       ues truncate their input to their least significant bytes.
845
846
847       val get_uint8 : bytes -> int -> int
848
849
850       get_uint8 b i is b 's unsigned 8-bit integer starting at byte index i .
851
852
853       Since 4.08
854
855
856
857       val get_int8 : bytes -> int -> int
858
859
860       get_int8 b i is b 's signed 8-bit integer starting at byte index i .
861
862
863       Since 4.08
864
865
866
867       val get_uint16_ne : bytes -> int -> int
868
869
870       get_uint16_ne b i is b 's native-endian unsigned 16-bit integer  start‐
871       ing at byte index i .
872
873
874       Since 4.08
875
876
877
878       val get_uint16_be : bytes -> int -> int
879
880
881       get_uint16_be  b  i is b 's big-endian unsigned 16-bit integer starting
882       at byte index i .
883
884
885       Since 4.08
886
887
888
889       val get_uint16_le : bytes -> int -> int
890
891
892       get_uint16_le b i is b 's little-endian unsigned 16-bit integer  start‐
893       ing at byte index i .
894
895
896       Since 4.08
897
898
899
900       val get_int16_ne : bytes -> int -> int
901
902
903       get_int16_ne  b  i is b 's native-endian signed 16-bit integer starting
904       at byte index i .
905
906
907       Since 4.08
908
909
910
911       val get_int16_be : bytes -> int -> int
912
913
914       get_int16_be b i is b 's big-endian signed 16-bit integer  starting  at
915       byte index i .
916
917
918       Since 4.08
919
920
921
922       val get_int16_le : bytes -> int -> int
923
924
925       get_int16_le  b  i is b 's little-endian signed 16-bit integer starting
926       at byte index i .
927
928
929       Since 4.08
930
931
932
933       val get_int32_ne : bytes -> int -> int32
934
935
936       get_int32_ne b i is b 's native-endian 32-bit integer starting at  byte
937       index i .
938
939
940       Since 4.08
941
942
943
944       val get_int32_be : bytes -> int -> int32
945
946
947       get_int32_be b i is b 's big-endian 32-bit integer starting at byte in‐
948       dex i .
949
950
951       Since 4.08
952
953
954
955       val get_int32_le : bytes -> int -> int32
956
957
958       get_int32_le b i is b 's little-endian 32-bit integer starting at  byte
959       index i .
960
961
962       Since 4.08
963
964
965
966       val get_int64_ne : bytes -> int -> int64
967
968
969       get_int64_ne  b i is b 's native-endian 64-bit integer starting at byte
970       index i .
971
972
973       Since 4.08
974
975
976
977       val get_int64_be : bytes -> int -> int64
978
979
980       get_int64_be b i is b 's big-endian 64-bit integer starting at byte in‐
981       dex i .
982
983
984       Since 4.08
985
986
987
988       val get_int64_le : bytes -> int -> int64
989
990
991       get_int64_le  b i is b 's little-endian 64-bit integer starting at byte
992       index i .
993
994
995       Since 4.08
996
997
998
999       val set_uint8 : bytes -> int -> int -> unit
1000
1001
1002       set_uint8 b i v sets b 's unsigned 8-bit integer starting at byte index
1003       i to v .
1004
1005
1006       Since 4.08
1007
1008
1009
1010       val set_int8 : bytes -> int -> int -> unit
1011
1012
1013       set_int8  b i v sets b 's signed 8-bit integer starting at byte index i
1014       to v .
1015
1016
1017       Since 4.08
1018
1019
1020
1021       val set_uint16_ne : bytes -> int -> int -> unit
1022
1023
1024       set_uint16_ne b i v sets b 's  native-endian  unsigned  16-bit  integer
1025       starting at byte index i to v .
1026
1027
1028       Since 4.08
1029
1030
1031
1032       val set_uint16_be : bytes -> int -> int -> unit
1033
1034
1035       set_uint16_be b i v sets b 's big-endian unsigned 16-bit integer start‐
1036       ing at byte index i to v .
1037
1038
1039       Since 4.08
1040
1041
1042
1043       val set_uint16_le : bytes -> int -> int -> unit
1044
1045
1046       set_uint16_le b i v sets b 's  little-endian  unsigned  16-bit  integer
1047       starting at byte index i to v .
1048
1049
1050       Since 4.08
1051
1052
1053
1054       val set_int16_ne : bytes -> int -> int -> unit
1055
1056
1057       set_int16_ne b i v sets b 's native-endian signed 16-bit integer start‐
1058       ing at byte index i to v .
1059
1060
1061       Since 4.08
1062
1063
1064
1065       val set_int16_be : bytes -> int -> int -> unit
1066
1067
1068       set_int16_be b i v sets b 's big-endian signed 16-bit integer  starting
1069       at byte index i to v .
1070
1071
1072       Since 4.08
1073
1074
1075
1076       val set_int16_le : bytes -> int -> int -> unit
1077
1078
1079       set_int16_le b i v sets b 's little-endian signed 16-bit integer start‐
1080       ing at byte index i to v .
1081
1082
1083       Since 4.08
1084
1085
1086
1087       val set_int32_ne : bytes -> int -> int32 -> unit
1088
1089
1090       set_int32_ne b i v sets b 's native-endian 32-bit integer  starting  at
1091       byte index i to v .
1092
1093
1094       Since 4.08
1095
1096
1097
1098       val set_int32_be : bytes -> int -> int32 -> unit
1099
1100
1101       set_int32_be b i v sets b 's big-endian 32-bit integer starting at byte
1102       index i to v .
1103
1104
1105       Since 4.08
1106
1107
1108
1109       val set_int32_le : bytes -> int -> int32 -> unit
1110
1111
1112       set_int32_le b i v sets b 's little-endian 32-bit integer  starting  at
1113       byte index i to v .
1114
1115
1116       Since 4.08
1117
1118
1119
1120       val set_int64_ne : bytes -> int -> int64 -> unit
1121
1122
1123       set_int64_ne  b  i v sets b 's native-endian 64-bit integer starting at
1124       byte index i to v .
1125
1126
1127       Since 4.08
1128
1129
1130
1131       val set_int64_be : bytes -> int -> int64 -> unit
1132
1133
1134       set_int64_be b i v sets b 's big-endian 64-bit integer starting at byte
1135       index i to v .
1136
1137
1138       Since 4.08
1139
1140
1141
1142       val set_int64_le : bytes -> int -> int64 -> unit
1143
1144
1145       set_int64_le  b  i v sets b 's little-endian 64-bit integer starting at
1146       byte index i to v .
1147
1148
1149       Since 4.08
1150
1151
1152
1153
1154   Byte sequences and concurrency safety
1155       Care must be taken when concurrently accessing byte sequences from mul‐
1156       tiple  domains:  accessing  a byte sequence will never crash a program,
1157       but  unsynchronized  accesses  might  yield   surprising   (non-sequen‐
1158       tially-consistent) results.
1159
1160
1161   Atomicity
1162       Every  byte  sequence operation that accesses more than one byte is not
1163       atomic. This includes iteration and scanning.
1164
1165       For example, consider the following program:
1166       let size = 100_000_000
1167       let b = Bytes.make size  ' '
1168       let update b f ()  =
1169         Bytes.iteri (fun i x -> Bytes.set b i (Char.chr (f (Char.code x)))) b
1170       let d1 = Domain.spawn (update b (fun x -> x + 1))
1171       let d2 = Domain.spawn (update b (fun x -> 2 * x + 1))
1172       let () = Domain.join d1; Domain.join d2
1173
1174       the bytes sequence b may contain a non-deterministic mixture of  '!'  ,
1175       'A' , 'B' , and 'C' values.
1176
1177       After  executing this code, each byte of the sequence b is either '!' ,
1178       'A' , 'B' , or 'C' . If atomicity is required, then the user  must  im‐
1179       plement their own synchronization (for example, using Mutex.t ).
1180
1181
1182   Data races
1183       If  two domains only access disjoint parts of a byte sequence, then the
1184       observed behaviour is the equivalent to some sequential interleaving of
1185       the operations from the two domains.
1186
1187       A  data  race  is  said  to occur when two domains access the same byte
1188       without synchronization and at least one of the accesses  is  a  write.
1189       In  the  absence of data races, the observed behaviour is equivalent to
1190       some sequential interleaving of the operations from different domains.
1191
1192       Whenever possible, data races should be avoided by  using  synchroniza‐
1193       tion to mediate the accesses to the elements of the sequence.
1194
1195       Indeed,  in the presence of data races, programs will not crash but the
1196       observed behaviour may not be equivalent to any sequential interleaving
1197       of  operations  from different domains. Nevertheless, even in the pres‐
1198       ence of data races, a read operation will  return  the  value  of  some
1199       prior write to that location.
1200
1201
1202   Mixed-size accesses
1203       Another  subtle point is that if a data race involves mixed-size writes
1204       and reads to the same location, the order in  which  those  writes  and
1205       reads are observed by domains is not specified.  For instance, the fol‐
1206       lowing code write sequentially a 32-bit integer and a char to the  same
1207       index
1208       let b = Bytes.make 10 '\000'
1209       let d1 = Domain.spawn (fun () -> Bytes.set_int32_ne b 0 100; b.[0] <- 'd' )
1210
1211
1212       In  this situation, a domain that observes the write of 'd' to b.  0 is
1213       not guaranteed to also observe the write to indices 1 , 2 , or 3 .
1214
1215OCamldoc                          2023-07-20                          Bytes(3)
Impressum