moriyoshi               Mon Jan  6 20:41:18 2003 EDT

  Modified files:              
    /php4/ext/standard  filters.c 
  Log:
  Implemented quoted-printable stream filter
  
  
Index: php4/ext/standard/filters.c
diff -u php4/ext/standard/filters.c:1.5 php4/ext/standard/filters.c:1.6
--- php4/ext/standard/filters.c:1.5     Mon Jan  6 19:03:25 2003
+++ php4/ext/standard/filters.c Mon Jan  6 20:41:18 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: filters.c,v 1.5 2003/01/07 00:03:25 moriyoshi Exp $ */
+/* $Id: filters.c,v 1.6 2003/01/07 01:41:18 moriyoshi Exp $ */
 
 #include "php.h"
 #include "php_globals.h"
@@ -480,6 +480,112 @@
 };
 /* }}} */
 
+/* {{{ quoted-printable stream filter implementation */
+
+static size_t strfilter_quoted_printable_write(php_stream *stream, php_stream_filter 
+*thisfilter,
+                       const char *buf, size_t count TSRMLS_DC)
+{
+       char chunk[4096];
+       size_t chunk_len;
+       unsigned char *ps;
+       unsigned int bcnt;
+       static char qp_digits[] = "0123456789ABCDEF";
+
+       chunk_len = 0;
+
+       ps = (unsigned char *)buf;
+       for (bcnt = count; bcnt > 0; bcnt--) {
+               unsigned int c = *(ps++);
+
+               if ((c >= 33 && c <= 60) || (c >= 62 && c <= 126)) { 
+                       if (chunk_len >= sizeof(chunk)) {
+                               php_stream_filter_write_next(stream, thisfilter, 
+chunk, chunk_len);
+                               chunk_len = 0;
+                       }
+                       chunk[chunk_len++] = c;
+               } else {
+                       if (chunk_len > sizeof(chunk) - 3) {
+                               php_stream_filter_write_next(stream, thisfilter, 
+chunk, chunk_len);
+                               chunk_len = 0;
+                       }
+                       chunk[chunk_len++] = '=';
+                       chunk[chunk_len++] = qp_digits[(c >> 4)];
+                       chunk[chunk_len++] = qp_digits[(c & 0x0f)]; 
+               }
+       }
+       php_stream_filter_write_next(stream, thisfilter, chunk, chunk_len);
+
+       return count;
+}
+
+static size_t strfilter_quoted_printable_read(php_stream *stream, php_stream_filter 
+*thisfilter,
+                       char *buf, size_t count TSRMLS_DC)
+{
+       size_t nbytes_decoded;
+       size_t bcnt;
+       unsigned char *ps, *pd;
+       unsigned int scan_stat = (unsigned int)thisfilter->abstract;
+       unsigned int v;
+
+       bcnt = php_stream_filter_read_next(stream, thisfilter, buf, count);
+       nbytes_decoded = 0; 
+       ps = pd = (unsigned char *)buf;
+       v = 0;
+
+       for (;bcnt > 0; bcnt--) {
+               switch (scan_stat) {
+                       case 0:
+                               if (*ps == '=') {
+                                       scan_stat = 1;
+                               } else {
+                                       *(pd++) = *ps;
+                                       nbytes_decoded++;
+                               }
+                               break;
+
+                       case 1: case 2: {
+                               unsigned int nbl = (*ps >= 'A' ? *ps - 0x37 : *ps - 
+0x30);
+
+                               if (nbl > 15) {
+                                       php_error(E_WARNING, "stream 
+filter(stream.quoted-printable): invalid character sequence"); 
+                                       return 0;
+                               }
+                               v = (v << 4) | nbl;
+
+                               scan_stat++;
+                               if (scan_stat == 3) {
+                                       *(pd++) = v;
+                                       nbytes_decoded++;
+                                       scan_stat = 0;
+                               }
+                       }
+               }
+               ps++;
+       }
+       (unsigned int)thisfilter->abstract = scan_stat;
+       return nbytes_decoded;
+}
+
+static php_stream_filter_ops strfilter_quoted_printable_ops = {
+       strfilter_quoted_printable_write,
+       strfilter_quoted_printable_read,
+       commonfilter_nop_flush,
+       commonfilter_nop_eof,
+       NULL,
+       "string.quoted-printable"
+};
+
+static php_stream_filter *strfilter_quoted_printable_create(const char *filtername, 
+const char *filterparams,
+               int filterparamslen, int persistent TSRMLS_DC)
+{
+       return php_stream_filter_alloc(&strfilter_quoted_printable_ops, 0, persistent);
+}
+
+static php_stream_filter_factory strfilter_quoted_printable_factory = {
+       strfilter_quoted_printable_create
+};
+/* }}} */
+
 static const struct {
        php_stream_filter_ops *ops;
        php_stream_filter_factory *factory;
@@ -488,6 +594,7 @@
        { &strfilter_toupper_ops, &strfilter_toupper_factory },
        { &strfilter_tolower_ops, &strfilter_tolower_factory },
        { &strfilter_base64_ops, &strfilter_base64_factory },
+       { &strfilter_quoted_printable_ops, &strfilter_quoted_printable_factory },
        /* additional filters to go here */
        { NULL, NULL }
 };



-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to