stream.h
4.95 KB
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
/*
* Zunächst ein paar allgemeine Bemerkungen zu scot_stream:
*
* 1. scot-stream ist eine auf andere Klassen aufbauende Klasse. Es gibt
* kein scot_stream_new. Mann kann natürlich über malloc ein leeres
* stream-objekt anlegen, das macht für gewöhnlich aber keinen Sinn.
* Stattdessen gibt es in Klassen, die stream-io Endpunkte darstellen
* Funktionen der Form scot_<Klasse>_get_new_stream
* (z.B. scot_socket_get_new_stream). Diese Funktionen geben ein
* gültiges Stream Objekt zu einem Objekt der übergeordneten Klasse
* zurück. Das Objekt der übergeordnete Klasse muss sich alle auf diese
* Art angelegten Stream-Objekte merken.
* 2. Wenn ein Objekt der übergeordneten Klasse geschlossen wird, so werden
* auch alle Stream Objekte die von diesem erzeugt wurden freigegeben und
* auf NULL gesetzt. (Auf Sie währe eh keine Sinnvolle operation mehr
* möglich.)
* 3. Wird ein Stream-Objekt freigegeben, so bleibt das übergeordnete
* Objekt erhalten (und somit auch der handle geöffnet).
* 4. Ein close auf ein Stream Objekt schließt auch das übergeordnete
* Objekt und gibt es frei. Somit werden auch alle weiteren Stream
* Objekte geschlossen.
*
* !!!Zusammenfassend bleibt nochmal hervorzuheben das close gegenüber free
* die stärkere operation ist und zu einem free aller stream objekte und
* des übergeordneten Objekts führt.!!!
*/
#ifndef SCOT_STREAM_H
#define SCOT_STREAM_H
#include <scot/scot_int.h>
#include <scot/scot_types.h>
#define SCOT_STREAM_BUF_SIZE 100
/* scot stream types (scot_stream:s_type) . */
/* Die ersten bis zum --- Kommentar sind stream_pool fähig */
#define SCOT_STREAM_TYPE_SOCKET 0
#define SCOT_STREAM_TYPE_PIPE 1
#define SCOT_STREAM_TYPE_TERM 2
/* --- */
#define SCOT_STREAM_TYPE_FILE 3
#define SCOT_STREAM_TYPE_INOTIFY 4
#ifdef WIN32
# include <windows.h>
# include <scot/stream_win.h>
# define SCOT_FILE_READ win_file_read
#else
# define SCOT_FILE_READ read
#endif /* WIN32 */
/* s must me a pointer to a stream...this is normally the case! */
#define SCOT_STREAM_TO_SOCKET(s) ((struct scot_socket *)(s))
#define SCOT_STREAM_TO_PIPE(s) ((struct scot_pipe *)(s))
#define SCOT_STREAM_TO_TERM(s) ((struct scot_term *)(s))
#define SCOT_STREAM_TO_FILE(s) ((struct scot_file *)(s))
#define SCOT_STREAM_TO_INOTIFY(s) ((struct scot_inotify *)(s))
/*
* get the base object of the given stream with the correct type
* Those base types has to be specified here at the moment... maybe
* sometimes there will be some kind of registration method for
* base types
*/
#define SCOT_STREAM_PROV(st) \
((st)->s_type == SCOT_STREAM_TYPE_SOCKET)? SCOT_STREAM_TO_SOCKET((st)):\
((st)->s_type == SCOT_STREAM_TYPE_PIPE)? SCOT_STREAM_TO_PIPE((st)):\
((st)->s_type == SCOT_STREAM_TYPE_TERM)? SCOT_STREAM_TO_TERM((st)):\
((st)->s_type == SCOT_STREAM_TYPE_FILE)? SCOT_STREAM_TO_FILE((st)):\
((st)->s_type == SCOT_STREAM_TYPE_INOTIFY)?SCOT_STREAM_TO_INOTIFY((st)):(st)
#define SCOT_STREAM_FREE(st) \
((st)->s_type == SCOT_STREAM_TYPE_SOCKET)?\
scot_socket_free (SCOT_STREAM_TO_SOCKET (st)):\
((st)->s_type == SCOT_STREAM_TYPE_PIPE)? scot_stream_free ((st)):\
((st)->s_type == SCOT_STREAM_TYPE_TERM)? scot_stream_free ((st)):\
((st)->s_type == SCOT_STREAM_TYPE_FILE)? scot_stream_free ((st)):\
((st)->s_type == SCOT_STREAM_TYPE_INOTIFY)?scot_stream_free ((st)):\
scot_stream_free ((st))
/*
* connections via ssl must be handled separately, because communication
* over them has some very distinc behaviour then with other streams.
* First, read and write are not done on a handle but on an ssl object.
* Next, ssl has an all or nothing approach. If a write could not send
* all data it sould be assumed as failed. This is neccessary for the
* encryption.
* Next, ssl is designed to sit on top of most stream types. Thus it
* is a separate object, that should be createable by a stream object.
*/
struct scot_stream
{
#ifndef WIN32
union
{
int32_t file;
int32_t sock;
} handle;
#else
union
{
HANDLE file;
SOCKET sock;
} handle;
#endif
char rbuf [SCOT_STREAM_BUF_SIZE];
char wbuf [SCOT_STREAM_BUF_SIZE];
uint32_t rbuf_idx;
uint32_t wbuf_idx;
int32_t s_type; /* an identifier of this stream (file, socket, pipe...) */
int16_t s_blk;
};
int scot_stream_eof (struct scot_stream *);
SSIZE_T scot_stream_read (struct scot_stream *, char *, SIZE_T);
SSIZE_T scot_stream_write (struct scot_stream *, char *, SIZE_T);
void scot_stream_flush (struct scot_stream *);
SSIZE_T scot_stream_read_pending (struct scot_stream *);
SSIZE_T scot_stream_write_pending (struct scot_stream *);
int scot_stream_get_blocking (struct scot_stream *);
void scot_stream_set_block (struct scot_stream *);
void scot_stream_set_nonblock (struct scot_stream *);
void scot_stream_close (struct scot_stream *);
int scot_stream_is_closed (struct scot_stream *);
void scot_stream_free (struct scot_stream *);
#endif /* SCOT_STREAM_H */