summaryrefslogtreecommitdiff
path: root/php/src/IcePHP/Util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'php/src/IcePHP/Util.cpp')
-rw-r--r--php/src/IcePHP/Util.cpp375
1 files changed, 330 insertions, 45 deletions
diff --git a/php/src/IcePHP/Util.cpp b/php/src/IcePHP/Util.cpp
index 60b52ac15a0..2bd1875bce5 100644
--- a/php/src/IcePHP/Util.cpp
+++ b/php/src/IcePHP/Util.cpp
@@ -17,6 +17,169 @@ using namespace std;
using namespace IcePHP;
using namespace Slice::PHP;
+namespace
+{
+
+bool
+getMember(zval* zv, const string& name, zval** member, int type, bool required TSRMLS_DC)
+{
+ *member = 0;
+
+ void* data = 0;
+ if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST(name.c_str()), name.size() + 1, &data) == FAILURE)
+ {
+ if(required)
+ {
+ invalidArgument("object does not contain member `%s'" TSRMLS_CC, name.c_str());
+ return false;
+ }
+ }
+
+ if(data)
+ {
+ zval** val = reinterpret_cast<zval**>(data);
+
+ if(Z_TYPE_PP(val) != type)
+ {
+ string expected = zendTypeToString(type);
+ string actual = zendTypeToString(Z_TYPE_PP(val));
+ invalidArgument("expected value of type %s for member `%s' but received %s" TSRMLS_CC, expected.c_str(),
+ name.c_str(), actual.c_str());
+ return false;
+ }
+
+ *member = *val;
+ }
+
+ return true;
+}
+
+void
+setStringMember(zval* obj, const string& name, const string& val TSRMLS_DC)
+{
+ zend_class_entry* cls = Z_OBJCE_P(obj);
+ assert(cls);
+ zend_update_property_stringl(cls, obj, const_cast<char*>(name.c_str()), static_cast<int>(name.size()),
+ const_cast<char*>(val.c_str()), static_cast<int>(val.size()) TSRMLS_CC);
+}
+
+template<typename T, const char* PT>
+bool
+getVersion(zval* zv, T& v TSRMLS_DC)
+{
+ if(Z_TYPE_P(zv) != IS_OBJECT)
+ {
+ invalidArgument("value does not contain an object" TSRMLS_CC);
+ return false;
+ }
+
+ zend_class_entry* cls = idToClass(PT TSRMLS_CC);
+ assert(cls);
+
+ zend_class_entry* ce = Z_OBJCE_P(zv);
+ if(ce != cls)
+ {
+ invalidArgument("expected an instance of %s" TSRMLS_CC, ce->name);
+ return false;
+ }
+
+ zval* majorVal;
+ if(!getMember(zv, "major", &majorVal, IS_LONG, true TSRMLS_CC))
+ {
+ return false;
+ }
+
+ zval* minorVal;
+ if(!getMember(zv, "minor", &minorVal, IS_LONG, true TSRMLS_CC))
+ {
+ return false;
+ }
+
+ long m;
+ m = Z_LVAL_P(majorVal);
+ if(m < 0 || m > 255)
+ {
+ invalidArgument("version major must be a value between 0 and 255" TSRMLS_CC);
+ return false;
+ }
+ v.major = m;
+
+ m = Z_LVAL_P(minorVal);
+ if(m < 0 || m > 255)
+ {
+ invalidArgument("version minor must be a value between 0 and 255" TSRMLS_CC);
+ return false;
+ }
+ v.minor = m;
+
+ return true;
+}
+
+template<typename T, const char* PT>
+bool
+createVersion(zval* zv, const T& version TSRMLS_DC)
+{
+ zend_class_entry* cls = idToClass(PT TSRMLS_CC);
+ assert(cls);
+
+ if(object_init_ex(zv, cls) != SUCCESS)
+ {
+ runtimeError("unable to initialize %s" TSRMLS_CC, cls->name);
+ return false;
+ }
+
+ zend_update_property_long(cls, zv, const_cast<char*>("major"), sizeof("major") - 1, version.major TSRMLS_CC);
+ zend_update_property_long(cls, zv, const_cast<char*>("minor"), sizeof("minor") - 1, version.minor TSRMLS_CC);
+
+ return true;
+}
+
+template<typename T, const char* PT>
+bool
+versionToString(zval* zv, zval* s TSRMLS_DC)
+{
+ T v;
+ if(!getVersion<T, PT>(zv, v TSRMLS_CC))
+ {
+ return false;
+ }
+
+ try
+ {
+ string str = IceInternal::versionToString<T>(v);
+ ZVAL_STRINGL(s, STRCAST(str.c_str()), str.length(), 1);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ return false;
+ }
+
+ return true;
+}
+
+template<typename T, const char* PT>
+bool
+stringToVersion(const string& s, zval* zv TSRMLS_DC)
+{
+ try
+ {
+ T v = IceInternal::stringToVersion<T>(s);
+ return createVersion<T, PT>(zv, v TSRMLS_CC);
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ throwException(ex TSRMLS_CC);
+ }
+
+ return false;
+}
+
+char Ice_ProtocolVersion[] = "::Ice::ProtocolVersion";
+char Ice_EncodingVersion[] = "::Ice::EncodingVersion";
+
+}
+
#if PHP_VERSION_ID < 50400
#ifdef _WIN32
extern "C"
@@ -103,10 +266,8 @@ IcePHP::createIdentity(zval* zv, const Ice::Identity& id TSRMLS_DC)
return false;
}
- zend_update_property_string(cls, zv, const_cast<char*>("name"), sizeof("name") - 1, STRCAST(id.name.c_str())
- TSRMLS_CC);
- zend_update_property_string(cls, zv, const_cast<char*>("category"), sizeof("category") - 1,
- STRCAST(id.category.c_str()) TSRMLS_CC);
+ setStringMember(zv, "name", id.name TSRMLS_CC);
+ setStringMember(zv, "category", id.category TSRMLS_CC);
return true;
}
@@ -133,35 +294,19 @@ IcePHP::extractIdentity(zval* zv, Ice::Identity& id TSRMLS_DC)
//
// Category is optional, but name is required.
//
- void* categoryData = 0;
- void* nameData;
- if(zend_hash_find(Z_OBJPROP_P(zv), STRCAST("name"), sizeof("name"), &nameData) == FAILURE)
- {
- invalidArgument("identity value does not contain member `name'" TSRMLS_CC);
- return false;
- }
- zend_hash_find(Z_OBJPROP_P(zv), STRCAST("category"), sizeof("category"), &categoryData);
- zval** categoryVal = reinterpret_cast<zval**>(categoryData);
- zval** nameVal = reinterpret_cast<zval**>(nameData);
+ zval* categoryVal;
+ zval* nameVal;
- if(Z_TYPE_PP(nameVal) != IS_STRING)
+ if(!getMember(zv, "category", &categoryVal, IS_STRING, false TSRMLS_CC) ||
+ !getMember(zv, "name", &nameVal, IS_STRING, true TSRMLS_CC))
{
- string s = zendTypeToString(Z_TYPE_PP(nameVal));
- invalidArgument("expected a string value for identity member `name' but received %s" TSRMLS_CC, s.c_str());
return false;
}
- if(categoryVal && Z_TYPE_PP(categoryVal) != IS_STRING && Z_TYPE_PP(categoryVal) != IS_NULL)
+ id.name = Z_STRVAL_P(nameVal);
+ if(categoryVal)
{
- string s = zendTypeToString(Z_TYPE_PP(categoryVal));
- invalidArgument("expected a string value for identity member `category' but received %s" TSRMLS_CC, s.c_str());
- return false;
- }
-
- id.name = Z_STRVAL_PP(nameVal);
- if(categoryVal && Z_TYPE_PP(categoryVal) == IS_STRING)
- {
- id.category = Z_STRVAL_PP(categoryVal);
+ id.category = Z_STRVAL_P(categoryVal);
}
else
{
@@ -286,13 +431,22 @@ IcePHP::extractStringArray(zval* zv, Ice::StringSeq& seq TSRMLS_DC)
return true;
}
-static void
-setStringMember(zval* obj, const string& name, const string& val TSRMLS_DC)
+bool
+IcePHP::createProtocolVersion(zval* zv, const Ice::ProtocolVersion& v TSRMLS_DC)
{
- zend_class_entry* cls = Z_OBJCE_P(obj);
- assert(cls);
- zend_update_property_stringl(cls, obj, const_cast<char*>(name.c_str()), static_cast<int>(name.size()),
- const_cast<char*>(val.c_str()), static_cast<int>(val.size()) TSRMLS_CC);
+ return createVersion<Ice::ProtocolVersion, Ice_ProtocolVersion>(zv, v TSRMLS_CC);
+}
+
+bool
+IcePHP::createEncodingVersion(zval* zv, const Ice::EncodingVersion& v TSRMLS_DC)
+{
+ return createVersion<Ice::EncodingVersion, Ice_EncodingVersion>(zv, v TSRMLS_CC);
+}
+
+bool
+IcePHP::extractEncodingVersion(zval* zv, Ice::EncodingVersion& v TSRMLS_DC)
+{
+ return getVersion<Ice::EncodingVersion, Ice_EncodingVersion>(zv, v TSRMLS_CC);
}
static bool
@@ -368,6 +522,7 @@ convertLocalException(const Ice::LocalException& ex, zval* zex TSRMLS_DC)
return false;
}
zend_update_property(cls, zex, const_cast<char*>("id"), sizeof("id") - 1, id TSRMLS_CC);
+ zval_ptr_dtor(&id);
}
catch(const Ice::RequestFailedException& e)
{
@@ -379,6 +534,7 @@ convertLocalException(const Ice::LocalException& ex, zval* zex TSRMLS_DC)
return false;
}
zend_update_property(cls, zex, const_cast<char*>("id"), sizeof("id") - 1, id TSRMLS_CC);
+ zval_ptr_dtor(&id);
setStringMember(zex, "facet", e.facet TSRMLS_CC);
setStringMember(zex, "operation", e.operation TSRMLS_CC);
}
@@ -398,21 +554,45 @@ convertLocalException(const Ice::LocalException& ex, zval* zex TSRMLS_DC)
}
catch(const Ice::UnsupportedProtocolException& e)
{
- zend_update_property_long(cls, zex, const_cast<char*>("badMajor"), sizeof("badMajor") - 1, e.badMajor
- TSRMLS_CC);
- zend_update_property_long(cls, zex, const_cast<char*>("badMinor"), sizeof("badMinor") - 1, e.badMinor
- TSRMLS_CC);
- zend_update_property_long(cls, zex, const_cast<char*>("major"), sizeof("major") - 1, e.major TSRMLS_CC);
- zend_update_property_long(cls, zex, const_cast<char*>("minor"), sizeof("minor") - 1, e.minor TSRMLS_CC);
+ zval* v;
+ MAKE_STD_ZVAL(v);
+ if(!createProtocolVersion(v, e.bad TSRMLS_CC))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("bad"), sizeof("bad") - 1, v TSRMLS_CC);
+ zval_ptr_dtor(&v);
+
+ MAKE_STD_ZVAL(v);
+ if(!createProtocolVersion(v, e.supported TSRMLS_CC))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("supported"), sizeof("supported") - 1, v TSRMLS_CC);
+ zval_ptr_dtor(&v);
}
catch(const Ice::UnsupportedEncodingException& e)
{
- zend_update_property_long(cls, zex, const_cast<char*>("badMajor"), sizeof("badMajor") - 1, e.badMajor
- TSRMLS_CC);
- zend_update_property_long(cls, zex, const_cast<char*>("badMinor"), sizeof("badMinor") - 1, e.badMinor
- TSRMLS_CC);
- zend_update_property_long(cls, zex, const_cast<char*>("major"), sizeof("major") - 1, e.major TSRMLS_CC);
- zend_update_property_long(cls, zex, const_cast<char*>("minor"), sizeof("minor") - 1, e.minor TSRMLS_CC);
+ zval* v;
+ MAKE_STD_ZVAL(v);
+ if(!createEncodingVersion(v, e.bad TSRMLS_CC))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("bad"), sizeof("bad") - 1, v TSRMLS_CC);
+ zval_ptr_dtor(&v);
+
+ MAKE_STD_ZVAL(v);
+ if(!createEncodingVersion(v, e.supported TSRMLS_CC))
+ {
+ zval_ptr_dtor(&v);
+ return false;
+ }
+ zend_update_property(cls, zex, const_cast<char*>("supported"), sizeof("supported") - 1, v TSRMLS_CC);
+ zval_ptr_dtor(&v);
}
catch(const Ice::NoObjectFactoryException& e)
{
@@ -746,3 +926,108 @@ ZEND_FUNCTION(Ice_generateUUID)
string uuid = IceUtil::generateUUID();
RETURN_STRINGL(STRCAST(uuid.c_str()), uuid.size(), 1);
}
+
+ZEND_FUNCTION(Ice_currentProtocol)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if(!createProtocolVersion(return_value, Ice::currentProtocol TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_currentProtocolEncoding)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if(!createEncodingVersion(return_value, Ice::currentProtocolEncoding TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_currentEncoding)
+{
+ if(ZEND_NUM_ARGS() > 0)
+ {
+ WRONG_PARAM_COUNT;
+ }
+
+ if(!createEncodingVersion(return_value, Ice::currentEncoding TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_protocolVersionToString)
+{
+ zend_class_entry* versionClass = idToClass(Ice_ProtocolVersion TSRMLS_CC);
+ assert(versionClass);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("O"), &zv, versionClass) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ if(!versionToString<Ice::ProtocolVersion, Ice_ProtocolVersion>(zv, return_value TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_stringToProtocolVersion)
+{
+ char* str;
+ int strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ if(!stringToVersion<Ice::ProtocolVersion, Ice_ProtocolVersion>(s, return_value TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_encodingVersionToString)
+{
+ zend_class_entry* versionClass = idToClass(Ice_EncodingVersion TSRMLS_CC);
+ assert(versionClass);
+
+ zval* zv;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("O"), &zv, versionClass) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+
+ if(!versionToString<Ice::EncodingVersion, Ice_EncodingVersion>(zv, return_value TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}
+
+ZEND_FUNCTION(Ice_stringToEncodingVersion)
+{
+ char* str;
+ int strLen;
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("s"), &str, &strLen) != SUCCESS)
+ {
+ RETURN_NULL();
+ }
+ string s(str, strLen);
+
+ if(!stringToVersion<Ice::EncodingVersion, Ice_EncodingVersion>(s, return_value TSRMLS_CC))
+ {
+ RETURN_NULL();
+ }
+}