* @ingroup SPL
* @brief class FileObject
* @author Marcus Boerger
- * @date 2003 - 2005
+ * @date 2003 - 2006
*
* SPL - Standard PHP Library
*/
/** @ingroup SPL
* @brief Object representation for any stream
* @author Marcus Boerger
- * @version 1.0
+ * @version 1.1
* @since PHP 5.1
*/
-class SplFileObject implements RecursiveIterator, SeekableIterator
+class SplFileObject extends SplFileInfo implements RecursiveIterator, SeekableIterator
{
/** Flag: wheter to suppress new lines */
const DROP_NEW_LINE = 0x00000001;
private $lnum = 0;
private $max_len = 0;
private $flags = 0;
+ private $delimiter= ',';
+ private $enclosure= '"';
/**
* Constructs a new file object
* @param enclosure end of
* @return array containing read data
*/
- function fgetcsv($delimiter = ';', $enclosure = '')
+ function fgetcsv($delimiter = NULL, $enclosure = NULL)
{
$this->freeLine();
$this->lnum++;
+ switch(fun_num_args())
+ {
+ case 0:
+ $delimiter = $this->delimiter;
+ case 1:
+ $enclosure = $this->enclosure;
+ default:
+ case 2:
+ break;
+ }
return fgetcsv($this->fp, $this->max_len, $delimiter, $enclosure);
}
+ /**
+ * Set the delimiter and enclosure character used in fgetcsv
+ *
+ * @param delimiter new delimiter, defaults to ','
+ * @param enclosure new enclosure, defaults to '"'
+ */
+ function setCsvControl($delimiter = ';', $enclosure = '"')
+ {
+ $this->delimiter = $delimiter;
+ $this->enclosure = $enclosure;
+ }
+
+ /**
+ * @return array(delimiter, enclosure) as used in fgetcsv
+ */
+ function getCsvControl($delimiter = ',', $enclosure = '"')
+ {
+ return array($this->delimiter, $this->enclosure);
+ }
+
/**
* @param operation lock operation (LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB)
* @retval $wouldblock whether the operation would block
/* avoid reference counting in debug mode, thus do it manually */
ZVAL_RESOURCE(&intern->u.file.zresource, php_stream_get_resource_id(intern->u.file.stream));
intern->u.file.zresource.refcount = 1;
+
+ intern->u.file.delimiter = ',';
+ intern->u.file.enclosure = '"';
zend_hash_find(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline"), (void **) &intern->u.file.func_getCurr);
spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2 TSRMLS_CC); \
}
-static void spl_filesystem_file_read_csv(zval * this_ptr, spl_filesystem_object *intern, int pass_num_args, zval *return_value TSRMLS_DC) /* {{{ */
+static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, zval *return_value TSRMLS_DC) /* {{{ */
{
- zval *arg2 = NULL;
- MAKE_STD_ZVAL(arg2);
- ZVAL_LONG(arg2, intern->u.file.max_line_len);
-
- spl_filesystem_file_free_line(intern TSRMLS_CC);
-
- FileFunctionCall(fgetcsv, pass_num_args, arg2);
+ int ret = SUCCESS;
+
+ do {
+ ret = spl_filesystem_file_read(intern, 1 TSRMLS_CC);
+ } while (ret == SUCCESS && !intern->u.file.current_line_len && (intern->flags & SPL_FILE_OBJECT_SKIP_EMPTY));
+
+ if (ret == SUCCESS) {
+ size_t buf_len = intern->u.file.current_line_len;
+ char *buf = estrndup(intern->u.file.current_line, buf_len);
- zval_ptr_dtor(&arg2);
+ if (Z_TYPE_P(return_value) != IS_NULL) {
+ zval_dtor(return_value);
+ ZVAL_NULL(return_value);
+ }
+ php_fgetcsv(intern->u.file.stream, delimiter, enclosure, buf_len, buf, return_value TSRMLS_CC);
+ }
+ return ret;
}
/* }}} */
}
if (intern->flags & SPL_FILE_OBJECT_READ_CSV) {
MAKE_STD_ZVAL(retval);
- spl_filesystem_file_read_csv(this_ptr, intern, 0, retval TSRMLS_CC);
+ return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, retval TSRMLS_CC);
} else {
zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
}
SPL_METHOD(SplFileObject, fgetcsv)
{
spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure;
+ char *delim, *enclo;
+ int d_len, e_len;
- spl_filesystem_file_read_csv(getThis(), intern, ZEND_NUM_ARGS(), return_value TSRMLS_CC);
- intern->u.file.current_line_num++;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, &d_len, &enclo, &e_len) == SUCCESS) {
+ switch(ZEND_NUM_ARGS())
+ {
+ case 2:
+ if (e_len != 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
+ RETURN_FALSE;
+ }
+ enclosure = enclo[0];
+ /* no break */
+ case 1:
+ if (d_len != 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
+ RETURN_FALSE;
+ }
+ delimiter = delim[0];
+ /* no break */
+ case 0:
+ break;
+ }
+ spl_filesystem_file_read_csv(intern, delimiter, enclosure, return_value TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"']])
+ Set the delimiter and enclosure character used in fgetcsv */
+SPL_METHOD(SplFileObject, setCsvControl)
+{
+ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ char delimiter = ',', enclosure = '"';
+ char *delim, *enclo;
+ int d_len, e_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, &d_len, &enclo, &e_len) == SUCCESS) {
+ switch(ZEND_NUM_ARGS())
+ {
+ case 2:
+ if (e_len != 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
+ RETURN_FALSE;
+ }
+ enclosure = enclo[0];
+ /* no break */
+ case 1:
+ if (d_len != 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
+ RETURN_FALSE;
+ }
+ delimiter = delim[0];
+ /* no break */
+ case 0:
+ break;
+ }
+ intern->u.file.delimiter = delimiter;
+ intern->u.file.enclosure = enclosure;
+ }
+}
+/* }}} */
+
+/* {{{ proto array SplFileObject::getCsvControl()
+ Get the delimiter and enclosure character used in fgetcsv */
+SPL_METHOD(SplFileObject, getCsvControl)
+{
+ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ char delimiter[2], enclosure[2];
+
+ array_init(return_value);
+
+ delimiter[0] = intern->u.file.delimiter;
+ delimiter[1] = '\0';
+ enclosure[0] = intern->u.file.enclosure;
+ enclosure[1] = '\0';
+
+ add_next_index_string(return_value, delimiter, 1);
+ add_next_index_string(return_value, enclosure, 1);
}
/* }}} */
SPL_ME(SplFileObject, valid, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, fgets, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, fgetcsv, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFileObject, setCsvControl, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFileObject, getCsvControl, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, flock, arginfo_file_object_flock, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, fflush, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, ftell, NULL, ZEND_ACC_PUBLIC)
Get line from file pointer and parse for CSV fields */
PHP_FUNCTION(fgetcsv)
{
- char *temp, *tptr, *bptr, *line_end, *limit;
char delimiter = ','; /* allow this to be set as parameter */
char enclosure = '"'; /* allow this to be set as parameter */
- const char escape_char = '\\';
/* first section exactly as php_fgetss */
long len = 0;
- size_t buf_len, temp_len, line_end_len;
+ size_t buf_len;
char *buf;
php_stream *stream;
- int inc_len;
{
zval *fd, **len_zv = NULL;
RETURN_FALSE;
}
}
+
+ php_fgetcsv(stream, delimiter, enclosure, buf_len, buf, return_value TSRMLS_CC);
+}
+/* }}} */
+
+
+PHPAPI void php_fgetcsv(php_stream *stream, /* {{{ */
+ char delimiter, char enclosure,
+ size_t buf_len, char *buf,
+ zval *return_value TSRMLS_DC)
+{
+ char *temp, *tptr, *bptr, *line_end, *limit;
+ const char escape_char = '\\';
+
+ size_t temp_len, line_end_len;
+ int inc_len;
+
/* initialize internal state */
php_mblen(NULL, 0);