1/* -*- c -*- 2 * File: pstring.h 3 * Author: Igor Vlasenko <vlasenko@imath.kiev.ua> 4 * Created: Fri Jul 1 20:11:51 2005 5 * 6 * $Id$ 7 */ 8 9#include <stdio.h> 10#include <string.h> 11#include <ctype.h> 12#include "pbuffer.h" 13#include "pstring.h" 14 15static 16PSTRING 17lowercase_pstring (pbuffer* pBuffer ,PSTRING pstring) { 18 const size_t size=pstring.endnext-pstring.begin; 19 char* buf=pbuffer_resize(pBuffer, size+1); 20 char* inbuf=buf; 21 const char* i=pstring.begin; 22 PSTRING retval; 23 while (i<pstring.endnext) { 24 *inbuf++=tolower((unsigned char) *i++); 25 } 26 *inbuf=0; 27 retval.begin=buf; 28 retval.endnext=buf+size; 29 return retval; 30} 31 32/* 33static 34void 35lowercase_pstring_inplace (PSTRING pstring) { 36 char* i=pstring.begin; 37 while (i<pstring.endnext) { 38 *i=tolower(*i); 39 i++; 40 } 41} 42*/ 43 44static 45PSTRING 46uppercase_pstring (pbuffer* pBuffer ,PSTRING pstring) { 47 const size_t size=pstring.endnext-pstring.begin; 48 char* buf=pbuffer_resize(pBuffer, size+1); 49 char* inbuf=buf; 50 const char* i=pstring.begin; 51 PSTRING retval; 52 while (i<pstring.endnext) { 53 *inbuf++=toupper((unsigned char) *i++); 54 } 55 *inbuf=0; 56 retval.begin=buf; 57 retval.endnext=buf+size; 58 return retval; 59} 60 61 62static 63int 64is_pstring_true (PSTRING s) { 65 const size_t len = s.endnext-s.begin; 66 if (s.begin == NULL || 0==len) return 0; 67 if (1==len) { 68 if (*(s.begin)=='0') return 0; else return 1; 69 } else if (3==len) { 70 if ('0'==*(s.begin) && '.'==*(s.begin+1) && '0'==*(s.begin+2)) return 0; else return 1; 71 } else return 1; 72} 73 74#define MAX_ESCAPE_SEQ sizeof(""") 75static 76PSTRING 77htmlencode_pstring (pbuffer* StrBuffer, PSTRING pstring) { 78 char* buf=pbuffer_resize(StrBuffer, pstring.endnext-pstring.begin+1+MAX_ESCAPE_SEQ); 79 const char* curpos=pstring.begin; 80 size_t offset=0; 81 size_t buflen=pbuffer_size(StrBuffer); 82 PSTRING retval; 83 while (curpos<pstring.endnext) { 84 unsigned char curchar=*curpos++; 85 int bufdelta=1; 86 if (offset>=buflen-MAX_ESCAPE_SEQ) { 87 buf=pbuffer_resize(StrBuffer, 2*(offset+MAX_ESCAPE_SEQ)); 88 buflen=pbuffer_size(StrBuffer); 89 } 90 switch (curchar) { 91 /* straight from the CGI.pm bible. (HTML::Template) */ 92 case '&' : bufdelta=5; strncpy(buf+offset, "&", bufdelta);break; 93 case '"' : bufdelta=6; strncpy(buf+offset, """,bufdelta);break; 94 case '>' : bufdelta=4; strncpy(buf+offset, ">", bufdelta);break; 95 case '<' : bufdelta=4; strncpy(buf+offset, "<", bufdelta);break; 96 case '\'': bufdelta=5; strncpy(buf+offset, "'", bufdelta);break; 97 default: *(buf+offset)=curchar; 98 } 99 offset+=bufdelta; 100 } 101 retval.begin=buf; 102 retval.endnext=buf+offset; 103 return retval; 104} 105 106static 107PSTRING 108jsencode_pstring (pbuffer* StrBuffer, PSTRING pstring) { 109 char* buf=pbuffer_resize(StrBuffer, pstring.endnext-pstring.begin+1+MAX_ESCAPE_SEQ); 110 const char* curpos=pstring.begin; 111 size_t offset=0; 112 size_t buflen=pbuffer_size(StrBuffer); 113 PSTRING retval; 114 while (curpos<pstring.endnext) { 115 unsigned char curchar=*curpos++; 116 int bufdelta=1; 117 if (offset>=buflen-MAX_ESCAPE_SEQ) { 118 buf=pbuffer_resize(StrBuffer, 2*(offset+MAX_ESCAPE_SEQ)); 119 buflen=pbuffer_size(StrBuffer); 120 } 121 switch (curchar) { 122 case '\\' : bufdelta=6; strncpy(buf+offset, "\\u005c", bufdelta);break; 123 case '"' : bufdelta=6; strncpy(buf+offset, "\\u0022",bufdelta);break; 124 case '\'' : bufdelta=6; strncpy(buf+offset, "\\u0027",bufdelta);break; 125 case '\n' : bufdelta=6; strncpy(buf+offset, "\\u000a",bufdelta);break; 126 case '\r' : bufdelta=6; strncpy(buf+offset, "\\u000d",bufdelta);break; 127 case '>' : bufdelta=6; strncpy(buf+offset, "\\u003e;", bufdelta);break; 128 case '<' : bufdelta=6; strncpy(buf+offset, "\\u003c;", bufdelta);break; 129 case '&' : bufdelta=6; strncpy(buf+offset, "\\u0026;", bufdelta);break; 130 case '=' : bufdelta=6; strncpy(buf+offset, "\\u003d;", bufdelta);break; 131 case '-' : bufdelta=6; strncpy(buf+offset, "\\u002d;", bufdelta);break; 132 case ';' : bufdelta=6; strncpy(buf+offset, "\\u003b;", bufdelta);break; 133 case '+' : bufdelta=6; strncpy(buf+offset, "\\u002b;", bufdelta);break; 134 default: *(buf+offset)=curchar; 135 } 136 offset+=bufdelta; 137 } 138 retval.begin=buf; 139 retval.endnext=buf+offset; 140 return retval; 141} 142 143static 144PSTRING 145urlencode_pstring (pbuffer* StrBuffer, PSTRING pstring) { 146 char* buf=pbuffer_resize(StrBuffer, pstring.endnext-pstring.begin+1+MAX_ESCAPE_SEQ); 147 const char* curpos=pstring.begin; 148 size_t offset=0; 149 size_t buflen=pbuffer_size(StrBuffer); 150 PSTRING retval; 151 while (curpos<pstring.endnext) { 152 unsigned char curchar=*curpos++; 153 int bufdelta=1; 154 if (offset>=buflen-MAX_ESCAPE_SEQ) { 155 buf=pbuffer_resize(StrBuffer, 2*(offset+MAX_ESCAPE_SEQ)); 156 buflen=pbuffer_size(StrBuffer); 157 } 158 /* 159 * # do the translation (RFC 2396 ^uric) 160 * s!([^a-zA-Z0-9_.\-])!sprintf('%%%02X', $_) 161 */ 162 if ((curchar>='a' && curchar<='z') || 163 (curchar>='A' && curchar<='Z') || 164 (curchar>='0' && curchar<='9') || 165 curchar=='_' || curchar=='.' || curchar=='\\' || curchar=='-' 166 ) 167 *(buf+offset)=curchar; 168 else { 169 bufdelta=3; sprintf(buf+offset,"%%%.2X",(int) curchar); 170 } 171 offset+=bufdelta; 172 } 173 retval.begin=buf; 174 retval.endnext=buf+offset; 175 return retval; 176} 177 178static 179PSTRING 180escape_pstring (pbuffer* strBuffer, PSTRING pstring, const int escapeopt) { 181 switch (escapeopt) { 182 case HTML_TEMPLATE_OPT_ESCAPE_HTML: 183 return htmlencode_pstring(strBuffer, pstring); 184 case HTML_TEMPLATE_OPT_ESCAPE_JS: 185 return jsencode_pstring(strBuffer, pstring); 186 case HTML_TEMPLATE_OPT_ESCAPE_URL: 187 return urlencode_pstring(strBuffer, pstring); 188 default : return pstring; 189 } 190} 191