diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..9b1aeb1 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,5 @@ + +Version 0.4 2011/12/09 + - Coding style fix. + - Add unittest. + - Change qr_save api to make it flexible. diff --git a/README b/README index a9a83d2..9acffad 100644 --- a/README +++ b/README @@ -3,23 +3,25 @@ php qrencode is the wrapper of libqrencode to generate qr code. only 2 function to generate qr code. -$qr = qr_encode ('test for qrcode'); -if (is_resource ($qr)) - qr_save ($qr, '1.png'); +$qr = qr_encode('test for qrcode'); +if (is_resource($qr)) + qr_save($qr, '1.png'); or you can output direct to stdout. -$qr = qr_encode ('test for qrcode'); -if (is_resource ($qr)) -{ - header ("Content-type: image/PNG"); - qr_save ($qr); +$qr = qr_encode('test for qrcode'); +if (is_resource($qr)) { + header("Content-type: image/PNG"); + qr_save($qr); } -resource = qr_encode (string $text, [ int $version, int $mode, int $casesensitive]); +resource = qr_encode(string $text, [int $version, int $mode, int $casesensitive]); -bool = qr_save (resource $qr, [ string $filename] ); +bool = qr_save(resource $qr, string $filename); +bool = qr_save(resource $qr, string $filename, int size, int margin); +bool = qr_save(resource $qr, int size, int margin, string $filename); +bool = qr_save(resource $qr, int size, int margin); diff --git a/qrencode.c b/qrencode.c index 10e2670..6ccff41 100644 --- a/qrencode.c +++ b/qrencode.c @@ -143,24 +143,23 @@ PHP_FUNCTION(qr_encode) { * @return */ PHP_FUNCTION(qr_save) { - zval *link = NULL; + zval *link = NULL, *arg2 = NULL, *arg3 = NULL, *arg4 = NULL; long size = 3, margin = 4; - const char *fn = NULL; - int fn_len, argc; + int argc; FILE *fp = NULL; png_structp png_ptr; png_infop info_ptr; unsigned char *row, *p, *q; int x, y, xx, yy, bit; - int realwidth; + int realwidth, temp_file = 0; char *path; int b; char buf[4096]; argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|sll", - &link, &fn, &fn_len, &size, &margin) == FAILURE) + if (zend_parse_parameters(argc TSRMLS_CC, "r|zzz", + &link, &arg2, &arg3, &arg4) == FAILURE) RETURN_FALSE; if (link) { @@ -169,20 +168,85 @@ PHP_FUNCTION(qr_save) { ZEND_FETCH_RESOURCE2(qr, php_qrcode *, &link, -1, "qr handle", le_qr, NULL); - if ((argc == 2) || (argc > 2 && fn != NULL)) { - fp = VCWD_FOPEN(fn, "wb"); - if (!fp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Unable to open '%s' for writing.", fn); - RETURN_FALSE; - } - } else { - fp = php_open_temporary_file(NULL, NULL, &path TSRMLS_CC); - if (!fp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Unable to open temporary file for writing."); + switch (argc) { + case 4: + if (Z_TYPE_P(arg2) == IS_STRING) { + // qr_save(resource $link, string $fn, int $size, int $margin); + fp = VCWD_FOPEN(Z_STRVAL_P(arg2), "wb"); + if (!fp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Unable to open '%s' for writing.", + Z_STRVAL_P(arg2)); + RETURN_FALSE; + } + size = Z_LVAL_P(arg3); + margin = Z_LVAL_P(arg4); + } else if (Z_TYPE_P(arg2) == IS_LONG) { + // qr_save(resource $link, int $size, int $margin, string $fn); + size = Z_LVAL_P(arg2); + margin = Z_LVAL_P(arg3); + + fp = VCWD_FOPEN(Z_STRVAL_P(arg4), "wb"); + if (!fp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Unable to open '%s' for writing.", + Z_STRVAL_P(arg4)); + RETURN_FALSE; + } + } + break; + + case 3: + // qr_save(resource $link, int $size, int $margin); + if (Z_TYPE_P(arg2) != IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "should use type long as argument 2 when pass 3 arguments"); + RETURN_FALSE; + } + + fp = php_open_temporary_file(NULL, NULL, &path TSRMLS_CC); + if (!fp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Unable to open temporary file for writing."); + RETURN_FALSE; + } + + size = Z_LVAL_P(arg2); + margin = Z_LVAL_P(arg3); + temp_file = 1; + + break; + case 2: + if (Z_TYPE_P(arg2) == IS_STRING) { + fp = VCWD_FOPEN(Z_STRVAL_P(arg2), "wb"); + if (!fp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Unable to open '%s' for writing.", + Z_STRVAL_P(arg2)); + RETURN_FALSE; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "should use type string as argument 2"); + RETURN_FALSE; + } + break; + + case 1: + fp = php_open_temporary_file(NULL, NULL, &path TSRMLS_CC); + + if (!fp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Unable to open temporary file for writing."); + RETURN_FALSE; + } + temp_file = 1; + + break; + + case 0: + default: RETURN_FALSE; - } } realwidth = (qr->c->width + margin * 2) * size; @@ -257,10 +321,7 @@ PHP_FUNCTION(qr_save) { efree(row); - if ((argc == 2) || (argc > 2 && fn != NULL)) { - fflush(fp); - fclose(fp); - } else { + if (temp_file) { fseek(fp, 0, SEEK_SET); #if APACHE && defined(CHARSET_EBCDIC) ap_bsetflag(php3_rqst->connection->client, B_EBCDIC2ASCII, 0); @@ -271,6 +332,9 @@ PHP_FUNCTION(qr_save) { fclose(fp); VCWD_UNLINK((const char *)path); efree(path); + } else { + fflush(fp); + fclose(fp); } RETURN_TRUE; diff --git a/tests/qr_encode.phpt b/tests/qr_encode.phpt new file mode 100644 index 0000000..e40f459 --- /dev/null +++ b/tests/qr_encode.phpt @@ -0,0 +1,15 @@ +--TEST-- +qrencode: qr_encode test +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (qr) diff --git a/tests/qr_save.phpt b/tests/qr_save.phpt new file mode 100644 index 0000000..5cb0834 --- /dev/null +++ b/tests/qr_save.phpt @@ -0,0 +1,56 @@ +--TEST-- +qrencode: qr_encode test +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Warning: qr_save(): should use type string as argument 2 in %s on line %d + +Warning: qr_save(): should use type long as argument 2 when pass 3 arguments in %s on line %d +iVBORw0KGgoAAAANSUhEUgAAAFcAAABXAQAAAABZs+TBAAAAtElEQVQ4jc3TsQ3CMBAF0EMU6WABS7fGdVnJWSCGCVjJndeIxAJOl+KU40JBKKyfEq56xS++v2Sy/egvXIlSCUQMPJsmC8mgcxiKxu7Anj/0KEc2HUk/HZr2/sPXW5r2m8u+SdO1o1PxKZBXYcvPx8LAVjQt04WQ53K+yfm+GPAqOnheGNivdjr2yO8duAqy7xl7r2fIOcQ+RGHstO1g2FGma2Fk0yH7FAbs/bd8ZuBf/bW2XweNtloIoiLrAAAAAElFTkSuQmCC +iVBORw0KGgoAAAANSUhEUgAAAHwAAAB8AQAAAACDZekTAAAAmklEQVRIie3UMQ7FIAwDUN/A97+lb8CPw1/KhtOxCAnxhog4arGOhQ9eAAFYUh8x7L2PFIQq2ccIVr9sCMQMvMGj20uodHWmfglejvgx/UuoplwV/a4QKpxSkgs5yOUIIofKxrcqzRgWKU+bRA5+m+OhYvgPuzJCDu6PHVIO/gjZMY1gD5sjqDso5bD/BJ5UDg65iyKG5/pgDD+c+VFPQmXXuAAAAABJRU5ErkJggg== +PASS