diff --git a/fmt.h b/fmt.h index 06f5255..57e7e1b 100644 --- a/fmt.h +++ b/fmt.h @@ -85,4 +85,7 @@ unsigned int fmt_humank(char* dest,unsigned long long l); /* "Sun, 06 Nov 1994 08:49:37 GMT" */ unsigned int fmt_httpdate(char* dest,time_t t); +/* internal functions, may be independently useful */ +char fmt_tohex(char c); + #endif diff --git a/fmt/fmt_tohex.c b/fmt/fmt_tohex.c new file mode 100644 index 0000000..a473d28 --- /dev/null +++ b/fmt/fmt_tohex.c @@ -0,0 +1,6 @@ +#include "fmt.h" + +char fmt_tohex(char c) { + return c>=10?c-10+'a':c+'0'; +} + diff --git a/scan.h b/scan.h index 5238ba5..8bcc8d4 100644 --- a/scan.h +++ b/scan.h @@ -73,4 +73,8 @@ unsigned long scan_noncharsetnskip(const char *in,const char *charset,unsigned l */ unsigned int scan_httpdate(const char *in,time_t *t) __pure__; +/* a few internal function that might be useful independently */ +/* convert from hex ASCII, return 0 to 15 for success or -1 for failure */ +int scan_fromhex(unsigned char c); + #endif diff --git a/scan/scan_fromhex.c b/scan/scan_fromhex.c new file mode 100644 index 0000000..7da5c93 --- /dev/null +++ b/scan/scan_fromhex.c @@ -0,0 +1,12 @@ +#include "scan.h" + +int scan_fromhex(unsigned char c) { + if (c>='0' && c<='9') + return c-'0'; + else if (c>='A' && c<='F') + return c-'A'+10; + else if (c>='a' && c<='f') + return c-'a'+10; + return -1; +} + diff --git a/scan/scan_xlong.c b/scan/scan_xlong.c index b82f721..71e0787 100644 --- a/scan/scan_xlong.c +++ b/scan/scan_xlong.c @@ -1,21 +1,10 @@ #include "scan.h" -#include "haveinline.h" - -static inline int fromhex(unsigned char c) { - if (c>='0' && c<='9') - return c-'0'; - else if (c>='A' && c<='F') - return c-'A'+10; - else if (c>='a' && c<='f') - return c-'a'+10; - return -1; -} unsigned int scan_xlong(const char *src,unsigned long *dest) { register const char *tmp=src; register int l=0; register unsigned char c; - while ((c=fromhex(*tmp))<16) { + while ((c=scan_fromhex(*tmp))<16) { l=(l<<4)+c; ++tmp; } diff --git a/socket/scan_ip6_flat.c b/socket/scan_ip6_flat.c index adcf9f7..d9b28f1 100644 --- a/socket/scan_ip6_flat.c +++ b/socket/scan_ip6_flat.c @@ -1,24 +1,14 @@ -#include "haveinline.h" - -static inline int fromhex(unsigned char c) { - if (c>='0' && c<='9') - return c-'0'; - else if (c>='A' && c<='F') - return c-'A'+10; - else if (c>='a' && c<='f') - return c-'a'+10; - return -1; -} +#include "scan.h" unsigned int scan_ip6_flat(const char *s,char ip[16]) { int i; for (i=0; i<16; i++) { int tmp; - tmp=fromhex(*s++); + tmp=scan_fromhex(*s++); if (tmp<0) return 0; ip[i]=tmp << 4; - tmp=fromhex(*s++); + tmp=scan_fromhex(*s++); if (tmp<0) return 0; ip[i]+=tmp; } diff --git a/textcode.h b/textcode.h index 955eacf..a8b4dd0 100644 --- a/textcode.h +++ b/textcode.h @@ -3,48 +3,75 @@ /* These take len bytes from src and write them in encoded form to * dest (if dest != NULL), returning the number of bytes written. */ -unsigned int fmt_uuencoded(char* dest,const char* src,unsigned int len); -unsigned int fmt_base64(char* dest,const char* src,unsigned int len); -unsigned int fmt_quotedprintable(char* dest,const char* src,unsigned int len); -unsigned int fmt_urlencoded(char* dest,const char* src,unsigned int len); -unsigned int fmt_yenc(char* dest,const char* src,unsigned int len); -unsigned int fmt_hexdump(char* dest,const char* src,unsigned int len); +unsigned long fmt_uuencoded(char* dest,const char* src,unsigned long len); +unsigned long fmt_base64(char* dest,const char* src,unsigned long len); +unsigned long fmt_quotedprintable(char* dest,const char* src,unsigned long len); +unsigned long fmt_urlencoded(char* dest,const char* src,unsigned long len); +unsigned long fmt_yenc(char* dest,const char* src,unsigned long len); +unsigned long fmt_hexdump(char* dest,const char* src,unsigned long len); /* this changes '<' to '<' and '&' to '&' */ -unsigned int fmt_html(char* dest,const char* src,unsigned int len); +unsigned long fmt_html(char* dest,const char* src,unsigned long len); +/* change '\' to "\\", '\n' to "\n", ^A to "\x01" etc */ +unsigned long fmt_cescape(char* dest,const char* src,unsigned long len); +/* fold awk whitespace to '_'; this is great for writing fields with + * white spaces to a log file and still allow awk to do log analysis */ +unsigned long fmt_foldwhitespace(char* dest,const char* src,unsigned long len); /* These read one line from src, decoded it, and write the result to * dest. The number of decoded bytes is written to destlen. dest - * should be able to hold destlen bytes as a rule of thumb. */ -unsigned int scan_uuencoded(const char *src,char *dest,unsigned int *destlen); -unsigned int scan_base64(const char *src,char *dest,unsigned int *destlen); -unsigned int scan_quotedprintable(const char *src,char *dest,unsigned int *destlen); -unsigned int scan_urlencoded(const char *src,char *dest,unsigned int *destlen); -unsigned int scan_yenc(const char *src,char *dest,unsigned int *destlen); -unsigned int scan_hexdump(const char *src,char *dest,unsigned int *destlen); -unsigned int scan_html(const char *src,char *dest,unsigned int *destlen); + * should be able to hold strlen(src) bytes as a rule of thumb. */ +unsigned long scan_uuencoded(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_base64(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_quotedprintable(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_urlencoded(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_yenc(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_hexdump(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_html(const char *src,char *dest,unsigned long *destlen); +unsigned long scan_cescape(const char *src,char *dest,unsigned long *destlen); #ifdef STRALLOC_H -/* These take len bytes from src and write them in encoded form to sa. - * As the stralloc_* functions do, 1 - * is returned. If they run out of memory, sa contains the bytes already - * written and 0 is returned. */ -int fmt_quotedprintable_sa(stralloc *sa,const char* src,unsigned int len); -int fmt_base64_sa(stralloc *sa,const char* src,unsigned int len); -int fmt_uuencoded_sa(stralloc *sa,const char* src,unsigned int len); -int fmt_urlencoded_sa(stralloc *sa,const char* src,unsigned int len); -int fmt_yenc_sa(stralloc *sa,const char* src,unsigned int len); -int fmt_hexdump_sa(stralloc *sa,const char* src,unsigned int len); +/* WARNING: these functions _append_ to the stralloc, not overwrite! */ +/* stralloc wrappers; return 1 on success, 0 on failure */ +/* arg 1 is one of the fmt_* functions from above */ +int fmt_to_sa(unsigned long (*func)(char*,const char*,unsigned long), + stralloc* sa,const char* src,unsigned long len); -/* These read one line from src, decoded it, and write the result to - * sa. As the stralloc_* functions do, 1 - * is returned. If they run out of memory, sa contains the bytes already - * written and 0 is returned. */ -int scan_base64_sa(const char *src,stralloc* sa); -int scan_quotedprintable_sa(const char *src,stralloc* sa); -int scan_uuencoded_sa(const char *src,stralloc *sa); -int scan_urlencoded_sa(const char *src,stralloc *sa); -int scan_yenc_sa(const char *src,stralloc *sa); -int scan_hexdump_sa(const char *src,stralloc *sa); +/* arg 1 is one of the scan_* functions from above */ +/* return number of bytes scanned */ +unsigned long scan_to_sa(unsigned long (*func)(const char*,char*,unsigned long*), + const char* src,stralloc* sa); + +#define fmt_uuencoded_sa(sa,src,len) fmt_to_sa(fmt_uuencoded,sa,src,len) +#define fmt_base64_sa(sa,src,len) fmt_to_sa(fmt_base64,sa,src,len) +#define fmt_quotedprintable_sa(sa,src,len) fmt_to_sa(fmt_quotedprintable,sa,src,len) +#define fmt_urlencoded_sa(sa,src,len) fmt_to_sa(fmt_urlencoded,sa,src,len) +#define fmt_yenc_sa(sa,src,len) fmt_to_sa(fmt_yenc,sa,src,len) +#define fmt_hexdump_sa(sa,src,len) fmt_to_sa(fmt_hexdump,sa,src,len) +#define fmt_html_sa(sa,src,len) fmt_to_sa(fmt_html,sa,src,len) +#define fmt_cescape_sa(sa,src,len) fmt_to_sa(fmt_cescape,sa,src,len) + +#define scan_uuencoded_sa(src,sa) scan_to_sa(scan_uuencoded,src,sa) +#define scan_base64_sa(src,sa) scan_to_sa(scan_base64,src,sa) +#define scan_quotedprintable_sa(src,sa) scan_to_sa(scan_quotedprintable,src,sa) +#define scan_urlencoded_sa(src,sa) scan_to_sa(scan_urlencoded,src,sa) +#define scan_yenc_sa(src,sa) scan_to_sa(scan_yenc,src,sa) +#define scan_hexdump_sa(src,sa) scan_to_sa(scan_hexdump,src,sa) +#define scan_html_sa(src,sa) scan_to_sa(scan_html,src,sa) +#define scan_cescape_sa(src,sa) scan_to_sa(scan_cescape,src,sa) +#endif + +#ifdef ARRAY_H +void fmt_to_array(unsigned long (*func)(char*,const char*,unsigned long), + array* a,const char* src,unsigned long len); + +void fmt_tofrom_array(unsigned long (*func)(char*,const char*,unsigned long), + array* dest,array* src); + +unsigned long scan_to_array(unsigned long (*func)(const char*,char*,unsigned long*), + const char* src,array* dest); + +unsigned long scan_tofrom_array(unsigned long (*func)(const char*,char*,unsigned long*), + array* src,array* dest); #endif extern const char base64[64]; diff --git a/textcode/fmt_base64.c b/textcode/fmt_base64.c index 10df12f..1c1d387 100644 --- a/textcode/fmt_base64.c +++ b/textcode/fmt_base64.c @@ -2,7 +2,7 @@ #include "textcode.h" #include "haveinline.h" -unsigned int fmt_base64(char* dest,const char* src,unsigned int len) { +unsigned long fmt_base64(char* dest,const char* src,unsigned long len) { register const unsigned char* s=(const unsigned char*) src; unsigned short bits=0,temp=0; unsigned long written=0,i; diff --git a/textcode/fmt_base64_sa.c b/textcode/fmt_base64_sa.c deleted file mode 100644 index 9ef7743..0000000 --- a/textcode/fmt_base64_sa.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "haveinline.h" - -int fmt_base64_sa(stralloc *sa,const char* src,unsigned int len) { - register const unsigned char* s=(const unsigned char*) src; - unsigned short bits=0,temp=0; - unsigned long i; - char dest; - for (i=0; i6) { - dest=base64[((temp>>(bits-6))&63)]; - if (!stralloc_catb(sa, &dest, 1)) return 0; - bits-=6; - } - } - if (bits) { - temp<<=(6-bits); - dest=base64[temp&63]; - if (!stralloc_catb(sa, &dest, 1)) return 0; - } - while (sa->len&3) { - if (!stralloc_catb(sa, "=", 1)) return 0; - } - return 1; -} diff --git a/textcode/fmt_foldwhitespace.c b/textcode/fmt_foldwhitespace.c new file mode 100644 index 0000000..f74e4de --- /dev/null +++ b/textcode/fmt_foldwhitespace.c @@ -0,0 +1,17 @@ +#include "fmt.h" +#include "textcode.h" +#include "str.h" +#include "haveinline.h" + +unsigned long fmt_foldwhitespace(char* dest,const char* src,unsigned long len) { + register const unsigned char* s=(const unsigned char*) src; + unsigned long i; + char c; + for (i=0; i9?c-10+'a':c+'0'; -} - -unsigned int fmt_hexdump(char* dest,const char* src,unsigned int len) { +unsigned long fmt_hexdump(char* dest,const char* src,unsigned long len) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; for (i=0; i>4); - dest[written+1]=tohex(s[i]&15); + dest[written]=fmt_tohex(s[i]>>4); + dest[written+1]=fmt_tohex(s[i]&15); written+=2; } return written; diff --git a/textcode/fmt_hexdump_sa.c b/textcode/fmt_hexdump_sa.c deleted file mode 100644 index 7499311..0000000 --- a/textcode/fmt_hexdump_sa.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "str.h" -#include "haveinline.h" - -static inline int tohex(char c) { - return c>9?c-10+'a':c+'0'; -} - -int fmt_hexdump_sa(stralloc* sa,const char* src,unsigned int len) { - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - for (i=0; i>4); - dest[1]=tohex(s[i]&15); - if (!stralloc_catb(sa, dest, 2)) return 0; - } - return 1; -} diff --git a/textcode/fmt_html.c b/textcode/fmt_html.c index ed1e5b2..64bc395 100644 --- a/textcode/fmt_html.c +++ b/textcode/fmt_html.c @@ -3,7 +3,7 @@ #include "str.h" #include "haveinline.h" -unsigned int fmt_html(char* dest,const char* src,unsigned int len) { +unsigned long fmt_html(char* dest,const char* src,unsigned long len) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; const char* seq; diff --git a/textcode/fmt_quotedprintable.c b/textcode/fmt_quotedprintable.c index bb4997b..c330947 100644 --- a/textcode/fmt_quotedprintable.c +++ b/textcode/fmt_quotedprintable.c @@ -2,19 +2,15 @@ #include "textcode.h" #include "haveinline.h" -static inline int tohex(char c) { - return c>9?c-10+'A':c+'0'; -} - -unsigned int fmt_quotedprintable(char* dest,const char* src,unsigned int len) { +unsigned long fmt_quotedprintable(char* dest,const char* src,unsigned long len) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; for (i=0; i>4); - dest[written+2]=tohex(s[i]&15); + dest[written+1]=fmt_tohex(s[i]>>4); + dest[written+2]=fmt_tohex(s[i]&15); } written+=3; } else { diff --git a/textcode/fmt_quotedprintable_sa.c b/textcode/fmt_quotedprintable_sa.c deleted file mode 100644 index 09f0a28..0000000 --- a/textcode/fmt_quotedprintable_sa.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "haveinline.h" - -static inline int tohex(char c) { - return c>9?c-10+'A':c+'0'; -} - -int fmt_quotedprintable_sa(stralloc* sa,const char* src,unsigned int len) { - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - for (i=0; i>4); - dest[2]=tohex(s[i]&15); - if (!stralloc_catb(sa, dest, 3)) return 0; - } else { - if (!stralloc_catb(sa, s + i, 1)) return 0; - } - } - return 1; -} diff --git a/textcode/fmt_to_array.c b/textcode/fmt_to_array.c new file mode 100644 index 0000000..cbae6aa --- /dev/null +++ b/textcode/fmt_to_array.c @@ -0,0 +1,12 @@ +#include "array.h" +#include "textcode.h" + +void fmt_to_array(unsigned long (*func)(char*,const char*,unsigned long), + array* a,const char* src,unsigned long len) { + unsigned long needed=func(0,src,len); + if (array_allocate(a,1,array_bytes(a)+needed-1)) { + char* x=array_start(a)+array_bytes(a)-needed; + func(x,src,len); + } else + array_fail(a); +} diff --git a/textcode/fmt_to_sa.c b/textcode/fmt_to_sa.c new file mode 100644 index 0000000..9ac0c8a --- /dev/null +++ b/textcode/fmt_to_sa.c @@ -0,0 +1,11 @@ +#include "stralloc.h" +#include "textcode.h" + +int fmt_to_sa(unsigned long (*func)(char*,const char*,unsigned long), + stralloc* sa,const char* src,unsigned long len) { + unsigned long needed=func(0,src,len); + if (!stralloc_readyplus(sa,needed)) return 0; + func(sa->s+sa->len,src,len); + sa->len+=needed; + return needed; +} diff --git a/textcode/fmt_tofrom_array.c b/textcode/fmt_tofrom_array.c new file mode 100644 index 0000000..78e4fef --- /dev/null +++ b/textcode/fmt_tofrom_array.c @@ -0,0 +1,15 @@ +#include "array.h" +#include "textcode.h" + +void fmt_tofrom_array(unsigned long (*func)(char*,const char*,unsigned long), + array* dest,array* src) { + unsigned long needed; + char* x; + if (array_failed(dest) || array_failed(src)) { array_fail(dest); return; } + needed=func(0,array_start(src),array_bytes(src)); + if (array_allocate(dest,1,array_bytes(dest)+needed-1)) { + x=array_start(dest)+array_bytes(dest)-needed; + func(x,array_start(src),array_bytes(src)); + } else + array_fail(dest); +} diff --git a/textcode/fmt_urlencoded.c b/textcode/fmt_urlencoded.c index 8bdd3ff..4bf56bc 100644 --- a/textcode/fmt_urlencoded.c +++ b/textcode/fmt_urlencoded.c @@ -3,11 +3,7 @@ #include "str.h" #include "haveinline.h" -static inline int tohex(char c) { - return c>9?c-10+'A':c+'0'; -} - -unsigned int fmt_urlencoded(char* dest,const char* src,unsigned int len) { +unsigned long fmt_urlencoded(char* dest,const char* src,unsigned long len) { const char unsafe[]=" +%<>\"#{}|\\^~[]`;/?:@=&"; register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; @@ -15,8 +11,8 @@ unsigned int fmt_urlencoded(char* dest,const char* src,unsigned int len) { if (s[i]&0x80 || unsafe[str_chr(unsafe,s[i])]==s[i]) { if (dest) { dest[written]='%'; - dest[written+1]=tohex(s[i]>>4); - dest[written+2]=tohex(s[i]&15); + dest[written+1]=fmt_tohex(s[i]>>4); + dest[written+2]=fmt_tohex(s[i]&15); } written+=3; } else { diff --git a/textcode/fmt_urlencoded_sa.c b/textcode/fmt_urlencoded_sa.c deleted file mode 100644 index 1764e75..0000000 --- a/textcode/fmt_urlencoded_sa.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "str.h" -#include "haveinline.h" - -static inline int tohex(char c) { - return c>9?c-10+'A':c+'0'; -} - -int fmt_urlencoded_sa(stralloc *sa,const char* src,unsigned int len) { - const char unsafe[]=" %<>\"#{}|\\^~[]`;/?:@=&"; - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - for (i=0; i>4); - dest[2]=tohex(s[i]&15); - if (!stralloc_catb(sa, dest, 3)) return 0; - } else { - if (!stralloc_catb(sa, s+i, 1)) return 0; - } - } - return 1; -} diff --git a/textcode/fmt_uuencoded.c b/textcode/fmt_uuencoded.c index be59be3..e21b1c3 100644 --- a/textcode/fmt_uuencoded.c +++ b/textcode/fmt_uuencoded.c @@ -6,7 +6,7 @@ static inline unsigned int enc(unsigned char x) { return ((x-1)&077)+'!'; } -unsigned int fmt_uuencoded(char* dest,const char* src,unsigned int len) { +unsigned long fmt_uuencoded(char* dest,const char* src,unsigned long len) { unsigned int i; register const unsigned char* s=(const unsigned char*) src; const char* orig=dest; diff --git a/textcode/fmt_uuencoded_sa.c b/textcode/fmt_uuencoded_sa.c deleted file mode 100644 index f02e0f7..0000000 --- a/textcode/fmt_uuencoded_sa.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "haveinline.h" - -static inline unsigned int enc(unsigned char x) { - return ((x-1)&077)+'!'; -} - -int fmt_uuencoded_sa(stralloc* sa,const char* src,unsigned int len) { - unsigned int i; - register const unsigned char* s=(const unsigned char*) src; - unsigned long tmp; - while (len) { - { - register unsigned int diff; - char c; - if (len>45) { i=15; diff=45; } else { i=(len+2)/3; diff=len; } - c=enc(diff); - len-=diff; - if (!stralloc_catb(sa,&c,1)) return 0; - } - for (; i; --i) { - char dest[4]; - tmp=((unsigned long)s[0] << 16) + - ((unsigned long)s[1] << 8) + - ((unsigned long)s[2]); - dest[0]=enc((tmp>>(3*6))&077); - dest[1]=enc((tmp>>(2*6))&077); - dest[2]=enc((tmp>>(1*6))&077); - dest[3]=enc(tmp&077); - s+=3; - if (!stralloc_catb(sa,dest,4)) return 0; - } - if (!stralloc_catb(sa,"\n",1)) return 0; - } - return 1; -} diff --git a/textcode/fmt_yenc.c b/textcode/fmt_yenc.c index 4b91ca8..ba5bc76 100644 --- a/textcode/fmt_yenc.c +++ b/textcode/fmt_yenc.c @@ -1,7 +1,7 @@ #include "fmt.h" #include "textcode.h" -unsigned int fmt_yenc(char* dest,const char* src,unsigned int len) { +unsigned long fmt_yenc(char* dest,const char* src,unsigned long len) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; int linelen=0; diff --git a/textcode/fmt_yenc_sa.c b/textcode/fmt_yenc_sa.c deleted file mode 100644 index 910db8c..0000000 --- a/textcode/fmt_yenc_sa.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" - -int fmt_yenc_sa(stralloc *sa,const char* src,unsigned int len) { - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - int linelen=0; - for (i=0; i='a' && x<='z') return x-'a'+26; - if (x>='0' && x<='9') return x-'0'+26+26; - switch (x) { - case '+': return 62; - case '/': return 63; - default: return -1; - } -} - -int scan_base64_sa(const char *src,stralloc* sa) { - unsigned short tmp=0,bits=0; - register const unsigned char* s=(const unsigned char*) src; - for (;;) { - int a=dec(*s); - if (a<0) { - while (*s=='=') ++s; - break; - } - tmp=(tmp<<6)|a; bits+=6; - ++s; - if (bits>=8) { - char dest=(tmp>>(bits-=8)); - if (!stralloc_catb(sa,&dest,1)) return 0; - } - } - return 1; -} diff --git a/textcode/scan_hexdump.c b/textcode/scan_hexdump.c index 7a82de1..d667c05 100644 --- a/textcode/scan_hexdump.c +++ b/textcode/scan_hexdump.c @@ -1,22 +1,15 @@ #include "fmt.h" #include "textcode.h" -#include "haveinline.h" +#include "scan.h" -static inline int fromhex(char c) { - if (c>='0' && c<='9') return c-'0'; - if (c>='A' && c<='F') return c-'A'+10; - if (c>='a' && c<='f') return c-'a'+10; - return -1; -} - -unsigned int scan_hexdump(const char *src,char *dest,unsigned int *destlen) { +unsigned long scan_hexdump(const char *src,char *dest,unsigned long *destlen) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; for (i=0; s[i]; ++i) { - int j=fromhex(s[i]); + int j=scan_fromhex(s[i]); if (j<0) break; dest[written]=j<<4; - j=fromhex(s[i+1]); + j=scan_fromhex(s[i+1]); if (j<0) break; dest[written]|=j; ++i; diff --git a/textcode/scan_hexdump_sa.c b/textcode/scan_hexdump_sa.c deleted file mode 100644 index 7ae5bc6..0000000 --- a/textcode/scan_hexdump_sa.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "haveinline.h" - -static inline int fromhex(char c) { - if (c>='0' && c<='9') return c-'0'; - if (c>='A' && c<='F') return c-'A'+10; - if (c>='a' && c<='f') return c-'a'+10; - return -1; -} - -int scan_hexdump_sa(const char *src,stralloc *sa) { - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - for (i=0; s[i]; ++i) { - char dest; - int j=fromhex(s[i]); - if (j<0) break; - dest=j<<4; - j=fromhex(s[i+1]); - if (j<0) break; - dest|=j; - ++i; - if (!stralloc_catb(sa, &dest, 1)) return 0; - } - return 1; -} diff --git a/textcode/scan_html.c b/textcode/scan_html.c index 0860c89..722b3e8 100644 --- a/textcode/scan_html.c +++ b/textcode/scan_html.c @@ -3,7 +3,7 @@ #include "haveinline.h" #include "case.h" -unsigned int scan_html(const char *src,char *dest,unsigned int *destlen) { +unsigned long scan_html(const char *src,char *dest,unsigned long *destlen) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; for (i=0; s[i]; ++i) { diff --git a/textcode/scan_quotedprintable.c b/textcode/scan_quotedprintable.c index 1b30272..23c8a42 100644 --- a/textcode/scan_quotedprintable.c +++ b/textcode/scan_quotedprintable.c @@ -1,23 +1,16 @@ #include "fmt.h" #include "textcode.h" -#include "haveinline.h" +#include "scan.h" -static inline int fromhex(char c) { - if (c>='0' && c<='9') return c-'0'; - if (c>='A' && c<='F') return c-'A'+10; - if (c>='a' && c<='f') return c-'a'+10; - return -1; -} - -unsigned int scan_quotedprintable(const char *src,char *dest,unsigned int *destlen) { +unsigned long scan_quotedprintable(const char *src,char *dest,unsigned long *destlen) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; for (i=0; s[i]; ++i) { if (s[i]=='=') { - int j=fromhex(s[i+1]); + int j=scan_fromhex(s[i+1]); if (j<0) break; dest[written]=j<<4; - j=fromhex(s[i+2]); + j=scan_fromhex(s[i+2]); if (j<0) break; dest[written]|=j; i+=2; diff --git a/textcode/scan_quotedprintable_sa.c b/textcode/scan_quotedprintable_sa.c deleted file mode 100644 index 9782d09..0000000 --- a/textcode/scan_quotedprintable_sa.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "haveinline.h" - -static inline int fromhex(char c) { - if (c>='0' && c<='9') return c-'0'; - if (c>='A' && c<='F') return c-'A'+10; - if (c>='a' && c<='f') return c-'a'+10; - return -1; -} - -int scan_quotedprintable_sa(const char *src,stralloc* sa) { - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - for (i=0; s[i]; ++i) { - if (s[i]=='=') { - char dest; - int j=fromhex(s[i+1]); - if (j<0) break; - dest=j<<4; - j=fromhex(s[i+2]); - if (j<0) break; - dest|=j; - if (!stralloc_catb(sa, &dest, 1)) return 0; - i+=2; - } else { - if (!stralloc_catb(sa, s+i, 1)) return 0; - } - } - return 1; -} diff --git a/textcode/scan_to_array.c b/textcode/scan_to_array.c new file mode 100644 index 0000000..17c662e --- /dev/null +++ b/textcode/scan_to_array.c @@ -0,0 +1,12 @@ +#include "str.h" +#include "array.h" +#include "textcode.h" + +unsigned long scan_to_array(unsigned long (*func)(const char*,char*,unsigned long*), + const char* src,array* dest) { + unsigned long scanned; + unsigned long needed=str_len(src); + char* x=array_start(dest)+array_bytes(dest); + if (!array_allocate(dest,1,array_bytes(dest)+needed-1)) return 0; + return func(src,x,&scanned); +} diff --git a/textcode/scan_to_sa.c b/textcode/scan_to_sa.c new file mode 100644 index 0000000..22898cd --- /dev/null +++ b/textcode/scan_to_sa.c @@ -0,0 +1,13 @@ +#include "str.h" +#include "stralloc.h" +#include "textcode.h" + +unsigned long scan_to_sa(unsigned long (*func)(const char*,char*,unsigned long*), + const char* src,stralloc* sa) { + unsigned long scanned; + unsigned long r; + if (!stralloc_readyplus(sa,str_len(src))) return 0; + if ((r=func(src,sa->s+sa->len,&scanned))) + sa->len+=r; + return r; +} diff --git a/textcode/scan_tofrom_array.c b/textcode/scan_tofrom_array.c new file mode 100644 index 0000000..3f6e393 --- /dev/null +++ b/textcode/scan_tofrom_array.c @@ -0,0 +1,18 @@ +#include "str.h" +#include "array.h" +#include "textcode.h" + +unsigned long scan_tofrom_array(unsigned long (*func)(const char*,char*,unsigned long*), + array* src,array* dest) { + unsigned long scanned; + unsigned long needed; + char* x; + array_cat0(src); + if (array_failed(src) || array_failed(dest)) return 0; + needed=array_bytes(src); + x=array_start(dest)+array_bytes(dest); + if (!array_allocate(dest,1,array_bytes(dest)+needed-1)) return 0; + needed=func(array_start(src),x,&scanned); + array_truncate(src,1,array_bytes(src)-1); + return needed; +} diff --git a/textcode/scan_urlencoded.c b/textcode/scan_urlencoded.c index 5504cf6..830dabe 100644 --- a/textcode/scan_urlencoded.c +++ b/textcode/scan_urlencoded.c @@ -1,23 +1,16 @@ #include "fmt.h" #include "textcode.h" -#include "haveinline.h" +#include "scan.h" -static inline int fromhex(char c) { - if (c>='0' && c<='9') return c-'0'; - if (c>='A' && c<='F') return c-'A'+10; - if (c>='a' && c<='f') return c-'a'+10; - return -1; -} - -unsigned int scan_urlencoded(const char *src,char *dest,unsigned int *destlen) { +unsigned long scan_urlencoded(const char *src,char *dest,unsigned long *destlen) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; for (i=0; s[i]; ++i) { if (s[i]=='%') { - int j=fromhex(s[i+1]); + int j=scan_fromhex(s[i+1]); if (j<0) break; dest[written]=j<<4; - j=fromhex(s[i+2]); + j=scan_fromhex(s[i+2]); if (j<0) break; dest[written]|=j; i+=2; diff --git a/textcode/scan_urlencoded_sa.c b/textcode/scan_urlencoded_sa.c deleted file mode 100644 index 42805a1..0000000 --- a/textcode/scan_urlencoded_sa.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" -#include "haveinline.h" - -static inline int fromhex(char c) { - if (c>='0' && c<='9') return c-'0'; - if (c>='A' && c<='F') return c-'A'+10; - if (c>='a' && c<='f') return c-'a'+10; - return -1; -} - -int scan_urlencoded_sa(const char *src, stralloc *sa) { - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - for (i=0; s[i]; ++i) { - if (s[i]=='%') { - char dest; - int j=fromhex(s[i+1]); - if (j<0) break; - dest=j<<4; - j=fromhex(s[i+2]); - if (j<0) break; - dest|=j; - i+=2; - if (!stralloc_catb(sa, &dest, 1)) return 0; - } else if (s[i]=='+') { - if (!stralloc_catb(sa," ",1)) return 0; - } else - if (!stralloc_catb(sa,s+i,1)) return 0; - } - return 1; -} diff --git a/textcode/scan_uuencoded.c b/textcode/scan_uuencoded.c index c09ae16..04e0197 100644 --- a/textcode/scan_uuencoded.c +++ b/textcode/scan_uuencoded.c @@ -1,6 +1,6 @@ #include "textcode.h" -unsigned int scan_uuencoded(const char *src,char *dest,unsigned int *destlen) { +unsigned long scan_uuencoded(const char *src,char *dest,unsigned long *destlen) { unsigned int len; unsigned long tmp; register const unsigned char* s=(const unsigned char*) src; diff --git a/textcode/scan_uuencoded_sa.c b/textcode/scan_uuencoded_sa.c deleted file mode 100644 index 98202f4..0000000 --- a/textcode/scan_uuencoded_sa.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "stralloc.h" -#include "textcode.h" - -int scan_uuencoded_sa(const char *src,stralloc *sa) { - unsigned int len; - unsigned long tmp; - register const unsigned char* s=(const unsigned char*) src; - if ((len=*s-' ')>64) return 0; len&=63; - ++s; - while (len>0) { - char dest[3]; - unsigned int l=len; - if (s[0]-' '>64 || s[1]-' '>64 || s[2]-' '>64 || s[3]-' '>64) return 0; - tmp=(((s[0]-' ')&077) << (3*6)) + - (((s[1]-' ')&077) << (2*6)) + - (((s[2]-' ')&077) << (1*6)) + - (((s[3]-' ')&077)); - s+=4; - if (len) { dest[0]=tmp>>16; --len; } - if (len) { dest[1]=tmp>>8; --len; } - if (len) { dest[2]=tmp&0xff; --len; } - if (!stralloc_catb(sa,dest,l-len)) return 0; - } - return 1; -} diff --git a/textcode/scan_yenc.c b/textcode/scan_yenc.c index b199f7c..6ee10ca 100644 --- a/textcode/scan_yenc.c +++ b/textcode/scan_yenc.c @@ -1,7 +1,7 @@ #include "fmt.h" #include "textcode.h" -unsigned int scan_yenc(const char *src,char *dest,unsigned int *destlen) { +unsigned long scan_yenc(const char *src,char *dest,unsigned long *destlen) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; for (i=0; s[i]; ++i) { diff --git a/textcode/scan_yenc_sa.c b/textcode/scan_yenc_sa.c deleted file mode 100644 index 068c460..0000000 --- a/textcode/scan_yenc_sa.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "fmt.h" -#include "stralloc.h" -#include "textcode.h" - -int scan_yenc_sa(const char *src,stralloc *sa) { - register const unsigned char* s=(const unsigned char*) src; - unsigned long i; - for (i=0; s[i]; ++i) { - char dest; - if (s[i]=='=') { - ++i; - if (s[i]=='y') break; - dest=s[i]-64-42; - } else if (s[i]=='\n' || s[i]=='\r' || s[i]=='\0') - break; - else - dest=s[i]-42; - if (!stralloc_catb(sa,&dest,1)) return 0; - } - return 1; -}