/* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2001 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: David Eriksson | +----------------------------------------------------------------------+ */ /* * $Id$ * vim: syntax=c tabstop=2 shiftwidth=2 */ /* ----------------------------------------------------------------------- * * Functions to convert a zval to a CORBA_NamedValue * * ----------------------------------------------------------------------- */ #include #include "zval_to_namedvalue.h" #include "object.h" #include "struct.h" #include "common.h" #include "corba.h" #include /* for ALIGN_ADDRESS() */ /* * value should be a CORBA_boolean * */ static zend_bool satellite_zval_to_namedvalue_boolean(const zval * pSource, CORBA_NamedValue * pDestination) { CORBA_boolean * p_value = (CORBA_boolean *)pDestination->argument._value; pDestination->len = sizeof(CORBA_boolean); if (pSource == NULL) return TRUE; if (pSource->type != IS_BOOL && pSource->type != IS_LONG) return FALSE; *p_value = pSource->value.lval != 0; return TRUE; } /* * value should be a double * */ static zend_bool satellite_zval_to_namedvalue_double(const zval * pSource, CORBA_NamedValue * pDestination) { CORBA_double * p_value = (CORBA_double *)pDestination->argument._value; pDestination->len = sizeof(CORBA_double); if (pSource == NULL) return TRUE; /*convert_to_double(pSource);*/ if (pSource->type != IS_DOUBLE) return FALSE; *p_value = pSource->value.dval; return TRUE; } /* * value should be a long * */ static zend_bool satellite_zval_to_namedvalue_long(const zval * pSource, CORBA_NamedValue * pDestination) { CORBA_long * p_value = (CORBA_long *)pDestination->argument._value; pDestination->len = sizeof(CORBA_long); if (pSource == NULL) return TRUE; convert_to_long((zval*)pSource); /* so long "const" */ if (pSource->type != IS_LONG) return FALSE; *p_value = pSource->value.lval; return TRUE; } /* * value should be a short * */ static zend_bool satellite_zval_to_namedvalue_short(const zval * pSource, CORBA_NamedValue * pDestination) { CORBA_short * p_value = (CORBA_short *)pDestination->argument._value; pDestination->len = sizeof(CORBA_short); if (pSource == NULL) return TRUE; /* convert_to_long((zval *)pSource);*/ /* discard const */; if (pSource->type != IS_LONG) { /* printf("source value type is %i in satellite_zval_to_namedvalue_short\n", pSource->type);*/ return FALSE; } *p_value = pSource->value.lval; return TRUE; } /* * convert an OrbitObject to a CORBA object * * value should just be a CORBA_Object */ static zend_bool satellite_zval_to_namedvalue_objref(const zval * pSource, CORBA_NamedValue * pDestination) { OrbitObject * pObject = NULL; CORBA_Object * p_value = (CORBA_Object*)&pDestination->argument._value; pDestination->len = 1; if (pSource == NULL) return TRUE; /* nothing else to do */ if (pSource->type != IS_OBJECT) goto error; /* see that it's a corba object */ if (strcmp(Z_OBJCE_P(pSource)->name, "OrbitObject") != 0) goto error; /* bad class type */ pObject = OrbitObject_RetrieveData(pSource); if (pObject == NULL) goto error; /* unexpected error */ *p_value = OrbitObject_GetCorbaObject(pObject); /* debug */ /* (CORBA_Object)pDestination->argument._value = OrbitObject_GetCorbaObject(pObject);*/ if (*p_value == NULL) { /* printf("NULL object in satellite_zval_to_namedvalue_objref\n");*/ goto error; } /* printf("satellite_zval_to_namedvalue_objref: %s\n", (*p_value)->type_id);*/ return TRUE; error: return FALSE; } /* * convert a PHP array to a CORBA sequence * * value should be a CORBA_sequence_octet * */ static zend_bool satellite_zval_to_namedvalue_sequence(const zval * pSource, CORBA_NamedValue * pDestination) { CORBA_sequence_octet * p_sequence_octet = (CORBA_sequence_octet *)pDestination->argument._value; HashTable * p_hashtable = NULL; int member_count = 0; if (pSource == NULL) return TRUE; /* nothing to do */ if (pSource->type != IS_ARRAY) goto error; /* bad source type */ p_hashtable = pSource->value.ht; member_count = zend_hash_num_elements(p_hashtable); /* prepare sequence octet */ ORBit_sequence_octet_init(p_sequence_octet, member_count); /* * XXX: potential bug nest follows */ if (member_count > 0) { CORBA_NamedValue destination_value; zval * p_source_value; HashPosition position = NULL; int i; void ** p_members = (void **)p_sequence_octet->_buffer; /* prepare to start walking the hash table */ zend_hash_internal_pointer_reset_ex(p_hashtable, &position); for(i = 0; i < member_count; i++) { if (position == NULL) goto error; #if 0 /* the function call gets messed up */ if (zend_hash_get_current_data_ex( p_hashtable, /* XXX */, &position) == FAILURE) goto error; #else p_source_value = *(zval**)position->pData; #endif memset(&destination_value, 0, sizeof(destination_value)); destination_value.argument._type = CORBA_TypeCode_content_type( pDestination->argument._type, orbit_get_environment()); if (orbit_caught_exception()) goto error; /* now get a NamedValue for this element */ if (!orbit_zval_to_namedvalue(p_source_value, &destination_value)) goto error; /* put values in our value */ p_members[i] = *(void**)destination_value.argument._value; /* get next in hashtable */ if (zend_hash_move_forward_ex(p_hashtable, &position) == FAILURE) goto error; } } /* pDestination->argument._value = p_sequence_octet;*/ return TRUE; error: ORBit_sequence_octet_fini(p_sequence_octet); /* appropriate destruction? */ return FALSE; } /* * convert a PHP string to a CORBA string * * value should be a char ** */ static zend_bool satellite_zval_to_namedvalue_string(const zval * pSource, CORBA_NamedValue * pDestination) { char ** p_value = (char **)pDestination->argument._value; if (pSource == NULL) return TRUE; /* do nothing */ #if 0 convert_to_string((zval *)pSource); /* discard const */ if (pSource->type == IS_NULL) return TRUE; /* do nothing */ #endif if (pSource->type != IS_STRING) goto error; *p_value = CORBA_string_dup(pSource->value.str.val); pDestination->len = strlen(*p_value); return TRUE; error: return FALSE; } /* * convert an OrbitStruct object to a CORBA structure * * XXX: this is trouble! * */ static zend_bool satellite_zval_to_namedvalue_struct(const zval * pSource, CORBA_NamedValue * pDestination) { OrbitStruct * p_struct = NULL; int member_count = 0; CORBA_TypeCode type = NULL; pDestination->len = 1; /* nothing else to do if we have no source object */ if (pSource == NULL) return TRUE; /* see that it's an object */ if (pSource->type != IS_OBJECT) goto error; /* bad source type */ /* see that it's a structure object */ if (strcmp(Z_OBJCE_P(pSource)->name, "OrbitStruct") != 0) goto error; /* bad class type */ /* get struct info */ p_struct = OrbitStruct_RetrieveData(pSource); if (p_struct == NULL) goto error; /* unexpected error */ /* make type a shortcut to the typecode */ type = pDestination->argument._type; /* check respository ids */ { char * p_source_repository_id = OrbitStruct_GetRepositoryId(p_struct); char * p_destination_repository_id = CORBA_TypeCode_id(type, orbit_get_environment()); if (orbit_caught_exception()) goto error; if (strcmp(p_destination_repository_id, p_source_repository_id) != 0) goto error; /* bad struct */ } /* now we know the source and destination matches! */ member_count = CORBA_TypeCode_member_count(type, orbit_get_environment()); if (orbit_caught_exception()) goto error; if (member_count > 0) { int i; CORBA_NamedValue destination_value; zval source_value; zend_bool success; char * p_buffer = (char *)pDestination->argument._value; int element_size = 0; for (i = 0; i < member_count; i++) { int alignment; /* get member name */ char * p_name = CORBA_TypeCode_member_name(type, i, orbit_get_environment()); if (orbit_caught_exception()) goto error; /* get source value */ success = OrbitStruct_GetProperty(p_struct, p_name, &source_value); if (!success) { goto error; } /* prepare destination value */ memset(&destination_value, 0, sizeof(CORBA_NamedValue)); destination_value.argument._type = CORBA_TypeCode_member_type(type, i, orbit_get_environment()); if (destination_value.argument._type == NULL) goto error; /* convert member */ success = orbit_zval_to_namedvalue(&source_value, &destination_value); if (!success) goto error; element_size = ORBit_gather_alloc_info(destination_value.argument._type); /* align pointer and set value */ alignment = ORBit_find_alignment(destination_value.argument._type); p_buffer = ALIGN_ADDRESS(p_buffer, alignment); /* copy value to struct */ memcpy(p_buffer, destination_value.argument._value, element_size); p_buffer += element_size; } } return TRUE; error: return FALSE; } /* * public function to convert form a zval to CORBA_NamedValue * * The data type specific functions does not own * pDestination->argument._value!!! */ zend_bool orbit_zval_to_namedvalue(const zval * pSource, CORBA_NamedValue * pDestination) { zend_bool success = FALSE; CORBA_TCKind kind; if (pDestination->argument._type == NULL) { /* printf("pDestination->argument._type is NULL in orbit_zval_to_namedvalue\n");*/ return FALSE; } kind = CORBA_TypeCode_kind( pDestination->argument._type, orbit_get_environment()); if (orbit_caught_exception()) return FALSE; /* allocate memory for value */ if (pSource != NULL) { /* use special function to allocate value -- good or bad idea? */ pDestination->argument._value = ORBit_alloc_tcval(pDestination->argument._type, 1); } switch (kind) { case CORBA_tk_boolean: success = satellite_zval_to_namedvalue_boolean(pSource, pDestination); break; case CORBA_tk_double: success = satellite_zval_to_namedvalue_double(pSource, pDestination); break; case CORBA_tk_enum: case CORBA_tk_long: success = satellite_zval_to_namedvalue_long(pSource, pDestination); break; case CORBA_tk_objref: success = satellite_zval_to_namedvalue_objref(pSource, pDestination); break; case CORBA_tk_sequence: success = satellite_zval_to_namedvalue_sequence(pSource, pDestination); break; case CORBA_tk_short: success = satellite_zval_to_namedvalue_short(pSource, pDestination); break; case CORBA_tk_string: /* 18 */ success = satellite_zval_to_namedvalue_string(pSource, pDestination); break; case CORBA_tk_struct: /* 15 */ success = satellite_zval_to_namedvalue_struct(pSource, pDestination); break; default: /* printf("unsupported corba TCKind %i\n", kind);*/ /* php_error(E_WARNING, "unsupported corba TCKind %i", kind);*/ } if (!success) { /* printf("orbit_zval_to_namedvalue failed for TCKind %i\n", kind);*/ /* * does this always crash? then we better look for another way of * freeing the data! */ /* CORBA_free(pDestination->argument._value); */ pDestination->argument._value = NULL; } return success; }