3 * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 pipe_t
*pipe_list_start
;
25 pipe_t
*pipe_list_end
;
29 pipe_t
*p
= ((pipe_t
*) kmalloc (sizeof (pipe_t
)));
32 fd_create (fd_count
, FD_PIPE
);
36 fd_create (fd_count
, FD_PIPE
);
39 if(!pipe_list_start
) {
45 pipe_list_end
->next
= p
;
46 p
->prev
= pipe_list_end
;
54 p
->buffer_list_start
= ((pipe_buffer_t
*) kmalloc (sizeof(pipe_buffer_t
)));
55 p
->buffer_list_end
= p
->buffer_list_start
;
56 p
->buffer_list_start
->next
= NULL
;
57 p
->buffer_list_start
->prev
= NULL
;
58 p
->buffer_end_len
= 0;
59 p
->buffer_start_pos
= 0;
64 pipe_t
*pipe_get (int fd
)
66 pipe_t
*p
= pipe_list_start
;
83 unsigned int pipe_write (pipe_t
*p
, BYTE
* buffer
, unsigned int buffer_len
)
85 if ((!p
) || (!buffer
) || (!buffer_len
) || (!p
->buffer_list_start
))
89 unsigned int block_size
= 0;
90 unsigned int buffer_pos
= 0;
92 while (buffer_pos
< buffer_len
) {
93 if ((buffer_len
- buffer_pos
) >= (PIPE_BUFFER_PART_SIZE
- p
->buffer_end_len
)) {
94 ptr
= p
->buffer_list_end
;
95 block_size
= PIPE_BUFFER_PART_SIZE
- p
->buffer_end_len
;
96 memcpy (*((&ptr
->buffer
) + p
->buffer_end_len
), ((buffer
) + buffer_pos
), block_size
);
97 buffer_pos
+= block_size
;
99 p
->buffer_list_end
= ((pipe_buffer_t
*) kmalloc(sizeof (pipe_buffer_t
)));
100 p
->buffer_end_len
= 0;
101 ptr
->next
= p
->buffer_list_end
;
102 p
->buffer_list_end
->prev
= ptr
;
104 ptr
= p
->buffer_list_end
;
105 block_size
= buffer_len
- buffer_pos
;
106 memcpy (((ptr
->buffer
) + p
->buffer_end_len
), ((buffer
) + buffer_pos
), block_size
);
107 p
->buffer_end_len
+= block_size
;
108 buffer_pos
+= block_size
;
116 unsigned int pipe_read (pipe_t
*p
, BYTE
* buffer
, unsigned int buffer_max_len
)
118 unsigned int buffer_pos
= 0;
121 if ((!p
) || (!buffer
) || (!buffer_max_len
) || (!p
->buffer_list_start
))
124 while (true) { // hardcore code :)
125 while (buffer_pos
< buffer_max_len
) {
127 unsigned int block_size
= 0;
128 unsigned int buffer_space
= buffer_max_len
- buffer_pos
;
130 if (p
->buffer_list_start
== p
->buffer_list_end
) {
131 unsigned int pipe_dl
= p
->buffer_end_len
- p
->buffer_start_pos
;
132 block_size
= (pipe_dl
< buffer_space
) ? (pipe_dl
) : (buffer_space
);
134 if(p
->buffer_start_pos
== p
->buffer_end_len
)
136 ptr
= p
->buffer_list_start
;
137 memcpy (((buffer
) + buffer_pos
), ((ptr
->buffer
) + p
->buffer_start_pos
), block_size
);
138 p
->buffer_start_pos
+= block_size
;
139 buffer_pos
+= block_size
;
140 } else if (buffer_space
>= PIPE_BUFFER_PART_SIZE
- p
->buffer_start_pos
) {
141 ptr
= p
->buffer_list_start
;
143 block_size
= PIPE_BUFFER_PART_SIZE
- p
->buffer_start_pos
;
144 memcpy (((buffer
) + buffer_pos
), ((ptr
->buffer
) + p
->buffer_start_pos
), block_size
);
145 buffer_pos
+= block_size
;
147 p
->buffer_start_pos
= 0;
148 p
->buffer_list_start
= ptr
->next
;
149 p
->buffer_list_start
->prev
= NULL
;
152 ptr
= p
->buffer_list_start
;
153 memcpy (((buffer
) + buffer_pos
), ((ptr
->buffer
) + p
->buffer_start_pos
), buffer_space
);
154 p
->buffer_start_pos
+= buffer_space
;
158 if (buffer_pos
== buffer_max_len
)
165 void pipe_remove (pipe_t
*pipe
)
168 pipe
->next
->prev
= pipe
->prev
;
171 pipe_list_end
= pipe
->prev
;
173 pipe_list_end
= NULL
;
177 pipe
->prev
->next
= pipe
->next
;
180 pipe_list_start
= pipe
->next
;
182 pipe_list_start
= NULL
;
187 pipe_buffer_t
*p
= pipe
->buffer_list_start
;
199 void pipe_close (int fd
)
201 pipe_t
*p
= pipe_list_start
;
205 fd_delete (fd_get (fd
));
212 fd_delete (fd_get (fd
));