File: unsafe_write_c.ml

package info (click to toggle)
bin-prot 1.2.23-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 620 kB
  • ctags: 1,699
  • sloc: ml: 5,126; ansic: 1,586; makefile: 121
file content (182 lines) | stat: -rw-r--r-- 6,506 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
(* File: unsafe_write_c.ml

    Copyright (C) 2007-

      Jane Street Holding, LLC
      Author: Markus Mottl
      email: mmottl\@janestreet.com
      WWW: http://www.janestreet.com/ocaml

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*)

(* Unsafe_write_c: writing values to the binary protocol using unsafe C. *)

open Bigarray

open Common
open Unsafe_common

type 'a writer = sptr -> eptr -> 'a -> sptr
type ('a, 'b) writer1 = 'a writer -> 'b writer
type ('a, 'b, 'c) writer2 = 'a writer -> ('b, 'c) writer1
type ('a, 'b, 'c, 'd) writer3 = 'a writer -> ('b, 'c, 'd) writer2

external bin_write_unit : sptr -> eptr -> unit -> sptr = "write_small_int_stub"
external bin_write_bool : sptr -> eptr -> bool -> sptr = "write_small_int_stub"
external bin_write_string : sptr -> eptr -> string -> sptr = "write_string_stub"
external bin_write_char : sptr -> eptr -> char -> sptr = "write_small_int_stub"
external bin_write_int : sptr -> eptr -> int -> sptr = "write_int_stub"
external bin_write_float : sptr -> eptr -> float -> sptr = "write_float_stub"
external bin_write_int32 : sptr -> eptr -> int32 -> sptr = "write_int32_stub"
external bin_write_int64 : sptr -> eptr -> int64 -> sptr = "write_int64_stub"

external bin_write_nativeint :
  sptr -> eptr -> nativeint -> sptr = "write_nativeint_stub"

external bin_write_nat0 :
  sptr -> eptr -> Nat0.t -> sptr = "write_nat0_stub"

let bin_write_ref bin_write_el sptr eptr r = bin_write_el sptr eptr !r

let bin_write_lazy bin_write_el sptr eptr lv =
  let v = Lazy.force lv in
  bin_write_el sptr eptr v

let bin_write_option bin_write_el sptr eptr = function
  | None -> bin_write_bool sptr eptr false
  | Some v ->
      let new_sptr = bin_write_bool sptr eptr true in
      bin_write_el new_sptr eptr v

let bin_write_pair bin_write_a bin_write_b sptr eptr (a, b) =
  let new_sptr = bin_write_a sptr eptr a in
  bin_write_b new_sptr eptr b

let bin_write_triple bin_write_a bin_write_b bin_write_c sptr eptr (a, b, c) =
  let new_sptr1 = bin_write_a sptr eptr a in
  let new_sptr2 = bin_write_b new_sptr1 eptr b in
  bin_write_c new_sptr2 eptr c

let bin_write_list bin_write_el sptr eptr lst =
  let rec loop els_sptr = function
    | [] -> els_sptr
    | h :: t ->
        let new_els_sptr = bin_write_el els_sptr eptr h in
        loop new_els_sptr t
  in
  let plen = Nat0.unsafe_of_int (List.length lst) in
  let els_sptr = bin_write_nat0 sptr eptr plen in
  loop els_sptr lst

let bin_write_array_loop bin_write_el sptr eptr ar n =
  let els_sptr_ref = ref sptr in
  for i = 0 to n - 1 do
    let el = Array.unsafe_get ar i in
    let new_els_sptr = bin_write_el !els_sptr_ref eptr el in
    els_sptr_ref := new_els_sptr
  done;
  !els_sptr_ref

let bin_write_array bin_write_el sptr eptr ar =
  let n = Array.length ar in
  let pn = Nat0.unsafe_of_int n in
  let els_sptr = bin_write_nat0 sptr eptr pn in
  bin_write_array_loop bin_write_el els_sptr eptr ar n

let bin_write_hashtbl bin_write_key bin_write_val sptr eptr htbl =
  let len = Hashtbl.length htbl in
  let plen = Nat0.unsafe_of_int len in
  let els_sptr = bin_write_nat0 sptr eptr plen in
  let cnt_ref = ref 0 in
  let coll_htbl k v els_sptr =
    incr cnt_ref;
    let new_els_sptr = bin_write_key els_sptr eptr k in
    bin_write_val new_els_sptr eptr v
  in
  let res_sptr = Hashtbl.fold coll_htbl htbl els_sptr in
  if !cnt_ref <> len then raise_concurrent_modification "bin_write_hashtbl";
  res_sptr

external bin_write_float32_vec :
  sptr -> eptr -> vec32 -> sptr = "write_float32_vec_stub"

external bin_write_float64_vec :
  sptr -> eptr -> vec64 -> sptr = "write_float64_vec_stub"

external bin_write_vec : sptr -> eptr -> vec -> sptr = "write_float64_vec_stub"

external bin_write_float32_mat :
  sptr -> eptr -> mat32 -> sptr = "write_float32_mat_stub"

external bin_write_float64_mat :
  sptr -> eptr -> mat64 -> sptr = "write_float64_mat_stub"

external bin_write_mat : sptr -> eptr -> mat -> sptr = "write_float64_mat_stub"

external bin_write_bigstring :
  sptr -> eptr -> buf -> sptr = "write_bigstring_stub"

external bin_write_float_array :
  sptr -> eptr -> float array -> sptr = "write_float_array_stub"

external bin_write_variant_tag :
  sptr -> eptr -> [> ] -> sptr = "write_variant_tag_stub"

external bin_write_raw_string :
  sptr -> eptr -> string -> pos : int -> len : int -> sptr
  = "write_raw_string_stub"

let bin_write_raw_string sptr eptr str ~pos ~len =
  if pos < 0 then
    failwith "Bin_prot.unsafe_write_c.bin_write_raw_string: pos < 0"
  else if len < 0 then
    failwith "Bin_prot.unsafe_write_c.bin_write_raw_string: len < 0"
  else if pos + len > String.length str then
    failwith "Bin_prot.unsafe_write_c.bin_write_raw_string: pos + len > str_len"
  else bin_write_raw_string sptr eptr str ~pos ~len

external bin_write_int_8bit :
  sptr -> eptr -> int -> sptr = "write_int_8bit_stub"

external bin_write_int_16bit :
  sptr -> eptr -> int -> sptr = "write_int_16bit_stub"

external bin_write_int_32bit :
  sptr -> eptr -> int -> sptr = "write_int_32bit_stub"

external bin_write_int_64bit :
  sptr -> eptr -> int -> sptr = "write_int_64bit_stub"

external bin_write_int64_bits :
  sptr -> eptr -> int64 -> sptr = "write_int64_bits_stub"

external bin_write_network16_int :
  sptr -> eptr -> int -> sptr = "write_network16_int_stub"

external bin_write_network32_int :
  sptr -> eptr -> int -> sptr = "write_network32_int_stub"

external bin_write_network32_int32 :
  sptr -> eptr -> int32 -> sptr = "write_network32_int32_stub"

external bin_write_network64_int :
  sptr -> eptr -> int -> sptr = "write_network64_int_stub"

external bin_write_network64_int64 :
  sptr -> eptr -> int64 -> sptr = "write_network64_int64_stub"

let bin_write_array_no_length bin_write_el sptr eptr ar =
  bin_write_array_loop bin_write_el sptr eptr ar (Array.length ar)