[PHP-DEV] [PATCH] New function file_put_contents()

2002-11-22 Thread Christian Schneider
Ok, I try again to submit the patch and a test script for it :-)

Prototype:
int file_put_contents(string filename, mixed data [, string mode])

It takes a filename (URL wrappers supported), the data to be written and 
a mode for the file. The data can be either a string or an array (which 
is like using join(, $data) first and can be used to write data read 
by the file() function). The mode can be a or ab to append to a file 
and defaults to wb. The function returns the number of bytes written 
to the stream.

- Chris
Index: ext/standard/basic_functions.c
===
RCS file: /repository/php4/ext/standard/basic_functions.c,v
retrieving revision 1.528
diff -u -r1.528 basic_functions.c
--- ext/standard/basic_functions.c  6 Oct 2002 17:04:10 -   1.528
+++ ext/standard/basic_functions.c  16 Oct 2002 01:48:48 -
@@ -625,6 +625,7 @@
PHP_STATIC_FE(tmpfile,php_if_tmpfile,
 NULL)
PHP_FE(file,   
 NULL)
PHP_FE(file_get_contents,  
 NULL)
+   PHP_FE(file_put_contents,  
+ NULL)
PHP_FE(stream_select, 
first_through_third_args_force_ref)
PHP_FE(stream_context_create,  
 NULL)
PHP_FE(stream_context_set_params,  
 NULL)
Index: ext/standard/file.c
===
RCS file: /repository/php4/ext/standard/file.c,v
retrieving revision 1.270
diff -u -r1.270 file.c
--- ext/standard/file.c 15 Oct 2002 16:45:26 -  1.270
+++ ext/standard/file.c 16 Oct 2002 01:48:49 -
@@ -452,6 +452,79 @@
 }
 /* }}} */
 
+/* {{{ proto int file_put_contents(string filename, mixed data [, string mode])
+   Write an entire string or array to a file and return length written */
+PHP_FUNCTION(file_put_contents)
+{
+   size_t ret = 0;
+   char *filename;
+   int filename_len;
+   char *data = NULL;
+   int data_len;
+   zval *arr = NULL;
+   char *mode = wb;
+   int mode_len;
+   HashPosition pos;
+   zval **tmp = NULL;
+   php_stream *stream;
+
+   /* Parse arguments */
+   if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() 
+TSRMLS_CC, ss|s,
+ filename, 
+filename_len, data, data_len, mode, mode_len) == FAILURE) 
+   (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, sa|s,
+   filename, filename_len, arr, mode, mode_len) == 
+FAILURE)) {
+   return;
+   }
+
+   stream = php_stream_open_wrapper(filename, mode,
+   ENFORCE_SAFE_MODE | REPORT_ERRORS,
+   NULL);
+   if (!stream) {
+   RETURN_FALSE;
+   }
+
+   if (arr) {
+   zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), pos);
+
+   if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)tmp, 
+pos) == SUCCESS) {
+   convert_to_string_ex(tmp);
+   data = Z_STRVAL_PP(tmp);
+   data_len = Z_STRLEN_PP(tmp);
+   }
+   }
+
+   while (data) {
+   char *buffer = NULL;
+
+   if (PG(magic_quotes_runtime)) {
+   buffer = estrndup(data, data_len);
+   php_stripslashes(buffer, data_len TSRMLS_CC);
+   }
+
+   ret += php_stream_write(stream, buffer ? buffer : data, data_len);
+   if (buffer) {
+   efree(buffer);
+   }
+
+   data = NULL;
+
+   if (arr) {
+   zend_hash_move_forward_ex(Z_ARRVAL_P(arr), pos);
+
+   if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void 
+**)tmp, pos) == SUCCESS) {
+   convert_to_string_ex(tmp);
+   data = Z_STRVAL_PP(tmp);
+   data_len = Z_STRLEN_PP(tmp);
+   }
+   }
+   }
+
+   php_stream_close(stream);
+
+   RETURN_LONG(ret);
+}
+/* }}} */
+
 /* {{{ proto array file(string filename [, bool use_include_path])
Read entire file into an array */
 
Index: ext/standard/file.h
===
RCS file: /repository/php4/ext/standard/file.h,v
retrieving revision 1.70
diff -u -r1.70 file.h
--- ext/standard/file.h 28 Sep 2002 

[PHP-DEV] [PATCH] New function file_put_contents()

2002-10-15 Thread Christian Schneider

Wez Furlong wrote:
 It's just that there was a thread about this recently on php-dev,
 and it's something to get right for new functions - we can fix the
 old ones as we go :-)

The README, the Zend API doc on zend.com and the implementation in 
zend_API.c all assume an int * for string length in 
zend_parse_parameters. So I guess that's the right thing to do for now.

 Please re-submit the fixed version, and I'll probably commit it :-)

Ok, I attached the new patch:
a) renamed to file_put_contents (can I file minority report? :-))
b) now returns total length written if data is an array
c) return value was changed to size_t to match php_stream_write()

- Chris


? ext/standard/file_put.c
Index: ext/standard/basic_functions.c
===
RCS file: /repository/php4/ext/standard/basic_functions.c,v
retrieving revision 1.528
diff -u -r1.528 basic_functions.c
--- ext/standard/basic_functions.c  6 Oct 2002 17:04:10 -   1.528
+++ ext/standard/basic_functions.c  16 Oct 2002 01:48:48 -
 -625,6 +625,7 
PHP_STATIC_FE(tmpfile,php_if_tmpfile,
 NULL)
PHP_FE(file,   
 NULL)
PHP_FE(file_get_contents,  
 NULL)
+   PHP_FE(file_put_contents,  
+ NULL)
PHP_FE(stream_select, 
first_through_third_args_force_ref)
PHP_FE(stream_context_create,  
 NULL)
PHP_FE(stream_context_set_params,  
 NULL)
Index: ext/standard/file.c
===
RCS file: /repository/php4/ext/standard/file.c,v
retrieving revision 1.270
diff -u -r1.270 file.c
--- ext/standard/file.c 15 Oct 2002 16:45:26 -  1.270
+++ ext/standard/file.c 16 Oct 2002 01:48:49 -
 -452,6 +452,79 
 }
 /* }}} */
 
+/* {{{ proto int file_put_contents(string filename, mixed data [, string mode])
+   Write an entire string or array to a file and return length written */
+PHP_FUNCTION(file_put_contents)
+{
+   size_t ret = 0;
+   char *filename;
+   int filename_len;
+   char *data = NULL;
+   int data_len;
+   zval *arr = NULL;
+   char *mode = wb;
+   int mode_len;
+   HashPosition pos;
+   zval **tmp = NULL;
+   php_stream *stream;
+
+   /* Parse arguments */
+   if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() 
+TSRMLS_CC, ss|s,
+ filename, 
+filename_len, data, data_len, mode, mode_len) == FAILURE) 
+   (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, sa|s,
+   filename, filename_len, arr, mode, mode_len) == 
+FAILURE)) {
+   return;
+   }
+
+   stream = php_stream_open_wrapper(filename, mode,
+   ENFORCE_SAFE_MODE | REPORT_ERRORS,
+   NULL);
+   if (!stream) {
+   RETURN_FALSE;
+   }
+
+   if (arr) {
+   zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), pos);
+
+   if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)tmp, 
+pos) == SUCCESS) {
+   convert_to_string_ex(tmp);
+   data = Z_STRVAL_PP(tmp);
+   data_len = Z_STRLEN_PP(tmp);
+   }
+   }
+
+   while (data) {
+   char *buffer = NULL;
+
+   if (PG(magic_quotes_runtime)) {
+   buffer = estrndup(data, data_len);
+   php_stripslashes(buffer, data_len TSRMLS_CC);
+   }
+
+   ret += php_stream_write(stream, buffer ? buffer : data, data_len);
+   if (buffer) {
+   efree(buffer);
+   }
+
+   data = NULL;
+
+   if (arr) {
+   zend_hash_move_forward_ex(Z_ARRVAL_P(arr), pos);
+
+   if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void 
+**)tmp, pos) == SUCCESS) {
+   convert_to_string_ex(tmp);
+   data = Z_STRVAL_PP(tmp);
+   data_len = Z_STRLEN_PP(tmp);
+   }
+   }
+   }
+
+   php_stream_close(stream);
+
+   RETURN_LONG(ret);
+}
+/* }}} */
+
 /* {{{ proto array file(string filename [, bool use_include_path])
Read entire file into an array */
 
Index: ext/standard/file.h