fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / io / filehandle.c
blobd184b3105d7c4d9970f7f7f6507663954490e1bb
1 /*
2 Copyright (C) 2001-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/io/filehandle.c - FileHandle utility functions
9 =head1 DESCRIPTION
11 This file defines a set of utility functions for the FileHandle PMC used by all
12 operating systems. For the primary public I/O API, see F<src/io/api.c>.
14 =cut
18 #include "parrot/parrot.h"
19 #include "io_private.h"
20 #include "pmc/pmc_filehandle.h"
22 /* HEADERIZER HFILE: include/parrot/io.h */
26 =head2 Functions
28 =over 4
30 =item C<INTVAL Parrot_io_parse_open_flags(PARROT_INTERP, const STRING
31 *mode_str)>
33 Parses a Parrot string for file open mode flags (C<r> for read, C<w> for write,
34 C<a> for append, and C<p> for pipe) and returns the combined generic bit flags.
36 =cut
40 PARROT_EXPORT
41 PARROT_WARN_UNUSED_RESULT
42 INTVAL
43 Parrot_io_parse_open_flags(PARROT_INTERP, ARGIN_NULLOK(const STRING *mode_str))
45 ASSERT_ARGS(Parrot_io_parse_open_flags)
46 INTVAL i, mode_len;
47 INTVAL flags = 0;
49 if (STRING_IS_NULL(mode_str))
50 return PIO_F_READ;
52 mode_len = Parrot_str_byte_length(interp, mode_str);
54 for (i = 0; i < mode_len; ++i) {
55 const INTVAL s = Parrot_str_indexed(interp, mode_str, i);
56 switch (s) {
57 case 'r':
58 flags |= PIO_F_READ;
59 break;
60 case 'w':
61 flags |= PIO_F_WRITE;
62 if (!(flags & PIO_F_APPEND)) /* don't truncate if appending */
63 flags |= PIO_F_TRUNC;
64 break;
65 case 'a':
66 flags |= PIO_F_APPEND;
67 flags |= PIO_F_WRITE;
68 if ((flags & PIO_F_TRUNC)) /* don't truncate if appending */
69 flags &= ~PIO_F_TRUNC;
70 break;
71 case 'p':
72 flags |= PIO_F_PIPE;
73 break;
74 default:
75 break;
79 return flags;
84 =item C<STRING * Parrot_io_make_string(PARROT_INTERP, STRING **buf, size_t len)>
86 Creates a STRING* suitable for returning results from IO read functions.
87 The passed in C<buf> parameter can:
89 =over 4
91 =item 1
93 Point to a NULL STRING
95 =item 2
97 Point to a real STRING
99 =item 3
101 Point to a fake STRING with (strstart, bufused) holding the *buffer
102 information.
104 =back
106 In the third case, the buffer or STRING must be able to hold the required
107 amount of data. For cases 1 and 2, a NULL C<strstart> tells this function to
108 allocate the STRING memory.
110 =cut
114 PARROT_WARN_UNUSED_RESULT
115 PARROT_CANNOT_RETURN_NULL
116 STRING *
117 Parrot_io_make_string(PARROT_INTERP, ARGMOD(STRING **buf), size_t len)
119 ASSERT_ARGS(Parrot_io_make_string)
121 * when we get a NULL string, we read a default len
123 if (*buf == NULL) {
124 *buf = Parrot_str_new_noinit(interp, len);
125 return *buf;
127 else {
128 STRING * const s = *buf;
129 if (s->bufused < len)
130 Parrot_gc_reallocate_string_storage(interp, s, len);
131 return s;
138 =item C<void Parrot_io_set_os_handle(PARROT_INTERP, PMC *filehandle, PIOHANDLE
139 file_descriptor)>
141 Sets the C<os_handle> attribute of the FileHandle object, which stores the
142 low-level filehandle for the OS.
144 Currently, this pokes directly into the C struct of the FileHandle PMC. This
145 needs to change to a general interface that can be used by all subclasses and
146 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
147 it can be cleanly changed later.
149 Possibly, this function should reset some characteristics of the object (like
150 buffer and file positions) to their default values.
152 =cut
156 PARROT_EXPORT
157 void
158 Parrot_io_set_os_handle(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOHANDLE file_descriptor)
160 ASSERT_ARGS(Parrot_io_set_os_handle)
161 PARROT_FILEHANDLE(filehandle)->os_handle = file_descriptor;
166 =item C<PIOHANDLE Parrot_io_get_os_handle(PARROT_INTERP, const PMC *filehandle)>
168 Retrieve the C<os_handle> attribute of the FileHandle object, which stores the
169 low-level filehandle for the OS.
171 Currently, this pokes directly into the C struct of the FileHandle PMC. This
172 needs to change to a general interface that can be used by all subclasses and
173 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
174 it can be cleanly changed later.
176 =cut
180 PARROT_EXPORT
181 PARROT_WARN_UNUSED_RESULT
182 PIOHANDLE
183 Parrot_io_get_os_handle(SHIM_INTERP, ARGIN(const PMC *filehandle))
185 ASSERT_ARGS(Parrot_io_get_os_handle)
186 return PARROT_FILEHANDLE(filehandle)->os_handle;
191 =item C<void Parrot_io_set_flags(PARROT_INTERP, PMC *filehandle, INTVAL flags)>
193 Set the C<flags> attribute of the FileHandle object, which stores bitwise flags
194 marking filehandle characteristics.
196 Currently, this pokes directly into the C struct of the FileHandle PMC. This
197 needs to change to a general interface that can be used by all subclasses and
198 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
199 it can be cleanly changed later.
201 =cut
205 PARROT_EXPORT
206 void
207 Parrot_io_set_flags(SHIM_INTERP, ARGIN(PMC *filehandle), INTVAL flags)
209 ASSERT_ARGS(Parrot_io_set_flags)
210 Parrot_FileHandle_attributes * const handle_struct = PARROT_FILEHANDLE(filehandle);
211 handle_struct->flags = flags;
216 =item C<INTVAL Parrot_io_get_flags(PARROT_INTERP, PMC *filehandle)>
218 Set the C<flags> attribute of the FileHandle object, which stores bitwise flags
219 marking filehandle characteristics.
221 Currently, this pokes directly into the C struct of the FileHandle PMC. This
222 needs to change to a general interface that can be used by all subclasses and
223 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
224 it can be cleanly changed later.
226 =cut
230 PARROT_EXPORT
231 INTVAL
232 Parrot_io_get_flags(SHIM_INTERP, ARGIN(PMC *filehandle))
234 ASSERT_ARGS(Parrot_io_get_flags)
235 Parrot_FileHandle_attributes *handle_struct = PARROT_FILEHANDLE(filehandle);
236 INTVAL flags = handle_struct->flags;
237 return flags;
242 =item C<void Parrot_io_set_file_size(PARROT_INTERP, PMC *filehandle, PIOOFF_T
243 file_size)>
245 Set the C<file_size> attribute of the FileHandle object, which stores the
246 current file size.
248 Currently, this pokes directly into the C struct of the FileHandle PMC. This
249 needs to change to a general interface that can be used by all subclasses and
250 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
251 it can be cleanly changed later.
253 =cut
257 PARROT_EXPORT
258 void
259 Parrot_io_set_file_size(SHIM_INTERP, ARGIN(PMC *filehandle), PIOOFF_T file_size)
261 ASSERT_ARGS(Parrot_io_set_file_size)
262 PARROT_FILEHANDLE(filehandle)->file_size = file_size;
268 =item C<PIOOFF_T Parrot_io_get_file_size(PARROT_INTERP, PMC *filehandle)>
270 Get the C<file_size> attribute of the FileHandle object, which stores the
271 current file size.
274 Currently, this pokes directly into the C struct of the FileHandle PMC. This
275 needs to change to a general interface that can be used by all subclasses and
276 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
277 it can be cleanly changed later.
279 =cut
283 PARROT_EXPORT
284 PIOOFF_T
285 Parrot_io_get_file_size(SHIM_INTERP, ARGIN(PMC *filehandle))
287 ASSERT_ARGS(Parrot_io_get_file_size)
288 return PARROT_FILEHANDLE(filehandle)->file_size;
293 =item C<void Parrot_io_set_buffer_start(PARROT_INTERP, PMC *filehandle, unsigned
294 char *new_start)>
296 Set the C<buffer_start> attribute of the FileHandle object, which stores
297 the position of the start of the buffer.
299 Currently, this pokes directly into the C struct of the FileHandle PMC. This
300 needs to change to a general interface that can be used by all subclasses and
301 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
302 it can be cleanly changed later.
304 =cut
308 void
309 Parrot_io_set_buffer_start(SHIM_INTERP, ARGMOD(PMC *filehandle),
310 ARGIN_NULLOK(unsigned char *new_start))
312 ASSERT_ARGS(Parrot_io_set_buffer_start)
313 PARROT_FILEHANDLE(filehandle)->buffer_start = new_start;
318 =item C<unsigned char * Parrot_io_get_buffer_start(PARROT_INTERP, PMC
319 *filehandle)>
321 Get the C<buffer_start> attribute of the FileHandle object, which stores
322 the position of the start of the buffer.
324 Currently, this pokes directly into the C struct of the FileHandle PMC. This
325 needs to change to a general interface that can be used by all subclasses and
326 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
327 it can be cleanly changed later.
329 =cut
333 PARROT_EXPORT
334 PARROT_WARN_UNUSED_RESULT
335 PARROT_CAN_RETURN_NULL
336 unsigned char *
337 Parrot_io_get_buffer_start(SHIM_INTERP, ARGIN(PMC *filehandle))
339 ASSERT_ARGS(Parrot_io_get_buffer_start)
340 return PARROT_FILEHANDLE(filehandle)->buffer_start;
345 =item C<unsigned char * Parrot_io_get_buffer_next(PARROT_INTERP, const PMC
346 *filehandle)>
348 Get the C<buffer_next> attribute of the FileHandle object, which stores
349 the current position within the buffer.
351 Currently, this pokes directly into the C struct of the FileHandle PMC. This
352 needs to change to a general interface that can be used by all subclasses and
353 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
354 it can be cleanly changed later.
356 =cut
360 PARROT_EXPORT
361 PARROT_CAN_RETURN_NULL
362 unsigned char *
363 Parrot_io_get_buffer_next(SHIM_INTERP, ARGIN(const PMC *filehandle))
365 ASSERT_ARGS(Parrot_io_get_buffer_next)
366 return PARROT_FILEHANDLE(filehandle)->buffer_next;
371 =item C<void Parrot_io_set_buffer_next(PARROT_INTERP, PMC *filehandle, unsigned
372 char *new_next)>
374 Set the C<buffer_next> attribute of the FileHandle object, which stores
375 the current position within the buffer.
377 Currently, this pokes directly into the C struct of the FileHandle PMC. This
378 needs to change to a general interface that can be used by all subclasses and
379 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
380 it can be cleanly changed later.
382 =cut
386 void
387 Parrot_io_set_buffer_next(SHIM_INTERP, ARGMOD(PMC *filehandle),
388 ARGIN_NULLOK(unsigned char *new_next))
390 ASSERT_ARGS(Parrot_io_set_buffer_next)
391 PARROT_FILEHANDLE(filehandle)->buffer_next = new_next;
396 =item C<unsigned char * Parrot_io_get_buffer_end(PARROT_INTERP, const PMC
397 *filehandle)>
399 Get the C<buffer_end> attribute of the FileHandle object, which stores
400 the position of the end of the buffer.
402 Currently, this pokes directly into the C struct of the FileHandle PMC. This
403 needs to change to a general interface that can be used by all subclasses and
404 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
405 it can be cleanly changed later.
407 =cut
411 PARROT_EXPORT
412 PARROT_WARN_UNUSED_RESULT
413 PARROT_CAN_RETURN_NULL
414 unsigned char *
415 Parrot_io_get_buffer_end(SHIM_INTERP, ARGIN(const PMC *filehandle))
417 ASSERT_ARGS(Parrot_io_get_buffer_end)
418 return PARROT_FILEHANDLE(filehandle)->buffer_end;
423 =item C<void Parrot_io_set_buffer_end(PARROT_INTERP, PMC *filehandle, unsigned
424 char *new_end)>
426 Set the C<buffer_end> attribute of the FileHandle object, which stores
427 the position of the end of the buffer.
429 Currently, this pokes directly into the C struct of the FileHandle PMC. This
430 needs to change to a general interface that can be used by all subclasses and
431 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
432 it can be cleanly changed later.
434 =cut
438 void
439 Parrot_io_set_buffer_end(SHIM_INTERP, ARGMOD(PMC *filehandle),
440 ARGIN_NULLOK(unsigned char *new_end))
442 ASSERT_ARGS(Parrot_io_set_buffer_end)
443 PARROT_FILEHANDLE(filehandle)->buffer_end = new_end;
448 =item C<INTVAL Parrot_io_get_buffer_flags(PARROT_INTERP, const PMC *filehandle)>
450 Get the C<buffer_flags> attribute of the FileHandle object, which stores
451 a collection of flags specific to the buffer.
453 Currently, this pokes directly into the C struct of the FileHandle PMC. This
454 needs to change to a general interface that can be used by all subclasses and
455 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
456 it can be cleanly changed later.
458 =cut
462 PARROT_CAN_RETURN_NULL
463 INTVAL
464 Parrot_io_get_buffer_flags(SHIM_INTERP, ARGIN(const PMC *filehandle))
466 ASSERT_ARGS(Parrot_io_get_buffer_flags)
467 return PARROT_FILEHANDLE(filehandle)->buffer_flags;
472 =item C<void Parrot_io_set_buffer_flags(PARROT_INTERP, PMC *filehandle, INTVAL
473 new_flags)>
475 Set the C<buffer_flags> attribute of the FileHandle object, which stores
476 a collection of flags specific to the buffer.
478 Currently, this pokes directly into the C struct of the FileHandle PMC. This
479 needs to change to a general interface that can be used by all subclasses and
480 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
481 it can be cleanly changed later.
483 =cut
487 void
488 Parrot_io_set_buffer_flags(SHIM_INTERP, ARGMOD(PMC *filehandle), INTVAL new_flags)
490 ASSERT_ARGS(Parrot_io_set_buffer_flags)
491 PARROT_FILEHANDLE(filehandle)->buffer_flags = new_flags;
496 =item C<size_t Parrot_io_get_buffer_size(PARROT_INTERP, const PMC *filehandle)>
498 Get the C<buffer_size> attribute of the FileHandle object, which stores
499 the size of the buffer (in bytes).
501 Currently, this pokes directly into the C struct of the FileHandle PMC. This
502 needs to change to a general interface that can be used by all subclasses and
503 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
504 it can be cleanly changed later.
506 =cut
510 PARROT_CAN_RETURN_NULL
511 PARROT_WARN_UNUSED_RESULT
512 size_t
513 Parrot_io_get_buffer_size(SHIM_INTERP, ARGIN(const PMC *filehandle))
515 ASSERT_ARGS(Parrot_io_get_buffer_size)
516 return PARROT_FILEHANDLE(filehandle)->buffer_size;
521 =item C<void Parrot_io_set_buffer_size(PARROT_INTERP, PMC *filehandle, size_t
522 new_size)>
524 Set the C<buffer_size> attribute of the FileHandle object, which stores
525 the size of the buffer (in bytes).
527 Currently, this pokes directly into the C struct of the FileHandle PMC. This
528 needs to change to a general interface that can be used by all subclasses and
529 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
530 it can be cleanly changed later.
532 =cut
536 void
537 Parrot_io_set_buffer_size(SHIM_INTERP, ARGMOD(PMC *filehandle), size_t new_size)
539 ASSERT_ARGS(Parrot_io_set_buffer_size)
540 PARROT_FILEHANDLE(filehandle)->buffer_size = new_size;
545 =item C<void Parrot_io_clear_buffer(PARROT_INTERP, PMC *filehandle)>
547 Clear the filehandle buffer and free the associated memory.
549 Currently, this pokes directly into the C struct of the FileHandle PMC. This
550 needs to change to a general interface that can be used by all subclasses and
551 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
552 it can be cleanly changed later.
554 =cut
558 PARROT_CAN_RETURN_NULL
559 void
560 Parrot_io_clear_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle))
562 ASSERT_ARGS(Parrot_io_clear_buffer)
563 Parrot_FileHandle_attributes * const io = PARROT_FILEHANDLE(filehandle);
564 if (io->buffer_start && (io->flags & PIO_BF_MALLOC)) {
565 mem_gc_free(interp, io->buffer_start);
566 io->buffer_start = NULL;
572 =item C<PIOOFF_T Parrot_io_get_file_position(PARROT_INTERP, const PMC
573 *filehandle)>
575 Get the C<file_pos> attribute of the FileHandle object, which stores
576 the current file position of the filehandle.
578 Currently, this pokes directly into the C struct of the FileHandle PMC. This
579 needs to change to a general interface that can be used by all subclasses and
580 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
581 it can be cleanly changed later.
583 =cut
587 PARROT_EXPORT
588 PARROT_WARN_UNUSED_RESULT
589 PIOOFF_T
590 Parrot_io_get_file_position(SHIM_INTERP, ARGIN(const PMC *filehandle))
592 ASSERT_ARGS(Parrot_io_get_file_position)
593 return PARROT_FILEHANDLE(filehandle)->file_pos;
598 =item C<PIOOFF_T Parrot_io_get_last_file_position(PARROT_INTERP, const PMC
599 *filehandle)>
601 Get the C<file_pos> attribute of the FileHandle object, which stores
602 the current file position of the filehandle.
604 Currently, this pokes directly into the C struct of the FileHandle PMC. This
605 needs to change to a general interface that can be used by all subclasses and
606 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
607 it can be cleanly changed later.
609 =cut
613 PARROT_EXPORT
614 PARROT_WARN_UNUSED_RESULT
615 PIOOFF_T
616 Parrot_io_get_last_file_position(SHIM_INTERP, ARGIN(const PMC *filehandle))
618 ASSERT_ARGS(Parrot_io_get_last_file_position)
619 return PARROT_FILEHANDLE(filehandle)->last_pos;
624 =item C<void Parrot_io_set_file_position(PARROT_INTERP, PMC *filehandle,
625 PIOOFF_T file_pos)>
627 Get the C<file_pos> attribute of the FileHandle object, which stores the
628 current file position of the filehandle. Also set the C<last_pos> attribute to
629 the previous value of C<file_pos>.
631 Currently, this pokes directly into the C struct of the FileHandle PMC. This
632 needs to change to a general interface that can be used by all subclasses and
633 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
634 it can be cleanly changed later.
636 =cut
640 PARROT_EXPORT
641 void
642 Parrot_io_set_file_position(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOOFF_T file_pos)
644 ASSERT_ARGS(Parrot_io_set_file_position)
645 Parrot_FileHandle_attributes * const handle_struct = PARROT_FILEHANDLE(filehandle);
646 handle_struct->last_pos = handle_struct->file_pos;
647 handle_struct->file_pos = file_pos;
652 =item C<INTVAL Parrot_io_is_encoding(PARROT_INTERP, const PMC *filehandle,
653 STRING *value)>
655 Check whether the encoding attribute of the filehandle matches a passed in
656 string.
658 Currently, this pokes directly into the C struct of the FileHandle PMC. This
659 needs to change to a general interface that can be used by all subclasses and
660 polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
661 it can be cleanly changed later.
663 =cut
667 PARROT_EXPORT
668 PARROT_WARN_UNUSED_RESULT
669 INTVAL
670 Parrot_io_is_encoding(PARROT_INTERP, ARGIN(const PMC *filehandle), ARGIN(STRING *value))
672 ASSERT_ARGS(Parrot_io_is_encoding)
673 Parrot_FileHandle_attributes * const handle_struct = PARROT_FILEHANDLE(filehandle);
674 if (STRING_IS_NULL(handle_struct->encoding))
675 return 0;
677 if (Parrot_str_equal(interp, value, handle_struct->encoding))
678 return 1;
680 return 0;
685 =item C<INTVAL Parrot_io_close_filehandle(PARROT_INTERP, PMC *pmc)>
687 Flushes and closes the C<FileHandle> PMC C<*pmc>, but leaves the object intact
688 to be reused or collected.
690 =cut
694 PARROT_EXPORT
695 INTVAL
696 Parrot_io_close_filehandle(PARROT_INTERP, ARGMOD(PMC *pmc))
698 ASSERT_ARGS(Parrot_io_close_filehandle)
699 INTVAL result;
701 if (Parrot_io_is_closed_filehandle(interp, pmc))
702 return -1;
704 Parrot_io_flush_buffer(interp, pmc);
705 PIO_FLUSH(interp, pmc);
707 result = PIO_CLOSE(interp, pmc);
708 Parrot_io_clear_buffer(interp, pmc);
710 return result;
715 =item C<INTVAL Parrot_io_is_closed_filehandle(PARROT_INTERP, const PMC *pmc)>
717 Test whether a filehandle is closed.
719 =cut
723 PARROT_EXPORT
724 PARROT_WARN_UNUSED_RESULT
725 INTVAL
726 Parrot_io_is_closed_filehandle(PARROT_INTERP, ARGIN(const PMC *pmc))
728 ASSERT_ARGS(Parrot_io_is_closed_filehandle)
729 return PIO_IS_CLOSED(interp, pmc);
734 =item C<void Parrot_io_flush_filehandle(PARROT_INTERP, PMC *pmc)>
736 Flushes the C<FileHandle> PMC C<*pmc>.
738 =cut
742 PARROT_EXPORT
743 void
744 Parrot_io_flush_filehandle(PARROT_INTERP, ARGMOD(PMC *pmc))
746 ASSERT_ARGS(Parrot_io_flush_filehandle)
747 if (Parrot_io_is_closed(interp, pmc))
748 return;
750 Parrot_io_flush_buffer(interp, pmc);
751 PIO_FLUSH(interp, pmc);
756 =back
758 =head1 SEE ALSO
760 F<src/io/unix.c>,
761 F<src/io/win32.c>,
762 F<src/io/stdio.c>,
763 F<src/io/io_private.h>.
765 =cut
771 * Local variables:
772 * c-file-style: "parrot"
773 * End:
774 * vim: expandtab shiftwidth=4: