encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
{
	encodePtr enc = NULL;
	char *nscat;
	int ns_len = ns ? strlen(ns) : 0;
	int type_len = strlen(type);
	int len = ns_len + type_len + 1;

	nscat = emalloc(len + 1);
	memcpy(nscat, ns, ns_len);
	nscat[ns_len] = ':';
	memcpy(nscat+ns_len+1, type, type_len);
	nscat[len] = '\0';

	enc = get_encoder_ex(sdl, nscat, len);

	if (enc == NULL &&
	    ((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
	      memcmp(ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
	     (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
	      memcmp(ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
		char *enc_nscat;
		int enc_ns_len;
		int enc_len;

		enc_ns_len = sizeof(XSD_NAMESPACE)-1;
		enc_len = enc_ns_len + type_len + 1;
		enc_nscat = emalloc(enc_len + 1);
		memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
		enc_nscat[enc_ns_len] = ':';
		memcpy(enc_nscat+enc_ns_len+1, type, type_len);
		enc_nscat[enc_len] = '\0';

		enc = get_encoder_ex(NULL, enc_nscat, enc_len);
		efree(enc_nscat);
		if (enc && sdl) {
			encodePtr new_enc	= pemalloc(sizeof(encode), sdl->is_persistent);
			memcpy(new_enc, enc, sizeof(encode));
			if (sdl->is_persistent) {
				new_enc->details.ns = zend_strndup(ns, ns_len);
				new_enc->details.type_str = strdup(new_enc->details.type_str);
			} else {
				new_enc->details.ns = estrndup(ns, ns_len);
				new_enc->details.type_str = estrdup(new_enc->details.type_str);
			}
			if (sdl->encoders == NULL) {
				sdl->encoders = pemalloc(sizeof(HashTable), sdl->is_persistent);
				zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, sdl->is_persistent);
			}
			zend_hash_str_update_ptr(sdl->encoders, nscat, len, new_enc);
			enc = new_enc;
		}
	}
	efree(nscat);
	return enc;
}
encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
{
	encodePtr enc = NULL;
	char *nscat;
	int ns_len = ns ? strlen(ns) : 0;
	int type_len = strlen(type);
	int len = ns_len + type_len + 1;

	nscat = emalloc(len + 1);
	memcpy(nscat, ns, ns_len);
	nscat[ns_len] = ':';
	memcpy(nscat+ns_len+1, type, type_len);
	nscat[len] = '\0';

	enc = get_encoder_ex(sdl, nscat, len);

	if (enc == NULL &&
	    ((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
	      memcmp(ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
	     (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
	      memcmp(ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
		char *enc_nscat;
		int enc_ns_len;
		int enc_len;

		enc_ns_len = sizeof(XSD_NAMESPACE)-1;
		enc_len = enc_ns_len + type_len + 1;
		enc_nscat = emalloc(enc_len + 1);
		memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
		enc_nscat[enc_ns_len] = ':';
		memcpy(enc_nscat+enc_ns_len+1, type, type_len);
		enc_nscat[enc_len] = '\0';

		enc = get_encoder_ex(NULL, enc_nscat, enc_len);
		efree(enc_nscat);
		if (enc && sdl) {
			encodePtr new_enc	= pemalloc(sizeof(encode), sdl->is_persistent);
			memcpy(new_enc, enc, sizeof(encode));
			if (sdl->is_persistent) {
				new_enc->details.ns = zend_strndup(ns, ns_len);
				new_enc->details.type_str = strdup(new_enc->details.type_str);
			} else {
				new_enc->details.ns = estrndup(ns, ns_len);
				new_enc->details.type_str = estrdup(new_enc->details.type_str);
			}
			if (sdl->encoders == NULL) {
				sdl->encoders = pemalloc(sizeof(HashTable), sdl->is_persistent);
				zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, sdl->is_persistent);
			}
			zend_hash_str_update_ptr(sdl->encoders, nscat, len, new_enc);
			enc = new_enc;
		}
	}
	efree(nscat);
	return enc;
}