My first patch: AMFEXT

[email protected] ("J. Adams")
Newsgroups php.pecl.dev
Message-ID <[email protected]>
I know this is hardly much of a fix, but since it compiles on windows 
and OSX, I am submitting my first patch for AMFEXT.  I have successfully 
compiled it on my Win XP desktop using SDK 6.1 and 32-bit compilers and 
I have also compiled it successfully on OSX 10.5.  It reflects some 
changes I've made as well as some contributions [which I don't fully 
understand] from a guy named Mikko on irc:#php.pecl.  I have attached an 
svn diff patch to this email.

The changes include the following
1) Changed references to ZVAL_ADDREF, ZVAL_DELREF, and ZVAL_REFCOUNT to 
Z_ADDREF, Z_DELREF and Z_REFCOUNT, respectively per Gustavo Lopes' 
sagacious instruction.  Added conditional declarations of the new macros 
per Michael Maclean's generous suggestion. This is what permits 
compilation in my WinXP environment.
2) Added REGISTER_LONG_CONSTANT declarations to PHP_MINIT_FUNCTION so 
that these flag constants are available within PHP.  I reckon there 
should be more added but am not sure which yet.
3) Changes made by Mikko to remove reference to zend_get_parameters_ex 
in favor of zend_parse_parameters.  There are still 6 instances of the 
older funtion which I'd like to work on but I'll need some time to 
understand exactly what's going on in the code.
4) Re-ordering of code so that constant declarations precede MINIT 
function in which they are used.

I hope this helps and that it might demonstrate my sincere desire to 
improve amfext.  Maybe I could get a pecl account now?

In the meantime, I desperately want to know how I might set up some kind 
of debugging situation whereby I might be privy to the inner workings of 
this code as it runs.  Is there some way to enable traces from the code? 
Is there some IDE setup whereby I can set breakpoints, trace code, and 
inspect variable contents?  I have a little function that accepts 
printf-type parameters and writes this to a log file, but that hardly 
seems efficient.  Per Emanuele's suggestion, I've also tried the exact 
steps listed here:
http://blog.slickedit.com/2007/09/creating-a-php-5-extension-with-visual-c-2005/
But a build results in 100 'already defined' errors.


Thanks to Gustavo, Michael, and Pierre (and E. Smart on irc) for assistance.
amf.patch (text/plain, 9.6 KB)
Index: amf.c
===================================================================
--- amf.c	(revision 301672)
+++ amf.c	(working copy)
@@ -20,11 +20,36 @@
 #endif
 
 #include "php.h"
+#include "zend_constants.h"
 #include "ext/standard/php_string.h"
 #include "ext/standard/php_var.h"
 #include "ext/standard/php_smart_str.h"
 #include "ext/standard/basic_functions.h"
 #include "ext/standard/php_incomplete_class.h"
+
+/* The following compatibility declarations thanks to
+   Michael Maclean of pecl/cairo */
+/* 5.2 is stupid and needs some additional stuff */
+#ifndef zend_parse_parameters_none
+#define zend_parse_parameters_none()										\
+	zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")
+#endif
+
+/* refcount macros */
+#ifndef Z_ADDREF_P
+#define Z_ADDREF_P(pz)                (pz)->refcount++
+#endif
+
+#ifndef Z_DELREF_P
+#define Z_DELREF_P(pz)                (pz)->refcount--
+#endif
+
+#ifndef Z_SET_REFCOUNT_P
+#define Z_SET_REFCOUNT_P(pz, rc)      (pz)->refcount = rc
+#endif
+/* end compatibility stuff */
+
+
 #include "php_amf.h"
 #include "php_memory_streams.h"
 #include "ext/standard/info.h"
@@ -63,34 +88,6 @@
 static void php_amf_sb_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
 int amf_serialize_output_resource_reg;
 
-PHP_MINIT_FUNCTION(amf)
-{
-	amf_serialize_output_resource_reg = zend_register_list_destructors_ex(php_amf_sb_dtor, NULL, PHP_AMF_STRING_BUILDER_RES_NAME, module_number);
-	return SUCCESS;
-}
-
-zend_module_entry amf_module_entry = {
-#if ZEND_MODULE_API_NO >= 20010901
-    STANDARD_MODULE_HEADER,
-#endif
-    PHP_AMF_WORLD_EXTNAME,
-    amf_functions,
-    PHP_MINIT(amf),
-    NULL,
-    NULL,
-    NULL,
-    PHP_MINFO(amf),
-#if ZEND_MODULE_API_NO >= 20010901
-    PHP_AMF_VERSION,
-#endif
-    STANDARD_MODULE_PROPERTIES
-};
-
-#ifdef COMPILE_DL_AMF
-ZEND_GET_MODULE(amf)
-#endif
-
-
 /*  AMF enumeration {{{1*/
 
 /**  AMF0 types */
@@ -103,7 +100,7 @@
 enum AMFCallbackResult { AMFC_RAW, AMFC_XML, AMFC_OBJECT, AMFC_TYPEDOBJECT, AMFC_ANY, AMFC_ARRAY,AMFC_NONE,AMFC_BYTEARRAY,AMFC_EXTERNAL};
 
 /**  flags passed to amf_encode and amf_decode */
-enum AMFFlags { AMF_AMF3 = 1, AMF_BIGENDIAN=2,AMF_ASSOC=4,AMF_POST_DECODE = 8,AMF_AS_STRING_BUILDER = 16, AMF_TRANSLATE_CHARSET = 32,AMF_TRANSLATE_CHARSET_FAST = 32|64};
+enum AMFFlags { AMF_AMF3 = 1<<0, AMF_BIGENDIAN = 1<<1, AMF_ASSOC = 1<<2, AMF_POST_DECODE = 1<<3, AMF_AS_STRING_BUILDER = 1<<4, AMF_TRANSLATE_CHARSET = 1<<5, AMF_TRANSLATE_CHARSET_FAST = (1<<5)|(1<<6) };
 
 /**  events invoked by the callback */
 enum AMFEvent { AMFE_MAP = 1, AMFE_POST_OBJECT, AMFE_POST_XML, AMFE_MAP_EXTERNALIZABLE,AMFE_POST_BYTEARRAY,AMFE_TRANSLATE_CHARSET};
@@ -124,6 +121,48 @@
 
 enum AMFStringTranslate { AMF_TO_UTF8, AMF_FROM_UTF8};
 
+
+
+
+PHP_MINIT_FUNCTION(amf)
+{
+
+	/** declare encode/decode flags as php constants */
+	REGISTER_LONG_CONSTANT("AMF_AMF3", AMF_AMF3, CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("AMF_BIGENDIAN", AMF_BIGENDIAN, CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("AMF_ASSOC", AMF_ASSOC, CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("AMF_POST_DECODE", AMF_POST_DECODE, CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("AMF_AS_STRING_BUILDER", AMF_AS_STRING_BUILDER, CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("AMF_TRANSLATE_CHARSET", AMF_TRANSLATE_CHARSET, CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("AMF_TRANSLATE_CHARSET_FAST", AMF_TRANSLATE_CHARSET_FAST, CONST_CS | CONST_PERSISTENT);
+
+	amf_serialize_output_resource_reg = zend_register_list_destructors_ex(php_amf_sb_dtor, NULL, PHP_AMF_STRING_BUILDER_RES_NAME, module_number);
+	return SUCCESS;
+}
+
+zend_module_entry amf_module_entry = {
+#if ZEND_MODULE_API_NO >= 20010901
+    STANDARD_MODULE_HEADER,
+#endif
+    PHP_AMF_WORLD_EXTNAME,
+    amf_functions,
+    PHP_MINIT(amf),
+    NULL,
+    NULL,
+    NULL,
+    PHP_MINFO(amf),
+#if ZEND_MODULE_API_NO >= 20010901
+    PHP_AMF_VERSION,
+#endif
+    STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_AMF
+ZEND_GET_MODULE(amf)
+#endif
+
+
+
 /*  Memory Management {{{1*/
 
 /**  deallocates a zval during unserialization of string */
@@ -425,14 +464,14 @@
 			amf_string_chunk * chunk = (amf_string_chunk*)cur->data;
 			while(chunk->size != 0)
 			{
-	#ifndef amf_NO_ZVAL_STRING_BUILDER
+#ifndef amf_NO_ZVAL_STRING_BUILDER
 				if((chunk->size & 1) != 0)
 				{
 					amf_write_zstring(buf, chunk->zv);
 					chunk++;
 				}
 				else
-	#endif
+#endif
 				{
 					int len = chunk->size >> 1;
 					amf_write_string(buf, chunk->data,len);
@@ -557,9 +596,9 @@
 /**  initializes a zval to a HashTable of zval with a possible number of items */
 static int amf_array_init(zval *arg, int count TSRMLS_DC)
 {
-	ALLOC_HASHTABLE_REL(arg->value.ht);
+	ALLOC_HASHTABLE(arg->value.ht);
 
-	zend_hash_init(arg->value.ht, count, NULL, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
+	zend_hash_init(arg->value.ht, count, NULL, ZVAL_PTR_DTOR, 0);
 	arg->type = IS_ARRAY;
 	return SUCCESS;
 }
@@ -844,7 +883,7 @@
 
 		buf->last_chunk->size = 1;  /*  zval chun */
 		buf->last_chunk->zv = zstr;
-		ZVAL_ADDREF(zstr);
+		Z_ADDREF(zstr);
 		buf->chunks++;
 		buf->left_in_part -= sizeof(amf_string_chunk);
 
@@ -1185,7 +1224,7 @@
 		int resultType = AMFC_TYPEDOBJECT;
 		int resultValueLength = 0;
 		zval** resultValue = struc;
-		int deallocResult = ZVAL_REFCOUNT(*struc);
+		int deallocResult = Z_REFCOUNT(*struc);
 
 		resultType = amf_perform_serialize_callback(struc, &className,&classNameLen,&resultValue,var_hash TSRMLS_CC);
 		
@@ -2313,9 +2352,8 @@
 */
 PHP_FUNCTION(amf_join_test)
 {
-	int i;
-	int argc = ZEND_NUM_ARGS();
-	zval **params[10];
+	int argc;
+	zval ***params, *arr;
 #ifdef amf_USE_STRING_BUILDER
 	amf_serialize_output_t buf;
 	amf_serialize_output pbuf = &buf;
@@ -2323,18 +2361,18 @@
 #else
 	amf_serialize_output pbuf = php_stream_memory_create(0);
 #endif
-	if(argc > sizeof(params)/sizeof(params[0]))
-	{
-		argc = sizeof(params)/sizeof(params[0]);
-	}
 
-	if(zend_get_parameters_ex(argc, &params[0],&params[1],&params[2],&params[3],&params[4],
-		&params[5],&params[6],&params[7],&params[8],&params[9]) == FAILURE)
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == SUCCESS) {
+		_amf_sb_append(pbuf, arr, 1 TSRMLS_CC);
+	} else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &params, &argc) == SUCCESS) {
+		int i;	
+		for (i = 0; i < argc; i++) {
+			_amf_sb_append(pbuf, *params[i], 1 TSRMLS_CC);
+		}
+	} else {
 		return;
+	}
 
-	for(i = 0; i < argc; i++)
-		_amf_sb_append(pbuf, *params[i],1 TSRMLS_CC);
-
 #ifdef amf_USE_STRING_BUILDER
 	amf_serialize_output_get(pbuf, return_value);
 	amf_serialize_output_dtor(pbuf);
@@ -2368,24 +2406,10 @@
 	amf_serialize_output pbuf = php_stream_memory_create(0);
 #endif
 
-	switch(ZEND_NUM_ARGS())
-	{
-	case 0: WRONG_PARAM_COUNT; return;
-	case 1:
-		if(zend_get_parameters_ex(1, &struc) == FAILURE)
-		{
-			WRONG_PARAM_COUNT
-		}
-		break;
-	default:
-		 /*  min(ZEND_NUM_ARGS(),4 */
-		if(zend_get_parameters_ex(ZEND_NUM_ARGS() > 4 ? 4 : ZEND_NUM_ARGS(), &struc,&strucFlags,&zzCallback,&zzOutputSB) == FAILURE || Z_TYPE_PP(strucFlags) != IS_LONG)
-		{
-			WRONG_PARAM_COUNT
-		}
-		flags = Z_LVAL_PP(strucFlags);
-		break;
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zzz", &struc, &strucFlags, &zzCallback, &zzOutputSB) == FAILURE) {
+		return;
 	}
+
 #ifdef amf_USE_STRING_BUILDER
 
 	 /*  if we explicitly pass a SB use i */
@@ -2397,7 +2421,7 @@
 		{
 			pbuf = tpbuf;
 			asSB = 1;
-			 /* ZVAL_ADDREF(*zzOutputSB) */
+			 /* Z_ADDREF(*zzOutputSB) */
 			 /* return_value = *zzOutputSB */
 		}
 	}
@@ -2675,7 +2699,7 @@
 		}
 		else
 		{
-			ZVAL_DELREF(newval);
+			Z_DELREF(newval);
 		}
 		*rval = newval;
 	}
@@ -2735,11 +2759,11 @@
 			 /*  build the corresponding clas */
 			zend_class_entry ** classEntry;
 
-	#if PHP_MAJOR_VERSION >= 5
+#if PHP_MAJOR_VERSION >= 5
 			if (zend_lookup_class(Z_STRVAL_P(zClassname), Z_STRLEN_P(zClassname),  &classEntry TSRMLS_CC) != SUCCESS) {
-	#else
+#else
 			if(zend_hash_find(EG(class_table), Z_STRVAL_P(zClassname), Z_STRLEN_P(zClassname), (void **) &classEntry) != SUCCESS) {
-	#endif
+#endif
 				php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf cannot find class %s\n",Z_STRVAL_P(zClassname));
 				object_init(*rval);
 				 /* return FAILURE */
@@ -2829,7 +2853,7 @@
 	{
 		if(zClassname != NULL)
 		{
-			ZVAL_ADDREF(zClassname);
+			Z_ADDREF(zClassname);
 			add_assoc_zval(*rval, "_explicitType",zClassname);
 		}
 	}
@@ -3050,7 +3074,7 @@
 				MAKE_STD_ZVAL(zClassDef);
 				amf_array_init(zClassDef,nClassMemberCount+2 TSRMLS_CC); 
 				add_next_index_long(zClassDef,(bTypedObject?1:0)|nClassMemberCount << AMF_CLASS_MEMBERCOUNT_SHIFT |iDynamicObject|iExternalizable);
-				ZVAL_ADDREF(zClassname);
+				Z_ADDREF(zClassname);
 				add_next_index_zval(zClassDef, zClassname); 
 		
 				 /*  loop over classMemberCoun */
@@ -3061,7 +3085,7 @@
 					{
 						break;
 					}
-					ZVAL_ADDREF(zMemberName);
+					Z_ADDREF(zMemberName);
 					add_next_index_zval(zClassDef,zMemberName);  /*  pass referenc */
 				}
 
@@ -3121,11 +3145,11 @@
 						{
 							zend_class_entry **classEntry;
 
-			#if PHP_MAJOR_VERSION >= 5
+#if PHP_MAJOR_VERSION >= 5
 							if (zend_lookup_class(Z_STRVAL_P(zClassname), Z_STRLEN_P(zClassname),  &classEntry TSRMLS_CC) != SUCCESS) {
-			#else
+#else
 							if(zend_hash_find(EG(class_table), Z_STRVAL_P(zClassname), Z_STRLEN_P(zClassname), (void **) &classEntry) != SUCCESS) {
-			#endif
+#endif
 								php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf cannot find class entry %s", Z_STRVAL_P(zClassname));
 								object_init(*rval);
 							}
@@ -3206,7 +3230,7 @@
 				{
 					if(bTypedObject != 0)
 					{
-						ZVAL_ADDREF(zClassname);
+						Z_ADDREF(zClassname);
 						add_assoc_zval(*rval, "_explicitType",zClassname);
 					}
 				}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.