2 Copyright (C) 2001-2010, Parrot Foundation.
7 src/io/filehandle.c - FileHandle utility functions
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>.
18 #include "parrot/parrot.h"
19 #include "io_private.h"
20 #include "pmc/pmc_filehandle.h"
22 /* HEADERIZER HFILE: include/parrot/io.h */
30 =item C<INTVAL Parrot_io_parse_open_flags(PARROT_INTERP, const STRING
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.
41 PARROT_WARN_UNUSED_RESULT
43 Parrot_io_parse_open_flags(PARROT_INTERP
, ARGIN_NULLOK(const STRING
*mode_str
))
45 ASSERT_ARGS(Parrot_io_parse_open_flags
)
49 if (STRING_IS_NULL(mode_str
))
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
);
62 if (!(flags
& PIO_F_APPEND
)) /* don't truncate if appending */
66 flags
|= PIO_F_APPEND
;
68 if ((flags
& PIO_F_TRUNC
)) /* don't truncate if appending */
69 flags
&= ~PIO_F_TRUNC
;
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:
93 Point to a NULL STRING
97 Point to a real STRING
101 Point to a fake STRING with (strstart, bufused) holding the *buffer
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.
114 PARROT_WARN_UNUSED_RESULT
115 PARROT_CANNOT_RETURN_NULL
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
124 *buf
= Parrot_str_new_noinit(interp
, len
);
128 STRING
* const s
= *buf
;
129 if (s
->bufused
< len
)
130 Parrot_gc_reallocate_string_storage(interp
, s
, len
);
138 =item C<void Parrot_io_set_os_handle(PARROT_INTERP, PMC *filehandle, PIOHANDLE
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.
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.
181 PARROT_WARN_UNUSED_RESULT
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.
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.
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
;
242 =item C<void Parrot_io_set_file_size(PARROT_INTERP, PMC *filehandle, PIOOFF_T
245 Set the C<file_size> attribute of the FileHandle object, which stores the
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.
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
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.
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
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.
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
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.
334 PARROT_WARN_UNUSED_RESULT
335 PARROT_CAN_RETURN_NULL
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
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.
361 PARROT_CAN_RETURN_NULL
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
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.
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
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.
412 PARROT_WARN_UNUSED_RESULT
413 PARROT_CAN_RETURN_NULL
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
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.
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.
462 PARROT_CAN_RETURN_NULL
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
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.
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.
510 PARROT_CAN_RETURN_NULL
511 PARROT_WARN_UNUSED_RESULT
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
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.
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.
558 PARROT_CAN_RETURN_NULL
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
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.
588 PARROT_WARN_UNUSED_RESULT
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
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.
614 PARROT_WARN_UNUSED_RESULT
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,
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.
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,
655 Check whether the encoding attribute of the filehandle matches a passed in
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.
668 PARROT_WARN_UNUSED_RESULT
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
))
677 if (Parrot_str_equal(interp
, value
, handle_struct
->encoding
))
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.
696 Parrot_io_close_filehandle(PARROT_INTERP
, ARGMOD(PMC
*pmc
))
698 ASSERT_ARGS(Parrot_io_close_filehandle
)
701 if (Parrot_io_is_closed_filehandle(interp
, pmc
))
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
);
715 =item C<INTVAL Parrot_io_is_closed_filehandle(PARROT_INTERP, const PMC *pmc)>
717 Test whether a filehandle is closed.
724 PARROT_WARN_UNUSED_RESULT
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>.
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
))
750 Parrot_io_flush_buffer(interp
, pmc
);
751 PIO_FLUSH(interp
, pmc
);
763 F<src/io/io_private.h>.
772 * c-file-style: "parrot"
774 * vim: expandtab shiftwidth=4: