cvs: /php3/functions imap.c imap.h
| From: | Andrew Skalski | Date: | Mon, 17 Jan 2000 19:19:04 +0000 |
| Subject: | cvs: /php3/functions imap.c imap.h | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-14719@lists.php.net to get a copy of this message | ||
askalski Mon Jan 17 11:19:04 2000 EDT
Modified files:
/php3/functions imap.c imap.h
Log:
Added imap_utf7_decode() and imap_utf7_encode() functions.
Index: php3/functions/imap.c
diff -u php3/functions/imap.c:1.77 php3/functions/imap.c:1.78
--- php3/functions/imap.c:1.77 Sat Jan 15 13:39:15 2000
+++ php3/functions/imap.c Mon Jan 17 11:19:03 2000
@@ -33,7 +33,7 @@
| Andrew Skalski <askalski@chek.com> |
+----------------------------------------------------------------------+
*/
-/* $Id: imap.c,v 1.77 2000/01/15 21:39:15 fmk Exp $ */
+/* $Id: imap.c,v 1.78 2000/01/17 19:19:03 askalski Exp $ */
#define IMAP41
@@ -199,6 +199,8 @@
{"imap_mail", php3_imap_mail, NULL},
{"imap_search", php3_imap_search, NULL},
{"imap_utf8", php3_imap_utf8, NULL},
+ {"imap_utf7_decode", php3_imap_utf7_decode, NULL},
+ {"imap_utf7_encode", php3_imap_utf7_encode, NULL},
{NULL, NULL, NULL}
};
@@ -2492,7 +2494,6 @@
/* }}} */
-
/* {{{ proto string imap_utf8(string string)
Convert a string to UTF8 */
void php3_imap_utf8(INTERNAL_FUNCTION_PARAMETERS)
@@ -2515,6 +2516,251 @@
RETURN_STRINGL(dest.data,strlen(dest.data),1);
}
/* }}} */
+
+/* macros for the modified utf7 conversion functions */
+/* author: Andrew Skalski <askalski@chek.com> */
+
+/* tests `c' and returns true if it is a special character */
+#define SPECIAL(c) ((c) <= 0x1f || (c) >= 0x7f)
+/* validate a modified-base64 character */
+#define B64CHAR(c) (isalnum(c) || (c) == '+' || (c) == ',')
+/* map the low 64 bits of `n' to the modified-base64 characters */
+#define B64(n) "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ "abcdefghijklmnopqrstuvwxyz0123456789+,"[(n) & 0x3f];
+/* map the modified-base64 character `c' to its 64 bit value */
+#define UNB64(c) ((c) == '+' ? 62 : (c) == ',' ? 63 : (c) >=
'a' ? \
+ (c) - 71 : (c) >= 'A' ? (c) - 65 : (c) + 4)
+
+/* {{{ proto string imap_utf7_decode(string buf)
+ Decode a Modified UTF-7 string */
+void php3_imap_utf7_decode(INTERNAL_FUNCTION_PARAMETERS)
+{
+ /* author: Andrew Skalski <askalski@chek.com> */
+ int argc;
+ pval *arg;
+ const unsigned char *in, *inp, *endp;
+ unsigned char *out, *outp;
+ int inlen, outlen;
+ enum { ST_NORMAL, /* printable text */
+ ST_DECODE0, /* encoded text rotation... */
+ ST_DECODE1,
+ ST_DECODE2,
+ ST_DECODE3
+ } state;
+
+ /* collect arguments */
+ argc = ARG_COUNT(ht);
+ if (argc != 1 || getParameters(ht, argc, &arg) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(arg);
+ in = (const unsigned char*) arg->value.str.val;
+ inlen = arg->value.str.len;
+
+ /* validate and compute length of output string */
+ outlen = 0;
+ state = ST_NORMAL;
+ for (endp = (inp = in) + inlen; inp < endp; inp++) {
+ if (state == ST_NORMAL) {
+ /* process printable character */
+ if (SPECIAL(*inp))
+ {RETURN_FALSE;}
+ else if (*inp != '&')
+ outlen++;
+ else if (inp == endp)
+ {RETURN_FALSE;}
+ else if (inp[1] != '-')
+ state = ST_DECODE0;
+ else {
+ outlen++;
+ inp++;
+ }
+ }
+ else if (*inp == '-') {
+ /* return to NORMAL mode */
+ if (state == ST_DECODE1)
+ RETURN_FALSE;
+ state = ST_NORMAL;
+ }
+ else if (!B64CHAR(*inp))
+ {RETURN_FALSE;}
+ else {
+ switch (state) {
+ case ST_DECODE3:
+ outlen++;
+ state = ST_DECODE0;
+ break;
+ case ST_DECODE2:
+ case ST_DECODE1:
+ outlen++;
+ case ST_DECODE0:
+ state++;
+ case ST_NORMAL:
+ }
+ }
+ }
+
+ /* enforce end state */
+ if (state != ST_NORMAL)
+ RETURN_FALSE;
+
+ /* allocate output buffer */
+ if ((out = emalloc(outlen)) == NULL)
+ RETURN_FALSE;
+
+ /* decode input string */
+ outp = out;
+ state = ST_NORMAL;
+ for (endp = (inp = in) + inlen; inp < endp; inp++) {
+ if (state == ST_NORMAL) {
+ if (*inp == '&' && inp[1] != '-')
+ state = ST_DECODE0;
+ else if ((*outp++ = *inp) == '&')
+ inp++;
+ }
+ else if (*inp == '-')
+ state = ST_NORMAL;
+ else {
+ /* decode input character */
+ switch (state) {
+ case ST_DECODE0:
+ *outp = UNB64(*inp) << 2;
+ state = ST_DECODE1;
+ break;
+ case ST_DECODE1:
+ outp[1] = UNB64(*inp);
+ *outp++ |= outp[1] >> 4;
+ *outp <<= 4;
+ state = ST_DECODE2;
+ break;
+ case ST_DECODE2:
+ outp[1] = UNB64(*inp);
+ *outp++ |= outp[1] >> 2;
+ *outp <<= 6;
+ state = ST_DECODE3;
+ break;
+ case ST_DECODE3:
+ *outp++ |= UNB64(*inp);
+ state = ST_DECODE0;
+ case ST_NORMAL:
+ }
+ }
+ }
+
+ RETURN_STRINGL(out, outlen, 0);
+}
+/* }}} */
+
+/* {{{ proto string imap_utf7_decode(string buf)
+ Encode a string in Modified UTF-7 */
+void php3_imap_utf7_encode(INTERNAL_FUNCTION_PARAMETERS)
+{
+ /* author: Andrew Skalski <askalski@chek.com> */
+ int argc;
+ pval *arg;
+ const unsigned char *in, *inp, *endp;
+ unsigned char *out, *outp;
+ int inlen, outlen;
+ enum { ST_NORMAL, /* printable text */
+ ST_ENCODE0, /* encoded text rotation... */
+ ST_ENCODE1,
+ ST_ENCODE2
+ } state;
+
+ /* collect arguments */
+ argc = ARG_COUNT(ht);
+ if (argc != 1 || getParameters(ht, argc, &arg) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(arg);
+ in = (const unsigned char*) arg->value.str.val;
+ inlen = arg->value.str.len;
+
+ /* compute the length of the result string */
+ outlen = 0;
+ state = ST_NORMAL;
+ endp = (inp = in) + inlen;
+ while (inp < endp) {
+ if (state == ST_NORMAL) {
+ if (SPECIAL(*inp)) {
+ state = ST_ENCODE0;
+ outlen++;
+ }
+ else if (*inp++ == '&')
+ outlen++;
+ outlen++;
+ }
+ else if (!SPECIAL(*inp))
+ state = ST_NORMAL;
+ else {
+ /* ST_ENCODE0 -> ST_ENCODE1 - two chars
+ * ST_ENCODE1 -> ST_ENCODE2 - one char
+ * ST_ENCODE2 -> ST_ENCODE0 - one char
+ */
+ if (state == ST_ENCODE2)
+ state = ST_ENCODE0;
+ else if (state++ == ST_ENCODE0)
+ outlen++;
+ outlen++;
+ inp++;
+ }
+ }
+
+ /* allocate output buffer */
+ if ((out = emalloc(outlen)) == NULL)
+ RETURN_FALSE;
+
+ /* encode input string */
+ outp = out;
+ state = ST_NORMAL;
+ endp = (inp = in) + inlen;
+ while (inp < endp || state != ST_NORMAL) {
+ if (state == ST_NORMAL) {
+ if (SPECIAL(*inp)) {
+ /* begin encoding */
+ *outp++ = '&';
+ state = ST_ENCODE0;
+ }
+ else if ((*outp++ = *inp++) == '&')
+ *outp++ = '-';
+ }
+ else if (inp == endp || !SPECIAL(*inp)) {
+ /* flush overflow and terminate region */
+ if (state != ST_ENCODE0)
+ *outp++ = B64(*outp);
+ *outp++ = '-';
+ state = ST_NORMAL;
+ }
+ else {
+ /* encode input character */
+ switch (state) {
+ case ST_ENCODE0:
+ *outp++ = B64(*inp >> 2);
+ *outp = *inp++ << 4;
+ state = ST_ENCODE1;
+ break;
+ case ST_ENCODE1:
+ *outp++ = B64(*outp | *inp >> 4);
+ *outp = *inp++ << 2;
+ state = ST_ENCODE2;
+ break;
+ case ST_ENCODE2:
+ *outp++ = B64(*outp | *inp >> 6);
+ *outp++ = B64(*inp++);
+ state = ST_ENCODE0;
+ case ST_NORMAL:
+ }
+ }
+ }
+
+ RETURN_STRINGL(out, outlen, 0);
+}
+/* }}} */
+
+#undef SPECIAL
+#undef B64CHAR
+#undef B64
+#undef UNB64
/* {{{ proto int imap_setflag_full(int stream_id, string sequence, string flag [, int options])
Sets flags on messages */
Index: php3/functions/imap.h
diff -u php3/functions/imap.h:1.15 php3/functions/imap.h:1.16
--- php3/functions/imap.h:1.15 Wed Jan 12 00:57:14 2000
+++ php3/functions/imap.h Mon Jan 17 11:19:03 2000
@@ -1,4 +1,4 @@
-/* $Id: imap.h,v 1.15 2000/01/12 08:57:14 fmk Exp $ */
+/* $Id: imap.h,v 1.16 2000/01/17 19:19:03 askalski Exp $ */
#ifndef _INCLUDED_IMAP_H
#define _INCLUDED_IMAP_H
@@ -76,6 +76,8 @@
void php3_imap_mail(INTERNAL_FUNCTION_PARAMETERS);
void php3_imap_search(INTERNAL_FUNCTION_PARAMETERS);
void php3_imap_utf8(INTERNAL_FUNCTION_PARAMETERS);
+void php3_imap_utf7_decode(INTERNAL_FUNCTION_PARAMETERS);
+void php3_imap_utf7_encode(INTERNAL_FUNCTION_PARAMETERS);
#else
#define php3_imap_module_ptr NULL
#endif /* HAVE_IMAP */