[svn:mod_parrot] r560 - in mod_parrot/trunk: . include lib src/pmc
[email protected] Tue, 30 Dec 2008 14:13:25 -0800 (PST)
| Newsgroups | perl.cvs.mod_parrot |
|---|---|
| Message-ID | <[email protected]> |
Author: jhorwitz
Date: Tue Dec 30 14:13:25 2008
New Revision: 560
Added:
mod_parrot/trunk/src/pmc/
mod_parrot/trunk/src/pmc/modparrothandle.pmc
Modified:
mod_parrot/trunk/CHANGES
mod_parrot/trunk/Makefile.in
mod_parrot/trunk/include/mod_parrot.h
mod_parrot/trunk/lib/mod_parrot.pir
Log:
New ModParrotHandle PMC ties Parrot I/O ops to Apache I/O
Modified: mod_parrot/trunk/CHANGES
==============================================================================
--- mod_parrot/trunk/CHANGES (original)
+++ mod_parrot/trunk/CHANGES Tue Dec 30 14:13:25 2008
@@ -27,6 +27,7 @@
* Various configuration fixes
* Refactored lots of code to make it easier to maintain
* Refactored PIR compilation rules in Makefile
+ * New ModParrotHandle PMC ties Parrot I/O ops to Apache I/O
mod_perl6:
* Replace PIR mod_perl6 with pure-perl mod_perl6
Modified: mod_parrot/trunk/Makefile.in
==============================================================================
--- mod_parrot/trunk/Makefile.in (original)
+++ mod_parrot/trunk/Makefile.in Tue Dec 30 14:13:25 2008
@@ -19,6 +19,10 @@
PARROT_BLIB_DIR=@PARROT_BLIB_DIR@
PARROT=@PARROT@
APACHE_INCLUDE_DIR=@APACHE_INCLUDE_DIR@
+PARROT_DYNEXT=$(PARROT_SOURCE)/runtime/parrot/dynext
+BUILD_DYNPMC=$(PERL) $(PARROT_SOURCE)/tools/build/dynpmc.pl
+MODPARROT_GROUP=modparrot_group.so
+export DYNPMC_INCLUDE=$(APACHE_INCLUDE_DIR),../../include
SRC_DIR = src
TEST_SRC_DIR = t/src
@@ -56,7 +60,11 @@
lib/ModParrot/HLL/lolcode.pbc \
lib/ModParrot/HLL/nqp.pbc
-all: gen-src $(SRC_DIR)/mod_parrot.la libs
+PMCS= modparrothandle
+
+PMC_SOURCES= $(SRC_DIR)/pmc/modparrothandle.pmc
+
+all: gen-src $(SRC_DIR)/mod_parrot.la libs $(MODPARROT_GROUP)
%.lo: %.c
$(LIBTOOL) --mode=compile $(CC) -o $@ $(EXTRA_CPPFLAGS) $(DEBUG) $(CFLAGS) -I$(APACHE_INCLUDE_DIR) -I$(APR_INCLUDE_DIR) -I$(APU_INCLUDE_DIR) $(DEFINES) -c $<
@@ -73,6 +81,11 @@
libs: $(MPLIBS)
+$(MODPARROT_GROUP): $(PMC_SOURCES)
+ cd $(SRC_DIR)/pmc && $(BUILD_DYNPMC) generate $(PMCS)
+ cd $(SRC_DIR)/pmc && $(BUILD_DYNPMC) compile $(PMCS)
+ cd $(SRC_DIR)/pmc && $(BUILD_DYNPMC) linklibs $(PMCS)
+
modperl6: languages/perl6/lib/mod_perl6.pir languages/perl6/lib/ModPerl6/Registry.pir
%.pir: %.pm
@@ -94,17 +107,26 @@
libs-clean:
rm -f $(MPLIBS)
+pmcs-clean:
+ rm -f $(SRC_DIR)/pmc/$(MODPARROT_GROUP)
+ rm -f $(SRC_DIR)/pmc/*.c
+ rm -f $(SRC_DIR)/pmc/*.h
+ rm -f $(SRC_DIR)/pmc/*.o
+ rm -f $(SRC_DIR)/pmc/*.dump
+ rm -f $(SRC_DIR)/pmc/*.exp
+
test-clean:
if [ -x t/TEST ]; then t/TEST -clean; fi
rm -f t/core.* t/lib/handlers.pbc t/TEST
-clean: files-clean libs-clean gen-src-clean modperl6-clean
+clean: files-clean libs-clean pmcs-clean gen-src-clean modperl6-clean
distclean: clean test-clean
rm -f Makefile Makefile.old
-install: $(SRC_DIR)/mod_parrot.la
+install: $(SRC_DIR)/mod_parrot.la $(MODPARROT_GROUP)
$(APXS) -i -n parrot -a $(SRC_DIR)/mod_parrot.la
+ cd $(SRC_DIR)/pmc && $(BUILD_DYNPMC) copy "--destination=$(PARROT_DYNEXT)" $(PMCS)
test: $(SRC_DIR)/mod_parrot.la libs
$(PARROT) -o t/lib/handlers.pbc t/lib/handlers.pir
Modified: mod_parrot/trunk/include/mod_parrot.h
==============================================================================
--- mod_parrot/trunk/include/mod_parrot.h (original)
+++ mod_parrot/trunk/include/mod_parrot.h Tue Dec 30 14:13:25 2008
@@ -99,5 +99,6 @@
Parrot_PMC, Parrot_PMC);
modparrot_context *modparrot_get_current_ctx(apr_pool_t *);
void modparrot_set_current_ctx(apr_pool_t *, modparrot_context *);
+apr_size_t modparrot_request_read(request_rec *, char *, apr_size_t);
#endif /* _MODPARROT_H */
Modified: mod_parrot/trunk/lib/mod_parrot.pir
==============================================================================
--- mod_parrot/trunk/lib/mod_parrot.pir (original)
+++ mod_parrot/trunk/lib/mod_parrot.pir Tue Dec 30 14:13:25 2008
@@ -18,6 +18,8 @@
.include 'iglobals.pasm'
+.loadlib 'modparrot_group.so'
+
# use when NCI can dlfunc from the current image
.sub modparrot_init
.local pmc func
Added: mod_parrot/trunk/src/pmc/modparrothandle.pmc
==============================================================================
--- (empty file)
+++ mod_parrot/trunk/src/pmc/modparrothandle.pmc Tue Dec 30 14:13:25 2008
@@ -0,0 +1,547 @@
+/* $Id $ */
+
+/* Copyright (c) 2008 Jeff Horwitz
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+
+=head1 NAME
+
+src/pmc/modparrothandle.pmc - ModParrotHandle PMC
+
+=head1 DESCRIPTION
+
+=head2 Vtable Functions
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+#include "../src/io/io_private.h"
+#include "mod_parrot.h"
+#include "httpd.h"
+#include "http_protocol.h"
+
+pmclass ModParrotHandle dynpmc need_ext group modparrot_group {
+ ATTR INTVAL flags; /* Filehandle flags */
+ ATTR STRING *mode; /* The mode string used in open */
+ ATTR STRING *encoding; /* The encoding for read/write */
+ ATTR STRING *filename; /* A mock path and filename */
+ ATTR INTVAL read_offset; /* Position, for reading bytes */
+ ATTR PMC *r; /* RequestRec object */
+
+/*
+
+=item C<void init()>
+
+Initializes a newly created ModParrotHandle object.
+
+=cut
+
+*/
+
+ VTABLE void init() {
+ Parrot_ModParrotHandle_attributes *data_struct =
+ mem_allocate_typed(Parrot_ModParrotHandle_attributes);
+
+ PMC_data(SELF) = data_struct;
+ data_struct->flags = 0;
+ data_struct->mode = NULL;
+ data_struct->encoding = NULL;
+ data_struct->filename = NULL;
+ data_struct->r = NULL;
+ data_struct->read_offset = 0;
+
+ PObj_custom_mark_SET(SELF);
+ PObj_active_destroy_SET(SELF);
+ }
+
+/*
+
+=item C<PMC *clone()>
+
+Create a copy of the handle.
+
+=cut
+
+*/
+
+ VTABLE PMC *clone() {
+ Parrot_ModParrotHandle_attributes * const old_struct = PARROT_MODPARROTHANDLE(SELF);
+ PMC * const copy = pmc_new(INTERP, SELF->vtable->base_type);
+ Parrot_ModParrotHandle_attributes * const data_struct = PARROT_MODPARROTHANDLE(copy);
+
+ data_struct->flags = old_struct->flags;
+ data_struct->mode = string_copy(INTERP, old_struct->mode);
+ data_struct->encoding = string_copy(INTERP, old_struct->encoding);
+ data_struct->r = old_struct->r;
+
+ return copy;
+ }
+
+/*
+
+=item C<void mark()>
+
+Mark active modparrothandle data as live.
+
+=cut
+
+*/
+
+ VTABLE void mark() {
+ Parrot_ModParrotHandle_attributes * const data_struct = PARROT_MODPARROTHANDLE(SELF);
+ if (data_struct->r)
+ pobject_lives(interp, (PObj *)data_struct->r);
+ if (data_struct->mode)
+ pobject_lives(interp, (PObj *)data_struct->mode);
+ if (data_struct->encoding)
+ pobject_lives(interp, (PObj *)data_struct->encoding);
+ if (data_struct->filename)
+ pobject_lives(interp, (PObj *)data_struct->filename);
+ }
+
+/*
+
+=item C<void destroy()>
+
+Free structures.
+
+=cut
+
+*/
+ VTABLE void destroy() {
+ if (PARROT_MODPARROTHANDLE(SELF)) {
+ mem_sys_free(PARROT_MODPARROTHANDLE(SELF));
+ PMC_data(SELF) = NULL;
+ }
+ }
+
+/*
+
+=item C<INTVAL get_bool()>
+
+XXX FIXME! -- always true for now
+Returns whether the handle has reached the end of the file.
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_bool() {
+ return 0;
+ }
+
+
+/*
+
+=back
+
+=head2 Methods
+
+=over 4
+
+=item C<METHOD open(PMC *r, STRING *mode :optional)>
+
+Opens a mod_parrot handle using the supplied request_rec with the given mode.
+
+=cut
+
+*/
+
+ METHOD open(PMC *r, STRING *mode :optional, INTVAL got_mode :opt_flag) {
+ STRING *open_mode, *attrname;
+ INTVAL flags;
+ PMC *attrpmc;
+
+ if (PMC_IS_NULL(r)) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Missing RequestRec in ModParrotHandle open");
+ }
+ SET_ATTR_r(INTERP, SELF, r);
+
+ if (got_mode && !STRING_IS_NULL(mode))
+ SET_ATTR_mode(INTERP, SELF, string_copy(INTERP, mode));
+
+ /* Set a default mode of read-write. */
+ GET_ATTR_mode(INTERP, SELF, open_mode);
+ if (STRING_IS_NULL(open_mode)) {
+ open_mode = const_string(INTERP, "r");
+ SET_ATTR_mode(INTERP, SELF, open_mode);
+ }
+
+ flags = Parrot_io_parse_open_flags(interp, open_mode);
+ SET_ATTR_flags(INTERP, SELF, flags);
+
+ RETURN(PMC *SELF);
+ }
+
+/*
+
+=item C<METHOD is_tty()>
+
+ModParrotHandles are never tty's, returns false.
+
+=cut
+
+*/
+ METHOD is_tty() {
+ RETURN(INTVAL 0);
+ }
+
+/*
+
+=item C<METHOD close()>
+
+Resets the request_rec and other core data.
+
+=cut
+
+*/
+
+ METHOD close() {
+ SET_ATTR_r(INTERP, SELF, NULL);
+ SET_ATTR_read_offset(INTERP, SELF, 0);
+ RETURN(INTVAL 0);
+ }
+
+/*
+
+=item C<METHOD is_closed()>
+
+Check if the handle is open.
+
+=cut
+
+*/
+
+ METHOD is_closed() {
+ request_rec *rr = NULL;
+ STRING *attrname = const_string(INTERP, "r");
+ PMC *attrpmc;
+ PMC *r;
+
+ GET_ATTR_r(INTERP, SELF, r)
+ if (r) {
+ attrname = const_string(INTERP, "r");
+ attrpmc = VTABLE_get_attr_str(INTERP, r, attrname);
+ rr = (request_rec *)PMC_data(attrpmc);
+ }
+
+ if (rr)
+ RETURN(INTVAL 1);
+
+ RETURN(INTVAL 0);
+ }
+
+/*
+
+=item C<METHOD read(INTVAL length)>
+
+Read C<length> bytes from the handle.
+
+=cut
+
+*/
+
+ METHOD read(INTVAL length) {
+ INTVAL flags, bytes, offset;
+ STRING *attrname, *str;
+ PMC *attrpmc, *r;
+ request_rec *rr = NULL;
+ char *buf;
+
+ GET_ATTR_r(INTERP, SELF, r);
+ if (!r)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Cannot read from a closed filehandle");
+
+ attrname = const_string(INTERP, "r");
+ attrpmc = VTABLE_get_attr_str(INTERP, r, attrname);
+ rr = (request_rec *)PMC_data(attrpmc);
+
+ GET_ATTR_flags(INTERP, SELF, flags);
+ if (!(flags & PIO_F_READ))
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Cannot read from a filehandle not opened for read");
+
+ buf = (char *)mem_sys_allocate(length);
+ bytes = modparrot_request_read(rr, buf, length);
+
+ if (bytes) {
+ GET_ATTR_read_offset(INTERP, SELF, offset);
+ SET_ATTR_read_offset(INTERP, SELF, offset + bytes);
+ str = string_from_cstring(INTERP, buf, bytes);
+ }
+ else {
+ /* XXX should be a null string */
+ str = string_from_literal(INTERP, "");
+ }
+
+ mem_sys_free(buf);
+
+ RETURN(STRING *str);
+ }
+
+/*
+
+=item C<METHOD readline()>
+
+TODO
+
+=cut
+
+*/
+
+/* readline code here */
+
+/*
+
+=item METHOD readall(STRING *name);
+
+TODO
+
+=cut
+
+*/
+
+/* readall code here */
+
+/*
+
+=item C<METHOD flush()>
+
+TODO
+
+=cut
+
+*/
+
+/* flush code here */
+
+/*
+
+=item C<METHOD print([INTVAL|FLOATVAL|STRING *|PMC*] value)>
+
+Print the passed in integer, number, string, or PMC to the handle.
+(Integers, numbers, and strings are auto-boxed as PMCs.)
+
+=cut
+
+*/
+
+ METHOD print(PMC *to_print) {
+ STRING *string_to_print = VTABLE_get_string(INTERP, to_print);
+ Parrot_io_putps(interp, SELF, string_to_print);
+ }
+
+/*
+
+=item C<METHOD puts(STRING *value)>
+
+Print the string to the handle.
+
+=cut
+
+*/
+
+ METHOD puts(STRING *to_print) {
+ INTVAL flags, status;
+ STRING *attrname;
+ PMC *attrpmc, *r;
+ request_rec *rr = NULL;
+ char *str;
+
+ GET_ATTR_r(INTERP, SELF, r);
+ if (!r)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Cannot write to a closed filehandle");
+
+ attrname = const_string(INTERP, "r");
+ attrpmc = VTABLE_get_attr_str(INTERP, r, attrname);
+ rr = (request_rec *)PMC_data(attrpmc);
+
+ GET_ATTR_flags(INTERP, SELF, flags);
+ if (!(flags & PIO_F_WRITE))
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+ "Cannot write to a filehandle not opened for write");
+
+ str = string_to_cstring(INTERP, to_print);
+ status = ap_rputs(str, rr);
+ string_cstring_free(str);
+
+ RETURN(INTVAL status);
+ }
+
+/*
+
+=item C<METHOD buffer_type(STRING *new_type :optional)>
+
+Set or retrieve the buffering attribute for the handle. This attribute is
+ignored, but stored for mocking.
+
+=cut
+
+*/
+
+ METHOD buffer_type(STRING *new_type :optional, INTVAL got_type :opt_flag) {
+ INTVAL flags;
+ STRING *nobuffer_string = const_string(INTERP, "unbuffered");
+ STRING *linebuffer_string = const_string(INTERP, "line-buffered");
+ STRING *fullbuffer_string = const_string(INTERP, "full-buffered");
+
+ GET_ATTR_flags(INTERP, SELF, flags);
+
+ if (got_type) {
+ if (string_equal(INTERP, new_type, nobuffer_string) == 0) {
+ flags &= ~ PIO_F_LINEBUF;
+ flags &= ~ PIO_F_BLKBUF;
+ }
+ else if (string_equal(INTERP, new_type, linebuffer_string) == 0) {
+ flags |= PIO_F_LINEBUF;
+ flags &= ~ PIO_F_BLKBUF;
+ }
+ else if (string_equal(INTERP, new_type, fullbuffer_string) == 0) {
+ flags &= ~ PIO_F_LINEBUF;
+ flags |= PIO_F_BLKBUF;
+ }
+
+ SET_ATTR_flags(INTERP, SELF, flags);
+ }
+
+ if (flags & PIO_F_LINEBUF)
+ RETURN(STRING *linebuffer_string);
+ else if (flags & PIO_F_BLKBUF)
+ RETURN(STRING *fullbuffer_string);
+ RETURN(STRING *nobuffer_string);
+ }
+
+/*
+
+=item C<METHOD buffer_size(INTVAL new_size :optional)>
+
+Always returns 0 for ModParrotHandle.
+
+=cut
+
+*/
+
+ METHOD buffer_size(INTVAL new_size :optional, INTVAL got_size :opt_flag) {
+ RETURN(INTVAL 0);
+
+ }
+
+/*
+
+=item C<METHOD mode()>
+
+Retrieve the read mode string for the handle.
+
+=cut
+
+*/
+
+ METHOD mode() {
+ STRING *mode, *mode_copy;
+
+ GET_ATTR_mode(INTERP, SELF, mode);
+ mode_copy = string_copy(INTERP, mode);
+
+ RETURN(STRING *mode_copy);
+
+ }
+
+/*
+
+=item C<METHOD encoding(STRING *new_encoding)>
+
+Set or retrieve the encoding attribute (a string name of the selected encoding
+scheme) for the handle.
+
+=cut
+
+*/
+
+ METHOD encoding(STRING *new_encoding :optional, INTVAL got_encoding :opt_flag) {
+ STRING *encoding;
+ STRING *encoding_copy = NULL;
+
+ if (got_encoding) {
+ if (!STRING_IS_NULL(new_encoding))
+ encoding_copy = string_copy(INTERP, new_encoding);
+ SET_ATTR_encoding(INTERP, SELF, encoding_copy);
+ RETURN(STRING *new_encoding);
+ }
+
+ GET_ATTR_encoding(INTERP, SELF, encoding);
+ if (!STRING_IS_NULL(encoding))
+ encoding_copy = string_copy(INTERP, encoding);
+
+ RETURN(STRING *encoding_copy);
+
+ }
+
+/*
+
+=item C<METHOD eof()>
+
+XXX TODO
+Check if the handle is at end-of-file (if it has read to the end of
+the string data).
+
+=cut
+
+*/
+
+ METHOD eof() {
+ RETURN(INTVAL 0);
+ }
+
+
+/*
+
+=item C<METHOD get_fd()>
+
+ModParrotHandles do not use integer file descriptors, so always returns an
+error value.
+
+=cut
+
+*/
+
+ METHOD get_fd() {
+ RETURN(INTVAL -1);
+ }
+
+
+/*
+
+=back
+
+=cut
+
+*/
+
+} /* end pmclass */
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */