Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base: master
...
compare: whiteknight/io_vtable_lookup
Checking mergeability… Don't worry, you can still create the pull request.
  • 13 commits
  • 27 files changed
  • 0 commit comments
  • 1 contributor
Commits on Nov 17, 2012
@Whiteknight Whiteknight Separate out a new Pipe PMC type from FileHandle. Remove Pipe logic f…
…rom FileHandle, and make sure the two io vtables are separate.
ad2e031
@Whiteknight Whiteknight headerizer, and a few small fixes so this mess all builds f4e9a1f
@Whiteknight Whiteknight Break pipe-related tests from t/pmc/filehandle.t into a new t/pmc/pip…
…e.t. Update the test to pass.
2a30b1c
@Whiteknight Whiteknight Update socket.t and socket_ipv6.t to use pipes when communicating wit…
…h the test server instead of filehandle
a0df2bf
@Whiteknight Whiteknight Update makefile dependencies for pipe.c to fix checkdepend.t accee4c
@Whiteknight Whiteknight Update t/dynoplibs/io.t to not try to open a pipe, since it can't any…
…more.
81597d0
@Whiteknight Whiteknight Fix the makefile, my editor automatically converted all tabs to space…
…s, which breaks makefiles.
cec2bef
@Whiteknight Whiteknight Fix TAP::Parser and distutils to not use old-style pipes anymore. Thi…
…s fixes t/tools/mk_language_shell.t
d05f046
@Whiteknight Whiteknight start adding in new lookup routines for IO_VTABLE and IO_BUFFER, inst…
…ead of relying on get_pointer/set_pointer vtables for these.
e1aca18
@Whiteknight Whiteknight Remove get/set_pointer_keyed_int from handle. We no longer use that m…
…echanism to get access to the IO_VTABLE or the IO_BUFFERs
eb68007
@Whiteknight Whiteknight Completely redo buffer accesses. Buffers are now stored as IOBuffer P…
…MCs as properties on the handle PMCs. Rewrite all the accessor routines and initialization logic for buffers to account for this new situation.
b50b1c0
Commits on Nov 18, 2012
@Whiteknight Whiteknight Several fixes so the branch builds and passes most coretests. packfil…
…econstanttable.t fails for some odd-looking reasons. I have not made test yet.
c3edcbd
@Whiteknight Whiteknight Remove read_buffer and write_buffer from Handle PMC, since they aren'…
…t explicit attributes
849172b
View
3  MANIFEST
@@ -1378,6 +1378,7 @@ src/pmc/imageiostrings.pmc []
src/pmc/imageiothaw.pmc []
src/pmc/imccompiler.pmc []
src/pmc/integer.pmc []
+src/pmc/iobuffer.pmc []
src/pmc/iterator.pmc []
src/pmc/key.pmc []
src/pmc/lexinfo.pmc []
@@ -1408,6 +1409,7 @@ src/pmc/packfilesegment.pmc []
src/pmc/packfileview.pmc []
src/pmc/parrotinterpreter.pmc []
src/pmc/parrotlibrary.pmc []
+src/pmc/pipe.pmc []
src/pmc/pmc.num []
src/pmc/pmclist.pmc []
src/pmc/pmcproxy.pmc []
@@ -1944,6 +1946,7 @@ t/pmc/parrotinterpreter.t [test]
t/pmc/parrotio.t [test]
t/pmc/parrotlibrary.t [test]
t/pmc/parrotobject.t [test]
+t/pmc/pipe.t [test]
t/pmc/pmc.t [test]
t/pmc/pmclist.t [test]
t/pmc/pmcproxy.t [test]
View
9 config/gen/makefiles/root.in
@@ -702,6 +702,7 @@ STR_FILES = \
src/interp/inter_cb.str \
src/interp/api.str \
src/io/api.str \
+ src/io/utilities.str \
src/key.str \
src/library.str \
src/multidispatch.str \
@@ -1050,7 +1051,11 @@ src/events$(O) : \
src/alarm$(O) : $(PARROT_H_HEADERS) src/alarm.c \
$(INC_DIR)/alarm.h
-src/io/utilities$(O) : $(PARROT_H_HEADERS) src/io/io_private.h src/io/utilities.c
+src/io/utilities$(O) : \
+ $(PARROT_H_HEADERS) \
+ src/io/io_private.h \
+ src/io/utilities.str \
+ src/io/utilities.c
src/io/socket$(O) : \
$(PARROT_H_HEADERS) \
@@ -1069,7 +1074,7 @@ src/io/stringhandle$(O) : \
src/io/pipe$(O) : \
$(PARROT_H_HEADERS) \
src/io/io_private.h \
- $(INC_PMC_DIR)/pmc_filehandle.h \
+ $(INC_PMC_DIR)/pmc_pipe.h \
src/io/pipe.c
src/io/userhandle$(O) : \
View
59 include/parrot/io.h
@@ -46,7 +46,6 @@
#define PIO_F_APPEND 00000004 /* File is opened for append */
#define PIO_F_TRUNC 00000010
#define PIO_F_EOF 00000020 /* File is at EOF */
-#define PIO_F_PIPE 00000040 /* FileHandle is in pipe mode */
#define PIO_F_CONSOLE 00001000 /* A terminal */
#define PIO_F_READLINE 00002000 /* user interactive readline */
#define PIO_F_SOFT_SP 00040000 /* Python softspace */
@@ -179,21 +178,17 @@ typedef struct _io_vtable {
#define IO_VTABLE_STRINGHANDLE 3
#define IO_VTABLE_USER 4
-/* get_pointer values for common io-related pointer values.
- ALL IO handle types MUST implement get_pointer and MUST respond to these
- values. */
-#define IO_PTR_IDX_VTABLE 0
-#define IO_PTR_IDX_READ_BUFFER 1
-#define IO_PTR_IDX_WRITE_BUFFER 2
+#define IO_IDX_READ_BUFFER 1
+#define IO_IDX_WRITE_BUFFER 2
/* Specify that the buffer may be any size */
#define BUFFER_SIZE_ANY (size_t)-1
#define BUFFER_FLAGS_ANY (INTVAL)0
/* Helpful wrappers to get common pointers from IO handle PMCs */
-#define IO_GET_VTABLE(i, p) ((const IO_VTABLE *)VTABLE_get_pointer_keyed_int((i), (p), IO_PTR_IDX_VTABLE))
-#define IO_GET_READ_BUFFER(i, p) ((IO_BUFFER *)VTABLE_get_pointer_keyed_int((i), (p), IO_PTR_IDX_READ_BUFFER))
-#define IO_GET_WRITE_BUFFER(i, p) ((IO_BUFFER *)VTABLE_get_pointer_keyed_int((i), (p), IO_PTR_IDX_WRITE_BUFFER))
+#define IO_GET_VTABLE(i, p) ((const IO_VTABLE *)Parrot_io_get_vtable_for_pmc((i), (p)))
+#define IO_GET_READ_BUFFER(i, p) Parrot_io_get_handle_read_buffer((i), (p))
+#define IO_GET_WRITE_BUFFER(i, p) Parrot_io_get_handle_write_buffer((i), (p))
/* io/api.c - Public API functions */
/* HEADERIZER BEGIN: src/io/api.c */
@@ -632,6 +627,22 @@ INTVAL Parrot_io_get_flags(PARROT_INTERP, ARGIN(PMC *handle))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+IO_BUFFER * Parrot_io_get_handle_read_buffer(PARROT_INTERP,
+ ARGMOD(PMC *handle))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*handle);
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+IO_BUFFER * Parrot_io_get_handle_write_buffer(PARROT_INTERP,
+ ARGMOD(PMC *handle))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*handle);
+
PARROT_WARN_UNUSED_RESULT
PIOHANDLE Parrot_io_get_os_handle(PARROT_INTERP, ARGIN(PMC *handle))
__attribute__nonnull__(1)
@@ -642,13 +653,20 @@ PIOHANDLE Parrot_io_get_standard_piohandle(PARROT_INTERP, INTVAL idx)
__attribute__nonnull__(1);
PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
+PARROT_CANNOT_RETURN_NULL
const IO_VTABLE * Parrot_io_get_vtable(PARROT_INTERP,
INTVAL idx,
ARGIN_NULLOK(const char * name))
__attribute__nonnull__(1);
PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+const IO_VTABLE * Parrot_io_get_vtable_for_pmc(PARROT_INTERP,
+ ARGIN(PMC *handle))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
PIOOFF_T Parrot_io_make_offset_pmc(PARROT_INTERP, ARGMOD(PMC *pmc))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
@@ -851,6 +869,14 @@ INTVAL Parrot_io_write_byte_buffer_pmc(PARROT_INTERP,
#define ASSERT_ARGS_Parrot_io_get_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_Parrot_io_get_handle_read_buffer \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_Parrot_io_get_handle_write_buffer \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(handle))
#define ASSERT_ARGS_Parrot_io_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
@@ -859,6 +885,9 @@ INTVAL Parrot_io_write_byte_buffer_pmc(PARROT_INTERP,
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_io_get_vtable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_Parrot_io_get_vtable_for_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(handle))
#define ASSERT_ARGS_Parrot_io_make_offset_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pmc))
@@ -946,13 +975,10 @@ void Parrot_io_buffer_advance_position(PARROT_INTERP,
PARROT_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
IO_BUFFER * Parrot_io_buffer_allocate(PARROT_INTERP,
- ARGMOD(PMC *owner),
INTVAL flags,
ARGIN_NULLOK(const STR_VTABLE *encoding),
size_t init_size)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*owner);
+ __attribute__nonnull__(1);
void Parrot_io_buffer_clear(PARROT_INTERP, ARGMOD_NULLOK(IO_BUFFER *buffer))
__attribute__nonnull__(1)
@@ -1087,8 +1113,7 @@ size_t Parrot_io_buffer_write_b(PARROT_INTERP,
__attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_io_buffer_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(owner))
+ PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_io_buffer_clear __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_io_buffer_content_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
View
4 runtime/parrot/library/ProfTest/PIRProfile.nqp
@@ -83,8 +83,8 @@ method build_pir_profile() {
my $cli := "\"$parrot_exe\" $hash_seed_opt --runcore profiling $tmp_pir";
- my $pipe := pir::new__p_sc('FileHandle');
- $pipe.open($cli, "rp");
+ my $pipe := pir::new__p_sc('Pipe');
+ $pipe.open($cli, "r");
$pipe.readall();
self<exit_status> := $pipe.exit_status();
View
4 runtime/parrot/library/TAP/Parser.pir
@@ -967,9 +967,9 @@ C<TAP;Parser> is designed to produce a proper parse of TAP output.
unless $P0 goto L1
cmd .= ' 2>&1'
L1:
- $P0 = new 'FileHandle'
+ $P0 = new 'Pipe'
push_eh _handler
- $P0.'open'(cmd, 'pr')
+ $P0.'open'(cmd, 'r')
pop_eh
$P0.'encoding'('utf8')
setattribute self, 'stream', $P0
View
8 runtime/parrot/library/distutils.pir
@@ -3950,8 +3950,8 @@ TEMPLATE
.end
.sub 'get_timestamp' :anon
- $P0 = new 'FileHandle'
- $P0.'open'('date --rfc-2822', 'rp')
+ $P0 = new 'Pipe'
+ $P0.'open'('date --rfc-2822', 'r')
$S0 = $P0.'readline'()
$P0.'close'()
$S0 = chopn $S0, 1
@@ -4816,8 +4816,8 @@ Return the whole config
system(cmd, verbose :named('verbose'), 1 :named('ignore_error'))
unlink(srcname, verbose :named('verbose'))
- $P0 = new 'FileHandle'
- $P0.'open'(exename, 'rp')
+ $P0 = new 'Pipe'
+ $P0.'open'(exename, 'r')
$S0 = $P0.'readall'()
$P0.'close'()
View
1  src/dynoplibs/io.ops
@@ -226,7 +226,6 @@ The mode consists of a string of characters specified in any order:
r : read
w : write
a : append (Note: you must specify "wa", not just "a")
- p : pipe
=item B<open>(out PMC, in STR)
View
117 src/io/api.c
@@ -70,13 +70,13 @@ Parrot_io_init(PARROT_INTERP)
os_handle = Parrot_io_internal_std_os_handle(interp, PIO_STDIN_FILENO);
handle = Parrot_io_fdopen_flags(interp, PMCNULL, os_handle, PIO_F_READ);
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_BLKBUF);
_PIO_STDIN(interp) = handle;
os_handle = Parrot_io_internal_std_os_handle(interp, PIO_STDOUT_FILENO);
handle = Parrot_io_fdopen_flags(interp, PMCNULL, os_handle, PIO_F_WRITE);
- /* Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
+ /* Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_LINEBUF); */
_PIO_STDOUT(interp) = handle;
@@ -109,7 +109,10 @@ io_setup_vtables(PARROT_INTERP)
ASSERT_ARGS(io_setup_vtables)
const int number_of_vtables = 5;
interp->piodata->vtables = (const IO_VTABLE*)mem_gc_allocate_n_zeroed_typed(interp,
- number_of_vtables, const IO_VTABLE);
+ number_of_vtables, const IO_VTABLE);
+ interp->piodata->vtable_map = Parrot_hash_create(interp, enum_type_INTVAL,
+ Hash_key_type_ptr);
+
interp->piodata->num_vtables = number_of_vtables;
io_filehandle_setup_vtable(interp, NULL, IO_VTABLE_FILEHANDLE);
io_socket_setup_vtable(interp, NULL, IO_VTABLE_SOCKET);
@@ -129,7 +132,13 @@ Allocates a new IO_VTABLE * structure with the given name.
char * name)>
Retrieves the vtable at index C<idx>. If C<idx> is -1, the vtable is instead
-searched for by C<name>. Notice that name lookups are much slower.
+searched for by C<name>. Notice that name lookups are much slower. If both the
+C<idx> and C<name> are missing or invalid, the default vtable is returned.
+
+=item C<const IO_VTABLE * Parrot_io_get_vtable_for_pmc(PARROT_INTERP, PMC
+*handle)>
+
+Retrieves the vtable for the given handle type.
=cut
@@ -155,7 +164,7 @@ Parrot_io_allocate_new_vtable(PARROT_INTERP, ARGIN(const char *name))
}
PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
+PARROT_CANNOT_RETURN_NULL
const IO_VTABLE *
Parrot_io_get_vtable(PARROT_INTERP, INTVAL idx, ARGIN_NULLOK(const char * name))
{
@@ -163,19 +172,79 @@ Parrot_io_get_vtable(PARROT_INTERP, INTVAL idx, ARGIN_NULLOK(const char * name))
INTVAL i;
if (idx >= interp->piodata->num_vtables)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
- "Cannot get IO VTABLE %d", idx);
+ "Cannot get IO VTABLE %d (max = %d)", idx, interp->piodata->num_vtables);
+
+ /* If we have an idx, do a quick lookup. */
if (idx >= 0)
return &(interp->piodata->vtables[idx]);
+
+ /* If we have neither an idx nor a name, return the default user vtable */
if (!name)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
- "Cannot get IO VTABLE with no index and no name");
+ return &(interp->piodata->vtables[IO_VTABLE_USER]);
+ /* If we have a name, try to look it up by name. If we can't find it, return
+ the default */
for (i = 0; i < interp->piodata->num_vtables; i++) {
if (!strcmp(name, interp->piodata->vtables[i].name))
return &(interp->piodata->vtables[i]);
}
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
- "Cannot get IO VTABLE %s", name);
+ return &(interp->piodata->vtables[IO_VTABLE_USER]);
+}
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+const IO_VTABLE *
+Parrot_io_get_vtable_for_pmc(PARROT_INTERP, ARGIN(PMC *handle))
+{
+ ASSERT_ARGS(Parrot_io_get_vtable_for_pmc)
+ const IO_VTABLE * vtable = Parrot_hash_get(interp, interp->piodata->vtable_map,
+ handle->vtable->base_type);
+ if (!vtable)
+ return &(interp->piodata->vtables[IO_VTABLE_USER]);
+ return vtable;
+}
+
+/*
+
+=item C<IO_BUFFER * Parrot_io_get_handle_read_buffer(PARROT_INTERP, PMC
+*handle)>
+
+Get the read buffer for the given handle, if any.
+
+=item C<IO_BUFFER * Parrot_io_get_handle_write_buffer(PARROT_INTERP, PMC
+*handle)>
+
+Get the write buffer for the given handle, if any.
+
+=cut
+
+*/
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+IO_BUFFER *
+Parrot_io_get_handle_read_buffer(PARROT_INTERP, ARGMOD(PMC *handle))
+{
+ ASSERT_ARGS(Parrot_io_get_handle_read_buffer)
+ IO_VTABLE * const vtable = IO_GET_VTABLE(interp, handle);
+ PMC * const buffer_pmc = io_get_handle_buffer_pmc(interp, handle, IO_IDX_READ_BUFFER,
+ vtable, BUFFER_SIZE_ANY, BUFFER_FLAGS_ANY, 0);
+ if (!PMC_IS_NULL(buffer_pmc))
+ return VTABLE_get_pointer(interp, buffer_pmc);
+ return NULL;
+}
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+IO_BUFFER *
+Parrot_io_get_handle_write_buffer(PARROT_INTERP, ARGMOD(PMC *handle))
+{
+ ASSERT_ARGS(Parrot_io_get_handle_write_buffer)
+ IO_VTABLE * const vtable = IO_GET_VTABLE(interp, handle);
+ PMC * const buffer_pmc = io_get_handle_buffer_pmc(interp, handle, IO_IDX_WRITE_BUFFER,
+ vtable, BUFFER_SIZE_ANY, BUFFER_FLAGS_ANY, 0);
+ if (!PMC_IS_NULL(buffer_pmc))
+ return VTABLE_get_pointer(interp, buffer_pmc);
return NULL;
}
@@ -347,10 +416,10 @@ Parrot_io_open(PARROT_INTERP, ARGIN(PMC *pmc), ARGIN(STRING *path),
/* If this type uses buffers by default, set them up, and if we're
in an acceptable mode, set up buffers. */
if (vtable->flags & PIO_VF_DEFAULT_READ_BUF && flags & PIO_F_READ)
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_BLKBUF);
if (vtable->flags & PIO_VF_DEFAULT_WRITE_BUF && flags & PIO_F_WRITE)
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_BLKBUF);
}
@@ -709,7 +778,8 @@ Parrot_io_read_s(PARROT_INTERP, ARGMOD(PMC *handle), size_t length)
avoid using a read_buffer here. Detect that case and don't assign
a buffer if not needed. */
if (read_buffer == NULL)
- read_buffer = io_verify_has_read_buffer(interp, handle, vtable, BUFFER_SIZE_ANY);
+ read_buffer = io_verify_has_buffer(interp, handle, IO_IDX_READ_BUFFER,
+ vtable, BUFFER_SIZE_ANY, BUFFER_FLAGS_ANY);
io_verify_is_open_for(interp, handle, vtable, PIO_F_READ);
io_sync_buffers_for_read(interp, handle, vtable, read_buffer, write_buffer);
@@ -771,8 +841,8 @@ Parrot_io_readall_s(PARROT_INTERP, ARGMOD(PMC *handle))
return Parrot_str_new_init(interp, "", 0, encoding, 0);
if (total_size == PIO_UNKNOWN_SIZE) {
- IO_BUFFER * const read_buffer = io_verify_has_read_buffer(interp, handle, vtable,
- BUFFER_FLAGS_ANY);
+ IO_BUFFER * const read_buffer = io_verify_has_buffer(interp, handle,
+ IO_IDX_READ_BUFFER, vtable, BUFFER_SIZE_ANY, BUFFER_FLAGS_ANY);
size_t available_bytes = Parrot_io_buffer_fill(interp, read_buffer, handle, vtable);
STRING * const s = io_get_new_empty_string(interp, encoding, -1,
PIO_STRING_BUFFER_MINSIZE);
@@ -961,7 +1031,8 @@ Parrot_io_readline_s(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING * terminat
io_verify_is_open_for(interp, handle, vtable, PIO_F_READ);
if (read_buffer == NULL)
- read_buffer = io_verify_has_read_buffer(interp, handle, vtable, BUFFER_SIZE_ANY);
+ read_buffer = io_verify_has_buffer(interp, handle,IO_IDX_READ_BUFFER,
+ vtable, BUFFER_SIZE_ANY, BUFFER_FLAGS_ANY);
/* Because of the way buffering works, the terminator sequence may be,
at most, one character shorter than half the size of the buffer.
@@ -2017,19 +2088,19 @@ Parrot_io_set_buffer_mode(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING *mode
uses separate read/write buffers, so we have to act on them separately.
*/
if (STRING_equal(interp, mode, CONST_STRING(interp, "unbuffered"))) {
- Parrot_io_buffer_remove_from_handle(interp, handle, IO_PTR_IDX_READ_BUFFER);
- Parrot_io_buffer_remove_from_handle(interp, handle, IO_PTR_IDX_WRITE_BUFFER);
+ Parrot_io_buffer_remove_from_handle(interp, handle, IO_IDX_READ_BUFFER);
+ Parrot_io_buffer_remove_from_handle(interp, handle, IO_IDX_WRITE_BUFFER);
}
else if (STRING_equal(interp, mode, CONST_STRING(interp, "line-buffered"))) {
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_LINEBUF);
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_LINEBUF);
}
else if (STRING_equal(interp, mode, CONST_STRING(interp, "full-buffered"))) {
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_READ_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_BLKBUF);
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_WRITE_BUFFER, BUFFER_SIZE_ANY,
PIO_BF_BLKBUF);
}
else
@@ -2068,7 +2139,7 @@ Parrot_io_buffer_size(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL size, INTVAL ha
ASSERT_ARGS(Parrot_io_buffer_size)
if (has_size)
- Parrot_io_buffer_add_to_handle(interp, handle, IO_PTR_IDX_READ_BUFFER,
+ Parrot_io_buffer_add_to_handle(interp, handle, IO_IDX_READ_BUFFER,
size, PIO_BF_BLKBUF);
{
IO_BUFFER * const read_buffer = IO_GET_READ_BUFFER(interp, handle);
View
43 src/io/buffer.c
@@ -74,10 +74,10 @@ static size_t io_buffer_transfer_to_mem(PARROT_INTERP,
/*
-=item C<IO_BUFFER * Parrot_io_buffer_allocate(PARROT_INTERP, PMC *owner, INTVAL
-flags, const STR_VTABLE *encoding, size_t init_size)>
+=item C<IO_BUFFER * Parrot_io_buffer_allocate(PARROT_INTERP, INTVAL flags, const
+STR_VTABLE *encoding, size_t init_size)>
-Allocate a new buffer for PMC C<owner> with the given flags and settings.
+Allocate a new buffer with the given flags and settings.
=item C<void Parrot_io_buffer_free(PARROT_INTERP, IO_BUFFER *buffer)>
@@ -91,7 +91,7 @@ Free the C<buffer> memory.
PARROT_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
IO_BUFFER *
-Parrot_io_buffer_allocate(PARROT_INTERP, ARGMOD(PMC *owner), INTVAL flags,
+Parrot_io_buffer_allocate(PARROT_INTERP, INTVAL flags,
ARGIN_NULLOK(const STR_VTABLE *encoding), size_t init_size)
{
ASSERT_ARGS(Parrot_io_buffer_allocate)
@@ -145,15 +145,15 @@ Parrot_io_buffer_free(PARROT_INTERP, ARGFREE(IO_BUFFER *buffer))
idx, size_t length, INTVAL flags)>
Allocate a new C<IO_BUFFER*> and attach it to PMC C<handle> at position
-C<idx>. Valid positions are C<IO_PTR_IDX_READ_BUFFER> and
-C<IO_PTR_IDX_WRITE_BUFFER>. If the buffer already exists, resize it to match
+C<idx>. Valid positions are C<IO_IDX_READ_BUFFER> and
+C<IO_IDX_WRITE_BUFFER>. If the buffer already exists, resize it to match
the specifications.
=item C<void Parrot_io_buffer_remove_from_handle(PARROT_INTERP, PMC *handle,
INTVAL idx)>
Remove the buffer from C<handle> at position C<idx>. Valid positions are
-C<IO_PTR_IDX_READ_BUFFER> and C<IO_PTR_IDX_WRITE_BUFFER>.
+C<IO_IDX_READ_BUFFER> and C<IO_IDX_WRITE_BUFFER>.
=cut
@@ -164,22 +164,12 @@ Parrot_io_buffer_add_to_handle(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL idx,
size_t length, INTVAL flags)
{
ASSERT_ARGS(Parrot_io_buffer_add_to_handle)
- if (idx != IO_PTR_IDX_READ_BUFFER && idx != IO_PTR_IDX_WRITE_BUFFER)
+ if (idx != IO_IDX_READ_BUFFER && idx != IO_IDX_WRITE_BUFFER)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
"Unknown buffer number %d", idx);
{
- IO_BUFFER * buffer = (IO_BUFFER *)VTABLE_get_pointer_keyed_int(interp, handle, idx);
- if (buffer) {
- Parrot_io_buffer_resize(interp, buffer, length);
- PARROT_ASSERT(length == BUFFER_SIZE_ANY || buffer->buffer_size >= length);
- }
- else {
- buffer = Parrot_io_buffer_allocate(interp, handle, flags, NULL, length);
- PARROT_ASSERT(buffer);
- VTABLE_set_pointer_keyed_int(interp, handle, idx, buffer);
- }
- if (flags != BUFFER_FLAGS_ANY)
- buffer->flags = flags;
+ const IO_VTABLE * const vtable = IO_GET_VTABLE(interp, handle);
+ io_verify_has_buffer(interp, handle, idx, vtable, length, flags);
}
}
@@ -187,17 +177,14 @@ void
Parrot_io_buffer_remove_from_handle(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL idx)
{
ASSERT_ARGS(Parrot_io_buffer_remove_from_handle)
- if (idx != IO_PTR_IDX_READ_BUFFER && idx != IO_PTR_IDX_WRITE_BUFFER)
+ if (idx != IO_IDX_READ_BUFFER && idx != IO_IDX_WRITE_BUFFER)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
"Unknown buffer number %d", idx);
{
- IO_BUFFER * const buffer = (IO_BUFFER *)VTABLE_get_pointer_keyed_int(interp, handle, idx);
- if (!buffer)
+ PMC * const buffer_pmc = io_get_handle_buffer_pmc(interp, handle, idx, NULL, BUFFER_SIZE_ANY, BUFFER_FLAGS_ANY, 0);
+ if (PMC_IS_NULL(buffer_pmc))
return;
- /* TODO: Decrease reference count, only free it if the refcount is
- zero */
- Parrot_io_buffer_free(interp, buffer);
- VTABLE_set_pointer_keyed_int(interp, handle, idx, NULL);
+ io_remove_buffer_from_handle(interp, handle, idx);
}
}
@@ -248,8 +235,6 @@ Parrot_io_buffer_mark(SHIM_INTERP, ARGMOD_NULLOK(IO_BUFFER *buffer))
ASSERT_ARGS(Parrot_io_buffer_mark)
if (!buffer)
return;
- /*if (!PMC_IS_NULL(buffer->owner_pmc))
- Parrot_gc_mark_PMC_alive(interp, buffer->owner_pmc);*/
}
/*
View
147 src/io/filehandle.c
@@ -54,10 +54,20 @@ static const STR_VTABLE * io_filehandle_get_encoding(PARROT_INTERP,
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_WARN_UNUSED_RESULT
+static PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP,
+ ARGIN(const PMC *filehandle))
+ __attribute__nonnull__(2);
+
static INTVAL io_filehandle_get_flags(PARROT_INTERP, ARGIN(PMC *handle))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_WARN_UNUSED_RESULT
+static PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP,
+ ARGIN(const PMC *filehandle))
+ __attribute__nonnull__(2);
+
static PIOHANDLE io_filehandle_get_piohandle(PARROT_INTERP,
ARGIN(PMC *handle))
__attribute__nonnull__(1)
@@ -115,6 +125,12 @@ static void io_filehandle_set_eof(PARROT_INTERP,
__attribute__nonnull__(2)
FUNC_MODIFIES(*handle);
+static void io_filehandle_set_file_position(PARROT_INTERP,
+ ARGMOD(PMC *filehandle),
+ PIOOFF_T file_pos)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*filehandle);
+
static void io_filehandle_set_flags(PARROT_INTERP,
ARGIN(PMC *handle),
INTVAL flags)
@@ -158,9 +174,14 @@ static INTVAL io_filehandle_write_b(PARROT_INTERP,
#define ASSERT_ARGS_io_filehandle_get_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_io_filehandle_get_file_position \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_get_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_io_filehandle_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_get_piohandle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
@@ -188,6 +209,9 @@ static INTVAL io_filehandle_write_b(PARROT_INTERP,
#define ASSERT_ARGS_io_filehandle_set_eof __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
+#define ASSERT_ARGS_io_filehandle_set_file_position \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_set_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle))
@@ -248,6 +272,8 @@ io_filehandle_setup_vtable(PARROT_INTERP, ARGMOD_NULLOK(IO_VTABLE *vtable), INTV
vtable->get_flags = io_filehandle_get_flags;
vtable->total_size = io_filehandle_total_size;
vtable->get_piohandle = io_filehandle_get_piohandle;
+
+ Parrot_hash_put(interp, interp->piodata->vtable_map, enum_class_FileHandle, vtable);
}
/*
@@ -453,13 +479,6 @@ io_filehandle_open(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING *path), INTV
ASSERT_ARGS(io_filehandle_open)
PIOHANDLE os_handle;
- /* Hack! If we're opening in pipe mode, turn this FileHandle into a pipe
- and use that vtable instead. */
- if (flags & PIO_F_PIPE) {
- const IO_VTABLE * const vtable = io_filehandle_convert_to_pipe(interp, handle);
- return vtable->open(interp, handle, path, flags, mode);
- }
-
if ((flags & (PIO_F_WRITE | PIO_F_READ)) == 0)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Invalid mode for file open");
@@ -637,42 +656,25 @@ io_filehandle_get_piohandle(PARROT_INTERP, ARGIN(PMC *handle))
return io_filehandle_get_os_handle(interp, handle);
}
-
-
/*
-=item C<void io_filehandle_set_os_handle(PARROT_INTERP, PMC *filehandle,
-PIOHANDLE file_descriptor)>
+=back
-Sets the C<os_handle> attribute of the FileHandle object, which stores the
-low-level filehandle for the OS.
+=head2 Private Helper Functions
-Currently, this pokes directly into the C struct of the FileHandle PMC. This
-needs to change to a general interface that can be used by all subclasses and
-polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
-it can be cleanly changed later.
-
-Possibly, this function should reset some characteristics of the object (like
-buffer and file positions) to their default values.
+=over 4
=cut
*/
-void
-io_filehandle_set_os_handle(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOHANDLE file_descriptor)
-{
- ASSERT_ARGS(io_filehandle_set_os_handle)
- PARROT_FILEHANDLE(filehandle)->os_handle = file_descriptor;
-}
-
/*
-=item C<PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP, const PMC
+=item C<static PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP, const PMC
*filehandle)>
-Retrieve the C<os_handle> attribute of the FileHandle object, which stores the
-low-level filehandle for the OS.
+Get the C<file_pos> attribute of the FileHandle object, which stores
+the current file position of the filehandle.
Currently, this pokes directly into the C struct of the FileHandle PMC. This
needs to change to a general interface that can be used by all subclasses and
@@ -684,32 +686,21 @@ it can be cleanly changed later.
*/
PARROT_WARN_UNUSED_RESULT
-PIOHANDLE
-io_filehandle_get_os_handle(SHIM_INTERP, ARGIN(const PMC *filehandle))
+static PIOOFF_T
+io_filehandle_get_file_position(SHIM_INTERP, ARGIN(const PMC *filehandle))
{
- ASSERT_ARGS(io_filehandle_get_os_handle)
- return PARROT_FILEHANDLE(filehandle)->os_handle;
+ ASSERT_ARGS(io_filehandle_get_file_position)
+ return PARROT_FILEHANDLE(filehandle)->file_pos;
}
/*
-=back
-
-=head2 Helper Functions
-
-=over 4
-
-=cut
+=item C<static void io_filehandle_set_file_position(PARROT_INTERP, PMC
+*filehandle, PIOOFF_T file_pos)>
-*/
-
-/*
-
-=item C<PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP, const PMC
-*filehandle)>
-
-Get the C<file_pos> attribute of the FileHandle object, which stores
-the current file position of the filehandle.
+Get the C<file_pos> attribute of the FileHandle object, which stores the
+current file position of the filehandle. Also set the C<last_pos> attribute to
+the previous value of C<file_pos>.
Currently, this pokes directly into the C struct of the FileHandle PMC. This
needs to change to a general interface that can be used by all subclasses and
@@ -720,65 +711,65 @@ it can be cleanly changed later.
*/
-PARROT_WARN_UNUSED_RESULT
-PIOOFF_T
-io_filehandle_get_file_position(SHIM_INTERP, ARGIN(const PMC *filehandle))
+static void
+io_filehandle_set_file_position(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOOFF_T file_pos)
{
- ASSERT_ARGS(io_filehandle_get_file_position)
- return PARROT_FILEHANDLE(filehandle)->file_pos;
+ ASSERT_ARGS(io_filehandle_set_file_position)
+ Parrot_FileHandle_attributes * const handle_struct = PARROT_FILEHANDLE(filehandle);
+ handle_struct->last_pos = handle_struct->file_pos;
+ handle_struct->file_pos = file_pos;
}
/*
-=item C<void io_filehandle_set_file_position(PARROT_INTERP, PMC *filehandle,
-PIOOFF_T file_pos)>
+=item C<void io_filehandle_set_os_handle(PARROT_INTERP, PMC *filehandle,
+PIOHANDLE file_descriptor)>
-Get the C<file_pos> attribute of the FileHandle object, which stores the
-current file position of the filehandle. Also set the C<last_pos> attribute to
-the previous value of C<file_pos>.
+Sets the C<os_handle> attribute of the FileHandle object, which stores the
+low-level filehandle for the OS.
Currently, this pokes directly into the C struct of the FileHandle PMC. This
needs to change to a general interface that can be used by all subclasses and
polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
it can be cleanly changed later.
+Possibly, this function should reset some characteristics of the object (like
+buffer and file positions) to their default values.
+
=cut
*/
void
-io_filehandle_set_file_position(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOOFF_T file_pos)
+io_filehandle_set_os_handle(SHIM_INTERP, ARGMOD(PMC *filehandle), PIOHANDLE file_descriptor)
{
- ASSERT_ARGS(io_filehandle_set_file_position)
- Parrot_FileHandle_attributes * const handle_struct = PARROT_FILEHANDLE(filehandle);
- handle_struct->last_pos = handle_struct->file_pos;
- handle_struct->file_pos = file_pos;
+ ASSERT_ARGS(io_filehandle_set_os_handle)
+ PARROT_FILEHANDLE(filehandle)->os_handle = file_descriptor;
}
/*
-=item C<const IO_VTABLE * io_filehandle_convert_to_pipe(PARROT_INTERP, PMC
-*handle)>
+=item C<static PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP, const PMC
+*filehandle)>
-Convert FileHandle C<handle> from file mode to pipe mode by swapping vtables.
-Return the Pipe vtable.
+Retrieve the C<os_handle> attribute of the FileHandle object, which stores the
+low-level filehandle for the OS.
-Notice that this function may go away when FileHandle and Pipe are separate
-PMC types.
+Currently, this pokes directly into the C struct of the FileHandle PMC. This
+needs to change to a general interface that can be used by all subclasses and
+polymorphic equivalents of FileHandle. For now, hiding it behind a function, so
+it can be cleanly changed later.
=cut
*/
-PARROT_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
-const IO_VTABLE *
-io_filehandle_convert_to_pipe(PARROT_INTERP, ARGMOD(PMC *handle))
+static PIOHANDLE
+io_filehandle_get_os_handle(SHIM_INTERP, ARGIN(const PMC *filehandle))
{
- ASSERT_ARGS(io_filehandle_convert_to_pipe)
- const IO_VTABLE * const vtable = Parrot_io_get_vtable(interp, IO_VTABLE_PIPE, NULL);
- VTABLE_set_pointer_keyed_int(interp, handle, IO_PTR_IDX_VTABLE, (void *)vtable);
- return vtable;
+ ASSERT_ARGS(io_filehandle_get_os_handle)
+ return PARROT_FILEHANDLE(filehandle)->os_handle;
}
/*
View
104 src/io/io_private.h
@@ -125,6 +125,7 @@ struct _ParrotIOData {
PMC ** table; /* Standard IO Streams (STDIN, STDOUT, STDERR) */
INTVAL num_vtables; /* Number of vtables */
const IO_VTABLE * vtables; /* Array of VTABLES */
+ Hash * vtable_map; /* Mapping of pmc base_type -> io_vtable */
};
/* redefine PIO_STD* for internal use */
@@ -191,6 +192,19 @@ const STR_VTABLE * io_get_encoding(PARROT_INTERP,
PARROT_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
+PMC * io_get_handle_buffer_pmc(PARROT_INTERP,
+ ARGMOD(PMC *handle),
+ INTVAL buffer_idx,
+ ARGIN_NULLOK(const IO_VTABLE *vtable),
+ size_t buffer_size,
+ INTVAL flags,
+ INTVAL autocreate)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*handle);
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
STRING * io_get_new_empty_string(PARROT_INTERP,
ARGIN_NULLOK(const STR_VTABLE *encoding),
INTVAL char_length,
@@ -207,6 +221,21 @@ PARROT_WARN_UNUSED_RESULT
PMC * io_get_new_socket(PARROT_INTERP)
__attribute__nonnull__(1);
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+IO_BUFFER * io_initialize_buffer_pmc(PARROT_INTERP,
+ ARGMOD(PMC * buffer_pmc),
+ ARGMOD(PMC * handle),
+ ARGIN(const IO_VTABLE *vtable),
+ size_t buffer_size,
+ INTVAL flags)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ __attribute__nonnull__(4)
+ FUNC_MODIFIES(* buffer_pmc)
+ FUNC_MODIFIES(* handle);
+
void io_read_chars_append_string(PARROT_INTERP,
ARGMOD(STRING * s),
ARGMOD(PMC *handle),
@@ -252,6 +281,13 @@ STRING * io_readline_encoded_string(PARROT_INTERP,
FUNC_MODIFIES(*handle)
FUNC_MODIFIES(*buffer);
+void io_remove_buffer_from_handle(PARROT_INTERP,
+ ARGMOD(PMC *handle),
+ INTVAL buffer_idx)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*handle);
+
void io_sync_buffers_for_read(PARROT_INTERP,
ARGMOD(PMC *handle),
ARGIN(const IO_VTABLE *vtable),
@@ -278,13 +314,15 @@ void io_sync_buffers_for_write(PARROT_INTERP,
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
-IO_BUFFER * io_verify_has_read_buffer(PARROT_INTERP,
+IO_BUFFER * io_verify_has_buffer(PARROT_INTERP,
ARGIN(PMC *handle),
+ INTVAL buffer_idx,
ARGIN(const IO_VTABLE *vtable),
+ size_t buffer_size,
INTVAL flags)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
- __attribute__nonnull__(3);
+ __attribute__nonnull__(4);
void io_verify_is_open_for(PARROT_INTERP,
ARGIN(PMC *handle),
@@ -313,12 +351,20 @@ STRING * io_verify_string_encoding(PARROT_INTERP,
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle) \
, PARROT_ASSERT_ARG(vtable))
+#define ASSERT_ARGS_io_get_handle_buffer_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(handle))
#define ASSERT_ARGS_io_get_new_empty_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_io_get_new_filehandle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_io_get_new_socket __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_io_initialize_buffer_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(buffer_pmc) \
+ , PARROT_ASSERT_ARG(handle) \
+ , PARROT_ASSERT_ARG(vtable))
#define ASSERT_ARGS_io_read_chars_append_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(s) \
@@ -335,6 +381,9 @@ STRING * io_verify_string_encoding(PARROT_INTERP,
, PARROT_ASSERT_ARG(vtable) \
, PARROT_ASSERT_ARG(buffer) \
, PARROT_ASSERT_ARG(rs))
+#define ASSERT_ARGS_io_remove_buffer_from_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(handle))
#define ASSERT_ARGS_io_sync_buffers_for_read __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle) \
@@ -343,7 +392,7 @@ STRING * io_verify_string_encoding(PARROT_INTERP,
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle) \
, PARROT_ASSERT_ARG(vtable))
-#define ASSERT_ARGS_io_verify_has_read_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_io_verify_has_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(handle) \
, PARROT_ASSERT_ARG(vtable))
@@ -362,30 +411,6 @@ STRING * io_verify_string_encoding(PARROT_INTERP,
/* HEADERIZER BEGIN: src/io/filehandle.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-const IO_VTABLE * io_filehandle_convert_to_pipe(PARROT_INTERP,
- ARGMOD(PMC *handle))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*handle);
-
-PARROT_WARN_UNUSED_RESULT
-PIOOFF_T io_filehandle_get_file_position(PARROT_INTERP,
- ARGIN(const PMC *filehandle))
- __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PIOHANDLE io_filehandle_get_os_handle(PARROT_INTERP,
- ARGIN(const PMC *filehandle))
- __attribute__nonnull__(2);
-
-void io_filehandle_set_file_position(PARROT_INTERP,
- ARGMOD(PMC *filehandle),
- PIOOFF_T file_pos)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*filehandle);
-
void io_filehandle_set_os_handle(PARROT_INTERP,
ARGMOD(PMC *filehandle),
PIOHANDLE file_descriptor)
@@ -398,17 +423,6 @@ void io_filehandle_setup_vtable(PARROT_INTERP,
__attribute__nonnull__(1)
FUNC_MODIFIES(*vtable);
-#define ASSERT_ARGS_io_filehandle_convert_to_pipe __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(handle))
-#define ASSERT_ARGS_io_filehandle_get_file_position \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(filehandle))
-#define ASSERT_ARGS_io_filehandle_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(filehandle))
-#define ASSERT_ARGS_io_filehandle_set_file_position \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_set_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(filehandle))
#define ASSERT_ARGS_io_filehandle_setup_vtable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -419,12 +433,26 @@ void io_filehandle_setup_vtable(PARROT_INTERP,
/* HEADERIZER BEGIN: src/io/pipe.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+PARROT_WARN_UNUSED_RESULT
+PIOHANDLE io_pipe_get_os_handle(PARROT_INTERP, ARGIN(const PMC *pipe))
+ __attribute__nonnull__(2);
+
+void io_pipe_set_os_handle(PARROT_INTERP,
+ ARGMOD(PMC *pipe),
+ PIOHANDLE pipe_descriptor)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pipe);
+
void io_pipe_setup_vtable(PARROT_INTERP,
ARGMOD_NULLOK(IO_VTABLE *vtable),
INTVAL idx)
__attribute__nonnull__(1)
FUNC_MODIFIES(*vtable);
+#define ASSERT_ARGS_io_pipe_get_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pipe))
+#define ASSERT_ARGS_io_pipe_set_os_handle __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pipe))
#define ASSERT_ARGS_io_pipe_setup_vtable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
View
120 src/io/pipe.c
@@ -19,7 +19,7 @@ This file implements the IO_VTABLE for pipes and helper functions.
#include "parrot/parrot.h"
#include "io_private.h"
-#include "pmc/pmc_filehandle.h"
+#include "pmc/pmc_pipe.h"
/* HEADERIZER HFILE: src/io/io_private.h */
@@ -240,6 +240,8 @@ io_pipe_setup_vtable(PARROT_INTERP, ARGMOD_NULLOK(IO_VTABLE *vtable), INTVAL idx
vtable->get_flags = io_pipe_get_flags;
vtable->total_size = io_pipe_total_size;
vtable->get_piohandle = io_pipe_get_piohandle;
+
+ Parrot_hash_put(interp, interp->piodata->vtable_map, enum_class_Pipe, vtable);
}
/*
@@ -257,13 +259,13 @@ static INTVAL
io_pipe_read_b(PARROT_INTERP, ARGMOD(PMC *handle), ARGOUT(char *buffer), size_t byte_length)
{
ASSERT_ARGS(io_pipe_read_b)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
const size_t bytes_read = Parrot_io_internal_read(interp, os_handle, buffer, byte_length);
if (bytes_read == 0) {
INTVAL flags;
- GETATTR_FileHandle_flags(interp, handle, flags);
+ GETATTR_Pipe_flags(interp, handle, flags);
flags |= PIO_F_EOF;
- SETATTR_FileHandle_flags(interp, handle, flags);
+ SETATTR_Pipe_flags(interp, handle, flags);
}
return bytes_read;
}
@@ -283,7 +285,7 @@ static INTVAL
io_pipe_write_b(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(char *buffer), size_t byte_length)
{
ASSERT_ARGS(io_pipe_write_b)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
return Parrot_io_internal_write(interp, os_handle, buffer, byte_length);
}
@@ -302,7 +304,7 @@ io_pipe_flush(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_flush)
/* TODO: In read mode, don't do what this does. */
- PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
return Parrot_io_internal_flush(interp, os_handle);
}
@@ -325,7 +327,7 @@ io_pipe_is_eof(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_is_eof)
INTVAL flags;
- GETATTR_FileHandle_flags(interp, handle, flags);
+ GETATTR_Pipe_flags(interp, handle, flags);
if (flags & PIO_F_EOF)
return 1;
return 0;
@@ -336,9 +338,9 @@ io_pipe_set_eof(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL is_set)
{
ASSERT_ARGS(io_pipe_set_eof)
if (is_set)
- PARROT_FILEHANDLE(handle)->flags |= PIO_F_EOF;
+ PARROT_PIPE(handle)->flags |= PIO_F_EOF;
else
- PARROT_FILEHANDLE(handle)->flags &= ~PIO_F_EOF;
+ PARROT_PIPE(handle)->flags &= ~PIO_F_EOF;
}
/*
@@ -399,7 +401,7 @@ io_pipe_adv_position(PARROT_INTERP, ARGMOD(PMC *handle), size_t offset)
ASSERT_ARGS(io_pipe_adv_position)
UNUSED(handle);
UNUSED(offset);
- /* Pipes don't keep track of file position internally. Ignore this. */
+ /* Pipes don't keep track of stream position internally. Ignore this. */
}
/*
@@ -419,7 +421,7 @@ io_pipe_set_position(PARROT_INTERP, ARGMOD(PMC *handle), PIOOFF_T pos)
ASSERT_ARGS(io_pipe_set_position)
UNUSED(handle);
UNUSED(pos);
- /* Pipes don't keep track of file position internally. Ignore. */
+ /* Pipes don't keep track of stream position internally. Ignore. */
}
/*
@@ -436,7 +438,7 @@ static PIOOFF_T
io_pipe_get_position(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_get_position)
- /* Pipes don't keep track of file position internally. Return 0 */
+ /* Pipes don't keep track of stream position internally. Return 0 */
return (PIOOFF_T)0;
}
@@ -462,14 +464,6 @@ io_pipe_open(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING *path), INTVAL fla
INTVAL pid;
PIOHANDLE os_handle;
- /* Hack! If we're opening in file mode, turn this FileHandle into a file
- and use that vtable instead. */
- if ((flags & PIO_F_PIPE) == 0) {
- const IO_VTABLE * const vtable = Parrot_io_get_vtable(interp, IO_VTABLE_FILEHANDLE, NULL);
- VTABLE_set_pointer_keyed_int(interp, handle, IO_PTR_IDX_VTABLE, (void *)vtable);
- return vtable->open(interp, handle, path, flags, mode);
- }
-
if (f_read == f_write)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
"Invalid pipe mode: %X", flags);
@@ -480,13 +474,12 @@ io_pipe_open(PARROT_INTERP, ARGMOD(PMC *handle), ARGIN(STRING *path), INTVAL fla
VTABLE_set_integer_keyed_int(interp, handle, 0, pid);
if (flags & PIO_F_BINARY)
- SETATTR_FileHandle_encoding(interp, handle, Parrot_str_new(interp, "binary", 0));
+ SETATTR_Pipe_encoding(interp, handle, Parrot_str_new(interp, "binary", 0));
- SETATTR_FileHandle_os_handle(interp, handle, os_handle);
- SETATTR_FileHandle_flags(interp, handle, flags);
- SETATTR_FileHandle_filename(interp, handle, path);
- SETATTR_FileHandle_mode(interp, handle, mode);
- SETATTR_FileHandle_file_pos(interp, handle, 0);
+ SETATTR_Pipe_os_handle(interp, handle, os_handle);
+ SETATTR_Pipe_flags(interp, handle, flags);
+ SETATTR_Pipe_procname(interp, handle, path);
+ SETATTR_Pipe_mode(interp, handle, mode);
return 1;
}
@@ -505,7 +498,7 @@ static INTVAL
io_pipe_is_open(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_is_open)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
return os_handle != PIO_INVALID_HANDLE;
}
@@ -523,7 +516,7 @@ static INTVAL
io_pipe_close(PARROT_INTERP, ARGMOD(PMC *handle))
{
ASSERT_ARGS(io_pipe_close)
- const PIOHANDLE os_handle = io_filehandle_get_os_handle(interp, handle);
+ const PIOHANDLE os_handle = io_pipe_get_os_handle(interp, handle);
if (os_handle == PIO_INVALID_HANDLE)
return -1;
@@ -532,10 +525,10 @@ io_pipe_close(PARROT_INTERP, ARGMOD(PMC *handle))
INTVAL pid;
INTVAL status;
INTVAL result = Parrot_io_internal_close(interp, os_handle);
- io_filehandle_set_os_handle(interp, handle, PIO_INVALID_HANDLE);
- GETATTR_FileHandle_process_id(interp, handle, pid);
+ io_pipe_set_os_handle(interp, handle, PIO_INVALID_HANDLE);
+ GETATTR_Pipe_process_id(interp, handle, pid);
status = Parrot_proc_waitpid(interp, pid);
- SETATTR_FileHandle_exit_status(interp, handle, status);
+ SETATTR_Pipe_exit_status(interp, handle, status);
io_pipe_set_flags(interp, handle, 0);
return result;
}
@@ -561,7 +554,7 @@ io_pipe_get_encoding(PARROT_INTERP, ARGIN(PMC *handle))
STRING *encoding_str;
const STR_VTABLE *encoding;
- GETATTR_FileHandle_encoding(interp, handle, encoding_str);
+ GETATTR_Pipe_encoding(interp, handle, encoding_str);
if (!STRING_IS_NULL(encoding_str))
return Parrot_find_encoding_by_string(interp, encoding_str);
return NULL;
@@ -581,7 +574,7 @@ static void
io_pipe_set_flags(PARROT_INTERP, ARGIN(PMC *handle), INTVAL flags)
{
ASSERT_ARGS(io_pipe_set_flags)
- PARROT_FILEHANDLE(handle)->flags = flags;
+ PARROT_PIPE(handle)->flags = flags;
}
/*
@@ -598,7 +591,7 @@ static INTVAL
io_pipe_get_flags(PARROT_INTERP, ARGIN(PMC *handle))
{
ASSERT_ARGS(io_pipe_get_flags)
- return PARROT_FILEHANDLE(handle)->flags;
+ return PARROT_PIPE(handle)->flags;
}
/*
@@ -632,7 +625,64 @@ static PIOHANDLE
io_pipe_get_piohandle(PARROT_INTERP, ARGIN(PMC *handle))
{
ASSERT_ARGS(io_pipe_get_piohandle)
- return io_filehandle_get_os_handle(interp, handle);
+ return io_pipe_get_os_handle(interp, handle);
+}
+
+/*
+
+=back
+
+=head2 Private Helper Functions
+
+=over 4
+
+=item C<void io_pipe_set_os_handle(PARROT_INTERP, PMC *pipe, PIOHANDLE
+pipe_descriptor)>
+
+Sets the C<os_handle> attribute of the Pipe object, which stores the
+low-level pipe for the OS.
+
+Currently, this pokes directly into the C struct of the Pipe PMC. This
+needs to change to a general interface that can be used by all subclasses and
+polymorphic equivalents of Pipe. For now, hiding it behind a function, so
+it can be cleanly changed later.
+
+Possibly, this function should reset some characteristics of the object (like
+buffer position) to their default values.
+
+=cut
+
+*/
+
+void
+io_pipe_set_os_handle(SHIM_INTERP, ARGMOD(PMC *pipe), PIOHANDLE pipe_descriptor)
+{
+ ASSERT_ARGS(io_pipe_set_os_handle)
+ PARROT_PIPE(pipe)->os_handle = pipe_descriptor;
+}
+
+/*
+
+=item C<PIOHANDLE io_pipe_get_os_handle(PARROT_INTERP, const PMC *pipe)>
+
+Retrieve the C<os_handle> attribute of the pipe object, which stores the
+low-level pipe for the OS.
+
+Currently, this pokes directly into the C struct of the Pipe PMC. This
+needs to change to a general interface that can be used by all subclasses and
+polymorphic equivalents of Pipe. For now, hiding it behind a function, so
+it can be cleanly changed later.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PIOHANDLE
+io_pipe_get_os_handle(SHIM_INTERP, ARGIN(const PMC *pipe))
+{
+ ASSERT_ARGS(io_pipe_get_os_handle)
+ return PARROT_PIPE(pipe)->os_handle;
}
/*
View
2  src/io/socket.c
@@ -243,6 +243,8 @@ io_socket_setup_vtable(PARROT_INTERP, ARGMOD_NULLOK(IO_VTABLE *vtable), INTVAL i
vtable->set_flags = io_socket_set_flags;
vtable->get_flags = io_socket_get_flags;
vtable->total_size = io_socket_total_size;
+
+ Parrot_hash_put(interp, interp->piodata->vtable_map, enum_class_Socket, vtable);
}
/*
View
2  src/io/stringhandle.c
@@ -251,6 +251,8 @@ io_stringhandle_setup_vtable(PARROT_INTERP, ARGMOD_NULLOK(IO_VTABLE *vtable), IN
vtable->get_flags = io_stringhandle_get_flags;
vtable->total_size = io_stringhandle_total_size;
vtable->get_piohandle = io_stringhandle_get_piohandle;
+
+ Parrot_hash_put(interp, interp->piodata->vtable_map, enum_class_StringHandle, vtable);
}
/*
View
1  src/io/userhandle.c
@@ -199,6 +199,7 @@ io_userhandle_setup_vtable(PARROT_INTERP, ARGMOD_NULLOK(IO_VTABLE *vtable), INTV
vtable->total_size = io_userhandle_total_size;
vtable->get_piohandle = io_userhandle_get_piohandle;
*/
+ Parrot_hash_put(interp, interp->piodata->vtable_map, enum_class_Object, vtable);
}
View
121 src/io/utilities.c
@@ -21,10 +21,22 @@ of intelligence between the IO API and the buffering API.
#include "parrot/parrot.h"
#include "io_private.h"
+#include "utilities.str"
/* HEADERIZER HFILE: src/io/io_private.h */
/* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+static STRING * io_get_buffer_prop_name(PARROT_INTERP, INTVAL buffer_idx)
+ __attribute__nonnull__(1);
+
+#define ASSERT_ARGS_io_get_buffer_prop_name __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
/*
@@ -71,7 +83,8 @@ Parrot_io_parse_open_flags(PARROT_INTERP, ARGIN(const STRING *mode_str))
flags &= ~PIO_F_TRUNC;
break;
case 'p':
- flags |= PIO_F_PIPE;
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Open mode 'p' is no longer valid. Use a Pipe PMC instead.");
break;
case 'b':
flags |= PIO_F_BINARY;
@@ -198,29 +211,113 @@ IO_VTABLE *vtable, INTVAL flags)>
Verify that the given C<handle> has a read buffer attached. If not, allocate
one.
+=item C<IO_BUFFER * io_get_handle_read_buffer_pmc(PARROT_INTERP, PMC *handle,
+INTVAL autocreate)>
+
+Get the read buffer PMC for the given handle, if any. Autocreate the buffer
+if necessary.
+
+=item C<IO_BUFFER * io_get_handle_write_buffer_pmc(PARROT_INTERP, PMC *handle,
+INTVAL autocreate)>
+
+Get the write buffer for the given handle, if any. Autocreate the buffer
+if necessary.
+
=cut
*/
+void
+io_remove_buffer_from_handle(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL buffer_idx)
+{
+ //ASSERT_ARGS(io_remove_buffer_from_handle)
+ STRING * const prop_name = io_get_buffer_prop_name(interp, buffer_idx);
+ Parrot_pmc_delprop(interp, handle, prop_name);
+}
+
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
IO_BUFFER *
-io_verify_has_read_buffer(PARROT_INTERP, ARGIN(PMC *handle),
- ARGIN(const IO_VTABLE *vtable), INTVAL flags)
+io_verify_has_buffer(PARROT_INTERP, ARGIN(PMC *handle), INTVAL buffer_idx,
+ ARGIN(const IO_VTABLE *vtable), size_t buffer_size, INTVAL flags)
+{
+ ASSERT_ARGS(io_verify_has_buffer)
+ PMC * buffer_pmc = io_get_handle_buffer_pmc(interp, handle, buffer_idx,
+ vtable, buffer_size, flags, 1);
+ return (IO_BUFFER*) VTABLE_get_pointer(interp, buffer_pmc);
+}
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+static STRING *
+io_get_buffer_prop_name(PARROT_INTERP, INTVAL buffer_idx)
{
- ASSERT_ARGS(io_verify_has_read_buffer)
- IO_BUFFER * buffer = IO_GET_READ_BUFFER(interp, handle);
- if (!buffer) {
+ ASSERT_ARGS(io_get_buffer_prop_name)
+ switch (buffer_idx) {
+ case IO_IDX_READ_BUFFER:
+ return CONST_STRING(interp, "!Parrot_io_read_buffer!");
+ case IO_IDX_WRITE_BUFFER:
+ return CONST_STRING(interp, "!Parrot_io_write_buffer!");
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Unknown buffer index %d", buffer_idx);
+ }
+}
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PMC *
+io_get_handle_buffer_pmc(PARROT_INTERP, ARGMOD(PMC *handle), INTVAL buffer_idx,
+ ARGIN_NULLOK(const IO_VTABLE *vtable), size_t buffer_size, INTVAL flags,
+ INTVAL autocreate)
+{
+ ASSERT_ARGS(io_get_handle_buffer_pmc)
+ STRING * const prop_name = io_get_buffer_prop_name(interp, buffer_idx);
+
+ PMC * buffer_pmc = Parrot_pmc_getprop(interp, handle, prop_name);
+ /* TODO: Verify that the buffer is at least the size specified */
+ if (PMC_IS_NULL(buffer_pmc) && autocreate) {
+ buffer_pmc = Parrot_pmc_new(interp, enum_class_IOBuffer);
+ io_initialize_buffer_pmc(interp, buffer_pmc, handle, vtable, buffer_size, flags);
+
+ /* Store the buffer on the handle as a property */
+ Parrot_pmc_setprop(interp, handle, prop_name, buffer_pmc);
+ }
+ return buffer_pmc;
+}
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+IO_BUFFER *
+io_initialize_buffer_pmc(PARROT_INTERP, ARGMOD(PMC * buffer_pmc),
+ ARGMOD(PMC * handle), ARGIN(const IO_VTABLE *vtable), size_t buffer_size,
+ INTVAL flags)
+{
+ ASSERT_ARGS(io_initialize_buffer_pmc)
+ PARROT_ASSERT(!PMC_IS_NULL(buffer_pmc));
+ PARROT_ASSERT(!PMC_IS_NULL(handle));
+ vtable = vtable ? vtable : IO_GET_VTABLE(interp, handle);
+ PARROT_ASSERT(vtable);
+ {
+ /* Set up the buffer with the correct encoding */
const STR_VTABLE * encoding = vtable->get_encoding(interp, handle);
if (encoding == NULL)
encoding = Parrot_platform_encoding_ptr;
- buffer = Parrot_io_buffer_allocate(interp, handle, flags, encoding, BUFFER_SIZE_ANY);
- VTABLE_set_pointer_keyed_int(interp, handle, IO_PTR_IDX_READ_BUFFER, buffer);
+ {
+ IO_BUFFER * const buffer = Parrot_io_buffer_allocate(interp,
+ BUFFER_FLAGS_ANY, encoding,
+ buffer_size);
+
+ /* Make sure to use the correct flags */
+ if (flags != BUFFER_FLAGS_ANY)
+ buffer->flags = flags;
+
+ /* Assign the buffer to the IOBuffer PMC */
+ VTABLE_set_pointer(interp, buffer_pmc, buffer);
+ return buffer;
+ }
}
- PARROT_ASSERT(buffer);
- if (flags != BUFFER_FLAGS_ANY)
- buffer->flags = flags;
- return buffer;
}
/*
View
11 src/pmc.c
@@ -1168,10 +1168,13 @@ PMC *
Parrot_pmc_getprop(PARROT_INTERP, ARGIN(PMC *pmc), ARGIN(STRING *key))
{
ASSERT_ARGS(Parrot_pmc_getprop)
- if (PMC_IS_NULL(PMC_metadata(pmc)))
+ PMC * const props = PMC_metadata(pmc);
+ if (PMC_IS_NULL(props))
return check_get_std_props(interp, pmc, key);
- else
- return VTABLE_get_pmc_keyed_str(interp, PMC_metadata(pmc), key);
+ else {
+ PARROT_ASSERT(props);
+ return VTABLE_get_pmc_keyed_str(interp, props, key);
+ }
}
/*
@@ -1386,6 +1389,8 @@ make_prop_hash(PARROT_INTERP, ARGMOD(PMC *self))
PMC * const prop = Parrot_pmc_new(interp, enum_class_Hash);
propagate_std_props(interp, self, prop);
+ PARROT_ASSERT(prop);
+ PARROT_ASSERT(prop->data);
PARROT_GC_WRITE_BARRIER(interp, self);
return prop;
}
View
76 src/pmc/filehandle.pmc
@@ -39,17 +39,9 @@ pmclass FileHandle extends Handle auto_attrs {
ATTR INTVAL flags; /* Filehandle flags */
ATTR STRING *filename; /* The opened path and filename */
ATTR STRING *mode; /* The mode string used in open */
- ATTR INTVAL process_id; /* Child process on pipes */
- ATTR INTVAL exit_status; /* Child exit status on pipes */
ATTR PIOOFF_T file_pos; /* Current real file pointer */
ATTR PIOOFF_T last_pos; /* Last file position */
-
-/*
- * Using INTVAL for process_id is a temporary solution.
- * We may need to define a custom type to store it in a platform dependant way.
- */
-
/*
=item C<void init()>
@@ -69,8 +61,6 @@ Initializes a newly created FileHandle object.
attrs->filename = STRINGNULL;
attrs->mode = STRINGNULL;
attrs->encoding = STRINGNULL;
- attrs->process_id = 0;
- attrs->exit_status = 0;
attrs->file_pos = piooffsetzero;
attrs->last_pos = piooffsetzero;
attrs->io_vtable = (IO_VTABLE *)Parrot_io_get_vtable(interp,
@@ -115,8 +105,6 @@ Create a copy of the filehandle.
/* Copy over some metadata */
new_attrs->flags = old_attrs->flags;
- new_attrs->process_id = old_attrs->process_id;
- new_attrs->exit_status = old_attrs->exit_status;
new_attrs->file_pos = old_attrs->file_pos;
new_attrs->last_pos = old_attrs->last_pos;
@@ -167,54 +155,6 @@ Free structures.
/* TODO: flush and free the buffers */
}
-
-/*
-
-=item C<INTVAL get_integer_keyed_int(INTVAL key)>
-
-Shortcut to get the value of some attributes.
-For internal usage only, subject to change without notice.
-
-=cut
-
-*/
-
- VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
- INTVAL result;
- switch (key) {
- case 0:
- GET_ATTR_process_id(INTERP, SELF, result);
- break;
- default:
- result = 0;
- }
-
- return result;
- }
-
-
-/*
-
-=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
-
-Shortcut to set the value of some attributes
-For internal usage only, subject to change without notice.
-
-=cut
-
-*/
-
- VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
- switch (key) {
- case 0:
- SET_ATTR_process_id(INTERP, SELF, value);
- break;
- default:
- break;
- }
- }
-
-
/*
=item C<INTVAL get_bool()>
@@ -565,22 +505,6 @@ Returns the INTVAL used by the OS to identify this filehandle.
/*
-=item C<METHOD exit_status()>
-
-If this is a pipe, return the exit status of the child process.
-
-=cut
-
-*/
- METHOD exit_status() {
- INTVAL exit_status;
- GET_ATTR_exit_status(INTERP, SELF, exit_status);
- RETURN(INTVAL exit_status);
- }
-
-
-/*
-
=item C<METHOD tell()>
Get the file position of the stream. 2 C<INTVAL>s are returned. The first is
View
40 src/pmc/handle.pmc
@@ -36,8 +36,6 @@ pmclass Handle provides Handle manual_attrs {
ATTR PIOHANDLE os_handle; /* Low level OS descriptor */
ATTR STRING *record_separator; /* Record separator */
ATTR IO_VTABLE *io_vtable; /* Function dispatch table */
- ATTR IO_BUFFER *read_buffer; /* Read Buffer */
- ATTR IO_BUFFER *write_buffer; /* Write Buffer */
ATTR STRING *encoding; /* The encoding for read/write */
@@ -51,44 +49,6 @@ pmclass Handle provides Handle manual_attrs {
"Handle cannot be instantiated directly.");
}
- VTABLE void *get_pointer_keyed_int(INTVAL key)
- {
- void * ptr;
- switch (key) {
- case IO_PTR_IDX_VTABLE:
- GET_ATTR_io_vtable(INTERP, SELF, ptr);
- break;
- case IO_PTR_IDX_READ_BUFFER:
- GET_ATTR_read_buffer(INTERP, SELF, ptr);
- break;
- case IO_PTR_IDX_WRITE_BUFFER:
- GET_ATTR_write_buffer(INTERP, SELF, ptr);
- break;
- default:
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_PIO_ERROR,
- "Handle: Cannot get pointer %d", key);
- }
- return ptr;
- }
-
- VTABLE void set_pointer_keyed_int(INTVAL key, void *ptr)
- {
- switch (key) {
- case IO_PTR_IDX_VTABLE:
- SET_ATTR_io_vtable(INTERP, SELF, (IO_VTABLE *)ptr);
- break;
- case IO_PTR_IDX_READ_BUFFER:
- SET_ATTR_read_buffer(INTERP, SELF, (IO_BUFFER *)ptr);
- break;
- case IO_PTR_IDX_WRITE_BUFFER:
- SET_ATTR_write_buffer(INTERP, SELF, (IO_BUFFER *)ptr);
- break;
- default:
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_PIO_ERROR,
- "Handle: Cannot set pointer %d", key);
- }
- }
-
/*
=back
View
49 src/pmc/iobuffer.pmc
@@ -0,0 +1,49 @@
+/* HEADERIZER HFILE: none */
+/* HEADERIZER BEGIN: static */
+/* HEADERIZER END: static */
+
+pmclass IOBuffer auto_attrs {
+ ATTR IO_BUFFER * buffer;
+
+ VTABLE void init() {
+ Parrot_IOBuffer_attributes * const attrs = PARROT_IOBUFFER(SELF);
+ attrs->buffer = NULL;
+ PObj_custom_mark_SET(SELF);
+ PObj_custom_destroy_SET(SELF);
+ }
+
+ VTABLE void init_int(INTVAL buffer_size) {
+ VTABLE_init(INTERP, SELF);
+ VTABLE_set_integer_native(INTERP, SELF, buffer_size);
+ }
+
+ VTABLE void set_integer_native(INTVAL buffer_size) {
+ Parrot_IOBuffer_attributes * const attrs = PARROT_IOBUFFER(SELF);
+
+ PARROT_ASSERT(buffer_size > 0);
+ if (attrs->buffer)
+ Parrot_io_buffer_resize(INTERP, attrs->buffer, buffer_size);
+ else
+ attrs->buffer = Parrot_io_buffer_allocate(INTERP, 0,
+ Parrot_platform_encoding_ptr, (size_t)buffer_size);
+ }
+
+ VTABLE void mark() {