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