+ char *ptr;
+
+ /* examples:
+ * iso-8850-1'de'bl%f6der%20schei%df%21
+ * utf-8'de-DE'bl%c3%b6der%20schei%c3%9f%21
+ */
+
+ switch (Z_STRVAL_P(zv)[0]) {
+ case 'I':
+ case 'i':
+ if (!strncasecmp(Z_STRVAL_P(zv), ZEND_STRL("iso-8859-1"))) {
+ *latin1 = 1;
+ ptr = Z_STRVAL_P(zv) + lenof("iso-8859-1");
+ break;
+ }
+ /* no break */
+ case 'U':
+ case 'u':
+ if (!strncasecmp(Z_STRVAL_P(zv), ZEND_STRL("utf-8"))) {
+ *latin1 = 0;
+ ptr = Z_STRVAL_P(zv) + lenof("utf-8");
+ break;
+ }
+ /* no break */
+ default:
+ return;
+ }
+
+ /* extract language */
+ if (*ptr == '\'') {
+ for (*language = ++ptr; *ptr && *ptr != '\''; ++ptr);
+ if (!*ptr) {
+ *language = NULL;
+ return;
+ }
+ *language = estrndup(*language, ptr - *language);
+
+ /* remainder */
+ ptr = estrdup(++ptr);
+ zval_dtor(zv);
+ ZVAL_STRING(zv, ptr, 0);
+ }
+}
+
+static void utf8encode(zval *zv)
+{
+ size_t pos, len = 0;
+ unsigned char *ptr = (unsigned char *) Z_STRVAL_P(zv);
+
+ while (*ptr) {
+ if (*ptr++ >= 0x80) {
+ ++len;
+ }
+ ++len;
+ }