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