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