87
87
88
88
let init_state = Closed 0L
89
89
90
+ let count_nls s =
91
+ String. fold_right (fun c count -> if c = '\n' then 1 + count else count) s 0
92
+
90
93
let next_state c s = match c,s with
91
94
| Open_text , Closed _l ->
92
95
Open { position = 0L ;
@@ -123,30 +126,45 @@ struct
123
126
| Set_buffered b , Open { position; length; buffered = _ ; binary_mode } ->
124
127
Open { position; length; buffered = b; binary_mode }
125
128
(* output on open Out_channel *)
126
- | Output_char _, Open { position; length; buffered; binary_mode }
129
+ | Output_char c , Open { position; length; buffered; binary_mode } ->
130
+ let len = (* Windows text mode maps '\n' to "\r\n" *)
131
+ if (Sys. win32 || Sys. cygwin) && not binary_mode && c = '\n' then 2L else 1L in
132
+ Open { position = Int64. add position len;
133
+ length = Int64. add length len;
134
+ buffered;
135
+ binary_mode; }
127
136
| Output_byte _ , Open { position; length; buffered; binary_mode } ->
128
137
Open { position = Int64. succ position;
129
138
length = Int64. succ length;
130
139
buffered;
131
140
binary_mode; }
132
141
| Output_string str , Open { position; length; buffered; binary_mode } ->
133
- let len = Int64. of_int (String. length str) in
134
- Open { position = Int64. add position len;
135
- length = Int64. add length len;
136
- buffered;
137
- binary_mode; }
142
+ let len = (* Windows text mode maps '\n' to "\r\n" *)
143
+ if (Sys. win32 || Sys. cygwin) && not binary_mode
144
+ then Int64. of_int (String. length str + count_nls str)
145
+ else Int64. of_int (String. length str) in
146
+ Open { position = Int64. add position len;
147
+ length = Int64. add length len;
148
+ buffered;
149
+ binary_mode; }
138
150
| Output_bytes b , Open { position; length; buffered; binary_mode } ->
139
- let len = Int64. of_int (Bytes. length b) in
140
- Open { position = Int64. add position len;
141
- length = Int64. add length len;
142
- buffered;
143
- binary_mode; }
151
+ let len = (* Windows text mode maps '\n' to "\r\n" *)
152
+ if (Sys. win32 || Sys. cygwin) && not binary_mode
153
+ then Int64. of_int (Bytes. length b + count_nls (String. of_bytes b))
154
+ else Int64. of_int (Bytes. length b) in
155
+ Open { position = Int64. add position len;
156
+ length = Int64. add length len;
157
+ buffered;
158
+ binary_mode; }
144
159
| Output (b ,p ,l ), Open { position; length; buffered; binary_mode } ->
145
160
let bytes_len = Bytes. length b in
146
161
if p < 0 || p > = bytes_len || l < 0 || p+ l > bytes_len
147
162
then s
148
163
else
149
- let len = Int64. of_int l in
164
+ let len = (* Windows text mode maps '\n' to "\r\n" *)
165
+ if (Sys. win32 || Sys. cygwin) && not binary_mode
166
+ then Int64. of_int (l + count_nls String. (sub (of_bytes b) p l))
167
+ else Int64. of_int l in
150
168
Open { position = Int64. add position len;
151
169
length = Int64. add length len;
152
170
buffered;
@@ -156,7 +174,10 @@ struct
156
174
if p < 0 || p > = str_len || l < 0 || p+ l > str_len
157
175
then s
158
176
else
159
- let len = Int64. of_int l in
177
+ let len = (* Windows text mode maps '\n' to "\r\n" *)
178
+ if (Sys. win32 || Sys. cygwin) && not binary_mode
179
+ then Int64. of_int (l + count_nls (String. sub str p l))
180
+ else Int64. of_int l in
160
181
Open { position = Int64. add position len;
161
182
length = Int64. add length len;
162
183
buffered;
0 commit comments