/* {{{ ------- MEMORY stream implementation -------*/
typedef struct {
- char *data;
- size_t fpos;
- size_t fsize;
-} php_memory_stream_data;
+ char *data;
+ size_t fpos;
+ size_t fsize;
+ size_t smax;
+ php_stream *file;
+ int mode;
+} php_stream_temp_data;
-static size_t php_memory_stream_write(php_stream *stream, const char *buf, size_t count) {/* {{{ */
- php_memory_stream_data *ms;
+static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_t count STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
assert(stream != NULL);
ms = stream->abstract;
assert(ms != NULL);
+
+ if ( ms->mode & TEMP_STREAM_READONLY) {
+ return 0;
+ }
if ( ms->fpos + count > ms->fsize) {
char *tmp;
return count;
} /* }}} */
-static size_t php_memory_stream_read(php_stream *stream, char *buf, size_t count) {/* {{{ */
- php_memory_stream_data *ms;
+static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
assert(stream != NULL);
ms = stream->abstract;
count = ms->fsize - ms->fpos;
}
if ( count) {
+ assert(data!= NULL);
assert(buf!= NULL);
memcpy( buf, ms->data+ms->fpos, count);
ms->fpos += count;
} /* }}} */
-static int php_memory_stream_close(php_stream *stream, int close_handle) {/* {{{ */
- php_memory_stream_data *ms;
+static int php_stream_memory_close(php_stream *stream, int close_handle STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
assert(stream != NULL);
ms = stream->abstract;
assert(ms != NULL);
+
if (ms->data) {
efree(ms->data);
}
ms->data = NULL;
ms->fsize = 0;
ms->fpos = 0;
+ return 0;
} /* }}} */
-static int php_memory_stream_flush(php_stream *stream) {/* {{{ */
+static int php_stream_memory_flush(php_stream *stream STREAMS_DC) { /* {{{ */
// nothing to do here
return 0;
} /* }}} */
-static int php_memory_stream_seek(php_stream *stream, off_t offset, int whence) {/* {{{ */
- php_memory_stream_data *ms;
+static int php_stream_memory_seek(php_stream *stream, off_t offset, int whence STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
assert(stream != NULL);
ms = stream->abstract;
assert(ms != NULL);
+
if (offset == 0 && whence == SEEK_CUR)
return ms->fpos;
switch( whence) {
return 0;
default:
return 0;
- return /*EINVAL*/;
+ /*return EINVAL;*/
+ }
+} /* }}} */
+
+static char *php_stream_memory_gets(php_stream *stream, char *buf, size_t maxlen STREAMS_DC) { /* {{{ */
+ size_t n = 1;
+ char *c = buf;
+
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+ assert(buf!= NULL);
+ assert(ms->data!= NULL);
+
+ while(n < maxlen && ms->fpos<ms->fsize) {
+ n++;
+ if ( (*c = ms->data[ms->fpos++]) == '\n') {
+ c++;
+ break;
+ }
+ c++;
}
+ *c = 0;
+ return buf;
+} /* }}} */
+
+static int php_stream_memory_cast(php_stream *stream, int castas, void **ret STREAMS_DC) { /* {{{ */
+ return FAILURE;
} /* }}} */
php_stream_ops php_stream_memory_ops = {
- php_memory_stream_write, php_memory_stream_read,
- php_memory_stream_close, php_memory_stream_flush,
- php_memory_stream_seek,
- NULL,
- NULL,
+ php_stream_memory_write, php_stream_memory_read,
+ php_stream_memory_close, php_stream_memory_flush,
+ php_stream_memory_seek,
+ php_stream_memory_gets,
+ php_stream_memory_cast,
"MEMORY"
};
-PHPAPI php_stream *php_memory_stream_create() {/* {{{ */
- php_memory_stream_data *self;
+PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *self;
self = emalloc(sizeof(*self));
assert( self != NULL);
self->data = NULL;
self->fpos = 0;
self->fsize = 0;
- return php_stream_alloc(&php_stream_memory_ops, self, 0, "rwb");
+ self->smax = -1;
+ self->mode = mode;
+ return _php_stream_alloc(&php_stream_memory_ops, self, 0, "rwb" STREAMS_REL_CC);
+} /* }}} */
+
+/* }}} */
+
+PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length STREAMS_DC) { /* {{{ */
+ php_stream *stream;
+ php_stream_temp_data *ms;
+
+ if ( (stream = _php_stream_memory_create(mode STREAMS_REL_CC)) != NULL) {
+ if ( length) {
+ ms = stream->abstract;
+ ms->data = emalloc(length);
+ assert( buf != NULL);
+ memcpy(ms->data,buf,length);
+ }
+ ms->mode = mode;
+ }
+ return stream;
+} /* }}} */
+
+PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+ assert(length != 0);
+
+ *length = ms->fsize;
+ return ms->data;
+} /* }}} */
+
+/* {{{ ------- TEMP stream implementation -------*/
+
+static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t count STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+
+ if ( ms->mode & TEMP_STREAM_READONLY) {
+ return 0;
+ }
+ if ( !ms->file) {
+ size_t ret, fpos;
+ php_stream *file;
+
+ ret = php_stream_memory_write(stream,buf,count STREAMS_REL_CC);
+ if ( ms->fsize > ms->smax) {
+ fpos = ms->fpos;
+ ms->fpos = 0;
+ file = php_stream_fopen_tmpfile();
+ php_stream_copy_to_stream(stream, file, PHP_STREAM_COPY_ALL STREAMS_REL_CC);
+ php_stream_seek(file,fpos,SEEK_SET STREAMS_REL_CC);
+ ms->file = file;
+ ms->fsize = 0;
+ if ( ms->data) {
+ efree(ms->data);
+ }
+ ms->data = NULL;
+ }
+ return ret;
+ } else {
+ return php_stream_write(ms->file,buf,count STREAMS_REL_CC);
+ }
+} /* }}} */
+
+static size_t php_stream_temp_read(php_stream *stream, char *buf, size_t count STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+
+ if ( !ms->file) {
+ return php_stream_memory_read(stream,buf,count STREAMS_REL_CC);
+ } else {
+ return php_stream_read(ms->file,buf,count STREAMS_REL_CC);
+ }
+} /* }}} */
+
+
+static int php_stream_temp_close(php_stream *stream, int close_handle STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+
+ if ( !ms->file) {
+ return php_stream_memory_close(stream,close_handle STREAMS_REL_CC);
+ } else {
+ int ret = php_stream_close(ms->file STREAMS_REL_CC);
+ ms->file = NULL;
+ php_stream_memory_close(stream,close_handle STREAMS_REL_CC);
+ return ret;
+ }
+} /* }}} */
+
+
+static int php_stream_temp_flush(php_stream *stream STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+
+ if ( !ms->file) {
+ return php_stream_memory_flush(stream STREAMS_REL_CC);
+ } else {
+ return php_stream_flush(ms->file STREAMS_REL_CC);
+ }
+} /* }}} */
+
+
+static int php_stream_temp_seek(php_stream *stream, off_t offset, int whence STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+
+ if ( !ms->file) {
+ return php_stream_memory_seek(stream,offset,whence STREAMS_REL_CC);
+ } else {
+ return php_stream_seek(ms->file,offset,whence STREAMS_REL_CC);
+ }
+} /* }}} */
+
+char *php_stream_temp_gets(php_stream *stream, char *buf, size_t maxlen STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+
+ if ( !ms->file) {
+ return php_stream_memory_gets(stream,buf,maxlen STREAMS_REL_CC);
+ } else {
+ return php_stream_gets(ms->file,buf,maxlen STREAMS_REL_CC);
+ }
+} /* }}} */
+
+static int php_stream_temp_cast(php_stream *stream, int castas, void **ret STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+
+ if ( !ms->file) {
+ return php_stream_memory_cast(stream,castas,ret STREAMS_REL_CC);
+ } else {
+ return php_stream_cast(ms->file,castas,ret,0 STREAMS_REL_CC);
+ }
+} /* }}} */
+
+php_stream_ops php_stream_temp_ops = {
+ php_stream_temp_write, php_stream_temp_read,
+ php_stream_temp_close, php_stream_temp_flush,
+ php_stream_temp_seek,
+ php_stream_temp_gets,
+ php_stream_temp_cast,
+ "TEMP"
+};
+
+PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC) { /* {{{ */
+ php_stream_temp_data *self;
+ php_stream *stream;
+
+ self = emalloc(sizeof(*self));
+ assert( self != NULL);
+ self->data = NULL;
+ self->fpos = 0;
+ self->fsize = 0;
+ self->smax = max_memory_usage;
+ self->mode = mode;
+ if ( max_memory_usage)
+ self->file = NULL;
+ stream = _php_stream_alloc(&php_stream_temp_ops, self, 0, "rwb" STREAMS_REL_CC);
+ if ( !max_memory_usage)
+ php_stream_temp_write(stream,NULL,0 STREAMS_REL_CC);
+ return stream;
+} /* }}} */
+
+PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC) { /* {{{ */
+ php_stream *stream;
+ php_stream_temp_data *ms;
+
+ if ( (stream = _php_stream_temp_create(mode & ~TEMP_STREAM_READONLY, max_memory_usage STREAMS_REL_CC)) != NULL) {
+ if ( length) {
+ assert(buf != NULL);
+ php_stream_temp_write(stream,buf,length STREAMS_REL_CC);
+ }
+ ms = stream->abstract;
+ assert(ms != NULL);
+ ms->mode = mode;
+ }
+ return stream;
+} /* }}} */
+
+PHPAPI size_t _php_stream_temp_copy_buffer(php_stream *stream, char **buffer STREAMS_DC) { /* {{{ */
+ size_t fpos, size;
+ php_stream_temp_data *ms;
+
+ assert(stream != NULL);
+ ms = stream->abstract;
+ assert(ms != NULL);
+ assert(buffer != NULL);
+ assert(length != 0);
+
+ if ( !ms->file) {
+ *buffer = emalloc( ms->fsize);
+ if ( !*buffer) {
+ size = 0;
+ } else {
+ size = ms->fsize;
+ memcpy(*buffer,ms->data,size);
+ }
+ } else {
+ fpos = php_stream_tell(stream STREAMS_REL_CC);
+ php_stream_seek(stream,0,SEEK_END STREAMS_REL_CC);
+ size = php_stream_tell(stream STREAMS_REL_CC);
+ *buffer = emalloc( size);
+ if ( !*buffer) {
+ size = 0;
+ } else {
+ php_stream_seek(stream,0,SEEK_SET STREAMS_REL_CC);
+ size = php_stream_read(stream,*buffer,size STREAMS_REL_CC);
+ }
+ php_stream_seek(stream,fpos,SEEK_SET STREAMS_REL_CC);
+ }
+ return size;
} /* }}} */
/*