File: ftp_data_endpoint.mli

package info (click to toggle)
netclient 0.91-10
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 2,096 kB
  • ctags: 1,539
  • sloc: ml: 8,808; sh: 527; makefile: 203
file content (234 lines) | stat: -rw-r--r-- 7,916 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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
(* $Id: ftp_data_endpoint.mli 143 2005-07-27 20:32:41Z gerd $ *)

(** Senders and receivers for the FTP data connection *)


(* *********************************************************************)
(** {1 Types and Exceptions} *)


(** An [out_record_channel] can be used to output files with record
 * structure. This is purely abstract, as Unix does not support such
 * files natively, so this kind of channel is usually mapped to a flat
 * representation when stored in a real file, e.g. record boundaries 
 * become newline characters.
 *)
class type out_record_channel =
object
  inherit Netchannels.out_obj_channel
  method output_eor : unit -> unit
    (** Finishes the current record. 
     *
     * The record model is as follows: At the beginning of the channel,
     * or after [output_eor], a new record can be potentially started.
     * However, the record counts only as existing when either at least
     * one byte is output, or the record is explicitly ended with a
     * [output_eor] call.
     *
     * This rule allows it to represent channels containing no records.
     * There is an ambiguity at the end of the channel, however: It is
     * possible that there are characters between the last EOR and the
     * EOF. This could also be represented by printing another EOR just
     * before EOF. The preferred representation is the latter.
     *
     * This model correlates to the usual rules for line-structured
     * files, so think EOR = EOL.
     *)
end

(** An [in_record_channel] can be used to read files with record
 * structure. This is purely abstract, as Unix does not support such
 * files natively, so this kind of channel is usually mapped to a flat
 * representation when stored in a real file, e.g. record boundaries 
 * become newline characters.
 *)
class type in_record_channel =
object
  inherit Netchannels.in_obj_channel
  method input_eor : unit -> unit
    (** Skips over the remaining data of the current record and the
     * record boundary to the next record. Raises [End_of_file] when
     * the current record is the "EOF" record (see below for explanations).
     *
     * A record channel can be read as follows: After opening the channel,
     * one can read the contents of the first record with the [input]
     * method. The end of the record is indicated by an [End_of_file]
     * exception. By calling [input_eor], the next record is opened
     * and can be read.
     *
     * After the last real record, there is always a special 
     * "EOF" record which is empty, and must be ignored by applications
     * processing records. This means, after opening an empty channel,
     * the current record is this "EOF" record, and [input_eor] raises
     * [End_of_file]. After reading a non-empty channel, one can
     * do [input_eor] after the last regular record, and the following
     * [input_eor] raises [End_of_file].
     *)
end

type local_receiver =
    [ `File_structure of Netchannels.out_obj_channel
    | `Record_structure of out_record_channel
    ]
    (** The [local_receiver] is the object that gets the data received
     * over the data connection.
     *
     * Page structure is not supported.
     *)

type local_sender =
    [ `File_structure of Netchannels.in_obj_channel
    | `Record_structure of in_record_channel
    ]
    (** The [local_sender] is the object that provides the data sent
     * over the data connection.
     *
     * Page structure is not supported.
     *)

type transmission_mode =
    [ `Stream_mode
    | `Block_mode
    ]
    (** The transmission mode as described in RFC 959. 
     * Compressed mode is not supported.
     *)


type descr_state =
    [ `Clean
    | `Transfer_in_progress
    | `Down
    ]
    (** Describes the state of the socket used for data transfers.
     * The state [`Clean] means that a new data transfer may be started,
     * either because the socket is new, or the last block transfer was
     * properly finished. The state [`Transfer_in_progress] means that
     * data is being transferred, but also that the transfer is aborted.
     * The state [`Down] means that the socket is already at least half-closed,
     * i.e. EOF was sent in one direction.
     *)

type text_data_repr =
    [ `ASCII      of Netconversion.encoding
    | `ASCII_unix of Netconversion.encoding
    | `EBCDIC     of Netconversion.encoding
    ]
    (** Possible representation of text data:
     * [`ASCII] means an ASCII-compatible encoding where the newline
     * character is represented by CR/LF. [`ASCII_unix] is the same
     * but newline is only LF. [`EBCDIC] is an EBCDIC variant.
     *
     * The argument specifies the exact variant to be used, e.g.
     * [`ASCII `Enc_iso88591] or [`EBCDIC `Enc_cp1047].
     *
     * It is illegal to use [`ASCII] or [`ASCII_unix] with an ASCII-
     * incompatible encoding, as well as combining  [`EBCDIC] with a
     * non-EBCDIC encoding. Wrong conversions would be the result of
     * this.
     *)

(* *********************************************************************)
(** {1 Data Stream Converters} *)


class write_out_record_channel : 
        repr:text_data_repr -> 
	Netchannels.out_obj_channel -> 
	  out_record_channel
  (** Provides an [out_record_channel] that represents EOR as 
   * newline character.
   *
   * @param repr Determines the newline character to use
   *)


class read_in_record_channel :
        repr:text_data_repr ->
	Netchannels.in_obj_channel ->
	  in_record_channel
  (** Provides an [in_record_channel] that takes newline characters as
   * EOR representation.
   *
   * In this implementation, [input_line] can be used to read the full
   * contents of a record (=line). However, [input_line] does not
   * switch to the next record.
   *
   * @param repr Determines the newline character to use
   *)



class data_converter : 
        fromrepr:text_data_repr -> torepr:text_data_repr -> 
	  Netchannels.io_obj_channel
  (** Creates a data conversion pipe converting [fromrepr] to
   * [torepr].
   *
   * For simplicity, in an [`ASCII] input stream the CR characters are
   * discarded, and the LF characters are taken as newline characters.
   * In an output [`ASCII] stream, the CR/LF sequence is correctly
   * created for newline characters.
   *)


(* *********************************************************************)
(** {1 Engines} *)


(** The common type of FTP data engines *)
class type ftp_data_engine =
object
  inherit [unit] Uq_engines.engine
  method descr : Unix.file_descr
    (** The socket to use for data transfers. This class never closes
     * this socket, but it may be shut down at least partially.
     *)

  method descr_state : descr_state
    (** The socket state *)
end    


(** This engine receives data on a FTP data connection, and forwards
 * them to a local receiver. The socket must already be open.
 *
 * It is ensured that [local_receiver] is always closed after operation
 * (whether successful or not). The socket [descr] remains open.
 *)
class ftp_data_receiver : 
        esys:Unixqueue.event_system ->
	mode:transmission_mode ->
	local_receiver:local_receiver ->
	descr:Unix.file_descr ->
	unit ->
object
  inherit ftp_data_engine

  method local_receiver : local_receiver
    (** The local receiver. It is closed when the logical EOF is found in the
     * data connection
     *)

end


(** This engine sends data over a FTP data connection coming from
 * a local sender. The socket must already be open.
 *
 * It is ensured that [local_sender] is always closed after operation
 * (whether successful or not). The socket [descr] remains open.
 *)
class ftp_data_sender :
        esys:Unixqueue.event_system ->
	mode:transmission_mode ->
	local_sender:local_sender ->
	descr:Unix.file_descr ->
	unit ->
object
  inherit ftp_data_engine

  method local_sender : local_sender
    (** The local sender. It is closed after usage.
     *)
end