/* librock/text/html.c librock_CHISEL _summary String encoding and decoding useful in HTML and HTTP Copyright (c) 2001-2002, Forrest J. Cavalier III, doing business as Mib Software, Saylorsburg Pennsylvania USA Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /**************************************************************/ #ifdef librock_NOTLIBROCK /* ABOUT THIS FILE: GUIDE TO QUICK REUSE WITHOUT REWORK This file uses many preprocessor conditional blocks and features to publish http://www.mibsoftware.com/librock/ You can disable those features with little or no editing, and reuse this file: 1. At compile time, enable this conditional block by defining the preprocessor symbol librock_NOTLIBROCK, either with a compiler command line parameter, or as a #define in a source file which then #includes this source file. 2. Define any preprocessor symbols in this block (if any) appropriately for your machine and compilation environment. 3. Copy and use the declarations from this block in your source files as appropriate. This file is originally from the librock library, which is Free (libre), free (no cost), rock-stable API, and works on gcc/MSVC/Windows/Linux/BSD/more. Get originals, updates, license certificates, more, at http://www.mibsoftware.com/librock/ (Change log appears at end of this file.) */ #define librock_PTR #define librock_CONST const #define librock_PRIVATE static char *librock_HTML_astrcatEntityEncode(char * *ppasz,const char *text,int len); char *librock_HTML_astrcatEntityDecode(char * *ppasz,const char *textHTML,int len); char *librock_HTML_astrcatValueEncode(char * *ppasz,const char *pString,int cbString); char *librock_HTTP_astrcatUrlEncode(char **ppasz,const char *pString,int cbString); char *librock_HTTP_astrcpyFieldFromUrlEncode(char * *ppasz,const char *pszName,const char *pszQuerystring); char *librock_HTTP_astrSetFieldUrlEncode(char * *ppaszQueryString,const char *pszName,const char *pszValue); #endif /* ifdef librock_NOTLIBROCK */ /**************************************************************/ #ifndef librock_ISOLATED /**************************************************************/ #define librock_IMPLEMENT_html #ifndef librock_NOTLIBROCK #include #include #include #include #endif #include #include #include #include /**************************************************************/ #endif #ifdef librock_IMPL_LIDESC #ifndef librock_NOIMPL_LIDESC_html /**************************************************************/ #include /* librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ void *librock_LIDESC_html[] = { "\n" __FILE__ librock_LIDESC_librock "\n", 0 }; /**************************************************************/ #endif #endif #ifndef librock_WRAP /**************************************************************/ #define librock_body_HTML_astrcatEntityEncode librock_HTML_astrcatEntityEncode #define librock_body_HTML_astrcatEntityDecode librock_HTML_astrcatEntityDecode #define librock_body_HTML_astrcatValueEncode librock_HTML_astrcatValueEncode #define librock_body_HTTP_astrcatUrlEncode librock_HTTP_astrcatUrlEncode #define librock_body_HTTP_astrcpyFieldFromUrlEncode librock_HTTP_astrcpyFieldFromUrlEncode #define librock_body_HTTP_astrSetFieldUrlEncode librock_HTTP_astrSetFieldUrlEncode /**************************************************************/ #endif #ifndef librock_NOIMPL_HTML_astrcatEntityEncode #define librock_FNTYPE_HTML_astrcatEntityEncode fns_a_s_i /**************************************************************/ char librock_PTR *librock_body_HTML_astrcatEntityEncode(char librock_PTR * librock_PTR *ppasz,librock_CONST char *text,int len) { /*Copyright 1998-2000, Forrest J. Cavalier III d-b-a Mib Software Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License, originals, details: http://www.mibsoftware.com/librock/ */ #ifdef librock_MANUAL_HTML_astrcatEntityEncode /* librock_HTML_astrcatEntityEncode - append to a librock_astring, encoding HTML character entities (like <,>,&) librock_HTML_astrcatEntityDecode - append to a librock_astring, decoding HTML character entities (like ><) */ /**/ #include char * librock_HTML_astrcatEntityEncode /* append to a librock_astring, encoding HTML character entities (like <,>,&) */ ( char **ppaszHTML, // append to this destination const char *pText, // source. Plain text. int cbText // max octets at pText ); // returns *ppaszHTML /**/ #ifdef librock_TYPICAL_USE_HTML_astrcatEntityEncode /* Prepare plain text for HTML output */ char *aszHTML = 0; char *pText = "Show "; librock_HTML_astrcatEntityEncode(&aszHTML, /* (char **) */ pText, /* (const char *) */ strlen(pText)); /* (int) */ if (!aszHTML) return "E-0-astring memory allocation error"; printf("%s\n",aszHTML); #endif char * librock_HTML_astrcatEntityDecode( char **ppasz, // append to this destination const char *textHTML, // Source, HTML int cbTextHTML // max octets at textHTML ); // returns *ppasz /* Operation is similar to librock_astrcat(), with translations to or from HTML Entity Encoded. Returns *ppasz. Typical use is to prepare plain text for HTML output, or read HTML input. */ #ifdef librock_TYPICAL_USE_HTML_astrcatEntityEncode char *asz = 0; char *ptr = "Show "; librock_HTML_astrcatEntityEncode(&asz,ptr,strlen(ptr)); printf("%s\n", asz); #endif /* strlen() strcpy() librock_CHISEL _usesrc "text/astring.c" librock_astrensure() librock_astrcat() */ /* Copyright 1998-2002 Forrest J. Cavalier III, http://www.mibsoftware.com Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ #endif /* MANUAL */ /*-------------------------------------------*/ char buf[20]; int ensure = 0; int i = 0; const char *ptr = text; if (*ppasz) { i = strlen(*ppasz); } while((len > 0)||((len == -1)&&*ptr)) { if (i+1 >= ensure) { ensure = i+256; } librock_astrensure(ppasz,ensure); if (!*ppasz) { return *ppasz; } if (*ptr == '<') { librock_astrcat(ppasz,"<"); ptr++; } else if (*ptr == '>') { librock_astrcat(ppasz,">"); ptr++; } else if (*ptr == '&') { librock_astrcat(ppasz,"&"); ptr++; #if 0 /* RFC1866 doesn't require encoding this */ } else if (*ptr == '\"') { librock_astrcat(ppasz,"""); ptr++; #endif } else if (*ptr & 0x80) { /* 9-12-96 Take a shot at Entity-Encoding these */ if ((*ptr&0xff) == 241) { /* 9-12-96 */ librock_astrcat(ppasz,"ñ"); ptr++; } else if ((*ptr&0xff) == 225) { /* 9-12-96 */ librock_astrcat(ppasz,"á"); ptr++; } else if ((*ptr&0xff) == 233) { /* 9-12-96 */ librock_astrcat(ppasz,"é"); ptr++; } else if ((*ptr&0xff) == 237) { /* 9-12-96 */ librock_astrcat(ppasz,"í"); ptr++; } else if ((*ptr&0xff) == 243) { /* 9-12-96 */ librock_astrcat(ppasz,"ó"); ptr++; } else if ((*ptr&0xff) == 250) { /* 9-12-96 */ librock_astrcat(ppasz,"ú"); ptr++; } else { strcpy(buf,"&#"); if ((*ptr & 0xff) >= 100) { buf[2] = '0' + (*ptr & 0xff) / 100; buf[3] = '0' + (((*ptr & 0xff) / 10)%10); buf[4] = '0' + (((*ptr & 0xff) / 1)%10); buf[5] = 0; } else if((*ptr & 0xff) >= 10) { buf[2] = '0' + (((*ptr & 0xff) / 10)%10); buf[3] = '0' + (((*ptr & 0xff) / 1)%10); buf[4] = 0; } else { buf[2] = '0' + (((*ptr & 0xff) / 1)%10); buf[3] = 0; } librock_astrcat(ppasz,buf); ptr++; } } else { (*ppasz)[i++] = *ptr++; (*ppasz)[i] = '\0'; } i += strlen(*ppasz+i); if (len > 0) { len--; } } return *ppasz; } /**************************************************************/ #endif /* NOIMP */ #ifndef librock_NOIMPL_HTML_astrcatEntityDecode #define librock_FNTYPE_HTML_astrcatEntityDecode fns_a_s_i /**************************************************************/ char librock_PTR * librock_body_HTML_astrcatEntityDecode(char librock_PTR * librock_PTR *ppasz,librock_CONST char librock_PTR *textHTML,int len) { /*Copyright 1998-2000, Forrest J. Cavalier III d-b-a Mib Software Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License, originals, details: http://www.mibsoftware.com/librock/ */ int ensure = 0; int i = 0; const char *ptr = textHTML; if (*ppasz) { i = strlen(*ppasz); } while(*ptr && (ptr < textHTML + len)) { if (i+1 >= ensure) { ensure = i+256; } librock_astrensure(ppasz,ensure); if (!*ppasz) { return *ppasz; } if (*ptr == '&') { if (!strncmp(ptr,"<",3)) { librock_astrcat(ppasz,"<"); ptr += 3; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,">",3)) { librock_astrcat(ppasz,">"); ptr += 3; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,"&",4)) { librock_astrcat(ppasz,"&"); ptr += 4; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,""",5)) { librock_astrcat(ppasz,"\""); ptr += 5; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,"ñ",7)) { librock_astrcat(ppasz,"\xf1"); ptr += 7; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,"á",7)) { librock_astrcat(ppasz,"\xe1"); ptr += 7; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,"é",7)) { librock_astrcat(ppasz,"\xe9"); ptr += 7; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,"í",7)) { librock_astrcat(ppasz,"\xed"); ptr += 7; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,"ó",7)) { librock_astrcat(ppasz,"\xf3"); ptr += 7; if (*ptr == ';') { ptr++; } } else if (!strncmp(ptr,"ú",7)) { librock_astrcat(ppasz,"\xfa"); ptr += 7; if (*ptr == ';') { ptr++; } } else if ((ptr[0]=='&')&&(ptr[1]=='#')) { /* 9-12-96 Take a shot at it */ char ch = atoi(ptr+2); librock_astrn0cat(ppasz,&ch,1); ptr += 2; while((*ptr >= '0')&&(*ptr <= '9')) { ptr++; } } else { /* Just a bare ampersand */ librock_astrn0cat(ppasz,ptr,1); ptr++; } i += strlen(*ppasz+i); } else { (*ppasz)[i++] = *ptr++; (*ppasz)[i] = '\0'; } } return *ppasz; } /**************************************************************/ #endif /* NOIMP */ /**************************************************************/ #ifndef librock_NOIMPL_aschex2nib librock_PRIVATE int aschex2nib(char ch) { if (ch > '9') { return (ch & 0x0f)+9; } return ch & 0x0f; } #endif #ifndef librock_NOIMPL_nib2aschex librock_PRIVATE int nib2aschex(int n) { if ((n&0x0f) > 9) { return ((n&0x0f) - 10)+'A'; } return (n&0x0f)+'0'; } #endif #ifndef librock_NOIMPL_HTML_astrcatValueEncode /**************************************************************/ #define librock_FNTYPE_HTML_astrcatValueEncode fns_a_s_i char librock_PTR *librock_body_HTML_astrcatValueEncode(char librock_PTR * librock_PTR *ppasz,librock_CONST char librock_PTR *pString,int cbString) { /* 2/22/2000 */ /*Copyright 1998-2000, Forrest J. Cavalier III d-b-a Mib Software Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License, originals, details: http://www.mibsoftware.com/librock/ */ #ifdef librock_MANUAL_HTML_astrcatValueEncode /* librock_HTML_astrcatValueEncode - Encode special characters within an HTML attribute value. */ /**/ #include char * librock_HTML_astrcatValueEncode( char **ppasz, /* librock_astring */ const char *pString,int cbString) /* Perform encoding of characters so that the item can appear as the value within an HTML attribute. Per RFC 1866 3.2.4 This '&#-encodes' \t \r \n & " It does not encode ' ' or '%' Returns *ppasz. Typical use is */ #ifdef librock_TYPICAL_USE_HTML_astrcatValueEncode char *asz = 0; printf("\n", librock_HTML_astrcatValueEncode(&asz,"\"%&\"",4)); librock_astrfree(&asz); #endif /* sprintf() strlen() strchr() librock_CHISEL _usesrc "text/astring.c" librock_astrn0cat() */ /* Copyright 1998-2002 Forrest J. Cavalier III, http://www.mibsoftware.com Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ #endif /* MANUAL */ /*-------------------------------------------*/ char buf[64]; int ind = 0; while((cbString > 0)) { if (!*pString || strchr("\t\r\n&\"",*pString)) { buf[ind++] = '&'; buf[ind++] = '#'; sprintf(buf+ind,"%d",*pString); ind += strlen(buf+ind); buf[ind++] = ';'; } else { buf[ind++] = *pString; } if (ind >= sizeof(buf)-6) { librock_astrn0cat(ppasz,buf,ind); ind = 0; } pString++; cbString--; } if (ind) { librock_astrn0cat(ppasz,buf,ind); } return *ppasz; } /* HTML_astrcatValueEncode */ /**************************************************************/ #endif /* NOIMP */ #ifndef librock_NOIMPL_HTTP_astrcatUrlEncode #define librock_FNTYPE_HTTP_astrcatUrlEncode fns_a_s_i /**************************************************************/ char *librock_body_HTTP_astrcatUrlEncode(char **ppasz,const char *pString,int cbString) { /* 3/23/99 */ /*Copyright 1998-2000, Forrest J. Cavalier III d-b-a Mib Software Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License, originals, details: http://www.mibsoftware.com/librock/ */ #ifdef librock_MANUAL_HTTP_astrcatUrlEncode /* librock_HTTP_astrcatUrlEncode - Encode special characters to create a safe URL string, per RFC1630 */ /**/ #include char * librock_HTTP_astrcatUrlEncode( char **ppasz, /* librock_astring */ const char *pString,int cbString) /* Perform encoding of characters so that "unsafe" characters as per RFC 1630 can appear within an HTTP request This passes alphanumerics, encodes ' ' as '+' and '%-encodes' everything else. If you want '/' to appear literally, then handle it separately as in the example use below. Returns *ppasz. Typical use is */ #ifdef librock_TYPICAL_USE_HTTP_astrcatUrlEncode char *asz = 0; librock_astrcat(&asz,"/"); librock_HTTP_astrcatUrlEncode(&asz,"path",4); librock_astrcat(&asz,"/"); librock_HTTP_astrcatUrlEncode(&asz,"to resource",11); printf("GET %s HTTP/1.0\n",asz); librock_astrfree(&asz); #endif /* To construct a URL encoded Query String, see librock_HTTP_SetFieldUrlEncoded, or use code similar to the following: */ #ifdef librock_TYPICAL_USE_2_HTTP_astrcatUrlEncode char *asz = 0; librock_HTTP_astrcatUrlEncode(&asz,"field name",10); librock_astrcat(&asz,"="); librock_HTTP_astrcatUrlEncode(&asz,"/field value/",13); librock_astrcat(&asz,"&"); librock_HTTP_astrcatUrlEncode(&asz,"field name 2",12); librock_astrcat(&asz,"="); librock_HTTP_astrcatUrlEncode(&asz,"/field value 2/",15); printf("GET /query.cgi?%s HTTP/1.0\n",asz); librock_astrfree(&asz); #endif /* If you want to construct a URL-encoded Query String for placing inside an HREF attribute, then build up the query string, then use librock_astrcatValueEncode. (If you have difficulty thinking of the order, remember that any encoding must be done in the reverse order it will be decoded. The browser will decode the value first, so that means value encoding must be done last.) Code is similar to the following: */ #ifdef librock_TYPICAL_USE_3_HTTP_astrcatUrlEncode char *asz = 0; char *asz2 = 0; librock_HTTP_astrcatUrlEncode(&asz,"field",5); librock_astrcat(&asz,"="); librock_HTTP_astrcatUrlEncode(&asz,"value",5); librock_astrcat(&asz,"&"); librock_HTTP_astrcatUrlEncode(&asz,"field",5); librock_astrcat(&asz,"="); librock_HTTP_astrcatUrlEncode(&asz,"value",5); librock_HTML_astrcatValueEncode(&asz2,asz,strlen(asz)); printf("\n",asz2); librock_astrfree(&asz); librock_astrfree(&asz2); #endif /* See also librock_HTTP_astrSetFieldUrlEncode(), if field names are unique in the query string. */ /* isalnum() librock_chisel _usesrc "text/astring.c" librock_astrn0cat() */ /* Copyright 1998-2002 Forrest J. Cavalier III, http://www.mibsoftware.com Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ #endif /* MANUAL */ /*-------------------------------------------*/ char buf[64]; int ind = 0; while((cbString > 0)) { if (isalnum(*pString)) { buf[ind++] = *pString; } else if (*pString == ' ') { buf[ind++] = '+'; } else { buf[ind++] = '%'; buf[ind++] = nib2aschex((*pString>>4)&0x0f); buf[ind++] = nib2aschex(*pString&0x0f); } if (ind >= sizeof(buf)-4) { librock_astrn0cat(ppasz,buf,ind); ind = 0; } pString++; cbString--; } if (ind) { librock_astrn0cat(ppasz,buf,ind); } return *ppasz; } /* HTTP_astrcatUrlEncode */ /**************************************************************/ #endif /* NOIMP */ #ifndef librock_NOIMPL_HTTP_astrcpyFieldFromUrlEncode #define librock_FNTYPE_HTTP_astrcpyFieldFromUrlEncode fns_A_s_s /**************************************************************/ char librock_PTR *librock_body_HTTP_astrcpyFieldFromUrlEncode(char librock_PTR * librock_PTR *ppasz,librock_CONST char librock_PTR *pszName,librock_CONST char librock_PTR *pszQuerystring) { /*Copyright 1998-2000, Forrest J. Cavalier III d-b-a Mib Software Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License, originals, details: http://www.mibsoftware.com/librock/ */ #ifdef librock_MANUAL_HTTP_astrcpyFieldFromUrlEncode /* librock_HTTP_astrcpyFieldFromUrlEncode - Extract a field value from a URL-Encoded query-string */ /**/ #include char * librock_HTTP_astrcpyFieldFromUrlEncode( char **ppasz, const char *pszFieldName, const char *pszQuerystring ); /* Returns a decoded value for the first named field matching @pszFieldName. Returns a pointer to the name in pszQueryString. (See below for how to extract fields of identical names.) If @pszFieldName is 0, the first part of @pszQueryString is processed, and the string stored at @*ppasz is of the form 'name=value'. The return value points to the next part of @pszQueryString or is 0. Typical use is to obtain values from HTTP form submissions and query strings. */ #ifdef librock_TYPICAL_USE_HTTP_astrcpyFieldFromUrlEncode char *asz = 0; librock_HTTP_astrcpyFieldFromUrlEncode(&asz, "file","name=value&%66ile=a+test"); printf("Query had file='%s'\n",asz); librock_astrfree(&asz); #endif /* When the query string might have a field encoded multiple times, use code such as the following. Note the use of @p+1 on subsequent calls. */ #ifdef librock_TYPICAL_USE_2_HTTP_astrcpyFieldFromUrlEncode char *aszValue = 0; const char *p; if (p = librock_HTTP_astrcpyFieldFromUrlEncode(&aszValue,"file","name=value&%66ile=a+test&file=another+test")) { /* Append all */ char *asz = 0; while (p = librock_HTTP_astrcpyFieldFromUrlEncode(&asz,"file",p+1)) { librock_astrcat(&aszValue,","); librock_astrcat(&aszValue,asz); } librock_astrfree(&asz); } printf("file(s)=%s\n",aszValue); librock_astrfree(&aszValue); #endif /* To iterate all values of the query string, use code similar to the following. */ #ifdef librock_TYPICAL_USE_3_HTTP_astrcpyFieldFromUrlEncode char *aszNameValue = 0; const char *p = "field1=test&field2=test2&file=a&file=b"; while(p) { p = librock_HTTP_astrcpyFieldFromUrlEncode(&aszNameValue,0,p); if (p) { printf("%s\n",aszNameValue); } } librock_astrfree(&aszNameValue); #endif /* strlen() strncmp() strchr() librock_CHISEL _usesrc "text/count.c" librock_counttoch() librock_CHISEL _usesrc "text/astring.c" librock_astrensure() librock_astrfree() */ /* Copyright 1998-2002 Forrest J. Cavalier III, http://www.mibsoftware.com Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ #endif /* MANUAL */ /*-------------------------------------------*/ /* As of 7/7/99, returns pointer to pszQueryString to allow for additional parsing of duplicated field values */ /* as of 11/12/2001, passing in NULL for name will return the decoded name=value pair. */ const char *ptr = pszQuerystring; const char *pRet = 0; int ind; int ensure; const char *endptr; if (!pszName) { pRet = ptr + librock_counttoch(ptr,'&'); if (*pRet) { pRet++; } else { /* pRet = 0; No. Want to return *pRet == 0, or we will fool caller */ if (*ptr == '\0') { return 0; } } } else { int cbName = strlen(pszName); while(ptr) { int i = 0; while(1) { /* 2001-07-23 Name may be %encoded as well */ char ch; if (((*ptr == '=')||(*ptr == '&')||!*ptr)&&(i == cbName)) { break; /* Match */ } if (*ptr == '%') { ch = (aschex2nib(ptr[1])<<4) | aschex2nib(ptr[2]); ptr += 3; } else { ch = *ptr; ptr++; } if (ch != pszName[i]) { i = 0; break; } i++; } if (i == cbName) { break; /* Match */ } ptr = strchr(ptr,'&'); if (ptr) { ptr++; } } if (!ptr) { librock_astrfree(ppasz); return 0; } pRet = ptr; if (*ptr) { ptr++; } } /* Process until end of string, or get another '&' */ ind = 0; ensure = 64; librock_astrensure(ppasz,ensure); endptr = ptr + librock_counttoch(ptr,'&'); while(ptr < endptr) { if (ind+1 > ensure) { ensure += 64; if (!librock_astrensure(ppasz,ensure)) { return 0; } } if (*ptr == '+') { (*ppasz)[ind++] = ' '; ptr++; } else if (*ptr == '%') { (*ppasz)[ind++] = (aschex2nib(ptr[1])<<4) | aschex2nib(ptr[2]); ptr += 3; } else { (*ppasz)[ind++] = *ptr++; } } (*ppasz)[ind] = 0; return (char *) pRet; } /* HTTP_astrcpyFieldFromUrlEncode */ /**************************************************************/ #endif /* NOIMP */ #ifndef librock_NOIMPL_HTTP_astrSetFieldUrlEncode #define librock_FNTYPE_HTTP_astrSetFieldUrlEncode fns_a_s_s /**************************************************************/ char librock_PTR *librock_body_HTTP_astrSetFieldUrlEncode(char librock_PTR * librock_PTR *ppaszQueryString,const char librock_PTR *pszName,const char librock_PTR *pszValue) { /*Copyright 1998-2000, Forrest J. Cavalier III d-b-a Mib Software Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License, originals, details: http://www.mibsoftware.com/librock/ */ #ifdef librock_MANUAL_HTTP_astrSetFieldUrlEncode /* librock_HTTP_astrSetFieldUrlEncode - replace the value for a field in an URL-encoded query string */ /**/ #include char * librock_HTTP_astrSetFieldUrlEncode( char **ppaszQueryString, const char *pszName, const char *pszValue ); /* Locate the first occurrence of the named field in the encoded query string, and replace the value. If does not occur, append to the query string. Returns *ppasz. To determine if URL-encoding or Value-Encoding is more appropriate consider what will be decoding the string first. There is no way to ValueEncode a '&' in an anchor HREF hyperlink. (See the note in RFC1866 8.2.1. Any '&' will be taken as a field separator.) Using & works usually. Typical use is to modify an existing query string, or build one up from scratch. If field names are duplicated, use librock_HTTP_astrcatUrlEncode. This function will only modify the first matching field name. */ #ifdef librock_TYPICAL_USE_HTTP_astrSetFieldUrlEncode char *asz = 0; librock_astrcpy(&asz,"file=some+value&file=not+replaced+value"); librock_HTTP_astrSetFieldUrlEncode(&asz,"file","index.html"); printf("%s\n",asz); librock_astrfree(&asz); #endif /* strlen() strncmp() strchr() librock_HTTP_astrcatUrlEncode() librock_CHISEL _usesrc "text/astring.c" librock_astrcat() librock_astrn0cpy() librock_astrfree() librock_CHISEL _usesrc "text/count.c" librock_counttoch() */ /* Copyright 1998-2002 Forrest J. Cavalier III, http://www.mibsoftware.com Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ #endif /* MANUAL */ /*-------------------------------------------*/ const char *ptr = *ppaszQueryString; char *asz = 0; int cbName = strlen(pszName); const char *endptr; while(ptr) { int i = 0; while(1) { /* 2001-07-30 Name may be %encoded as well */ char ch; if (((*ptr == '=')||(*ptr == '&')||!*ptr)&&(i == cbName)) { break; /* Match */ } if (*ptr == '%') { ch = (aschex2nib(ptr[1])<<4) | aschex2nib(ptr[2]); ptr += 3; } else { ch = *ptr; ptr++; } if (ch != pszName[i]) { i = 0; break; } i++; } if (i == cbName) { break; /* Match */ } ptr = strchr(ptr,'&'); if (ptr) { ptr++; } } if (!ptr) { /* No match. Append */ librock_astrcat(ppaszQueryString,"&"); librock_HTTP_astrcatUrlEncode(ppaszQueryString,pszName,strlen(pszName)); librock_astrcat(ppaszQueryString,"="); librock_HTTP_astrcatUrlEncode(ppaszQueryString,pszValue,strlen(pszValue)); return *ppaszQueryString; } endptr = ptr + librock_counttoch(ptr,'&'); librock_astrn0cpy(&asz,*ppaszQueryString,ptr-*ppaszQueryString); if (*ptr) { ptr++; } librock_astrcat(&asz,"="); librock_HTTP_astrcatUrlEncode(&asz,pszValue,strlen(pszValue)); librock_astrcat(&asz,endptr); librock_astrfree(ppaszQueryString); *ppaszQueryString = asz; return asz; } /* librock_HTTP_astrSetFieldUrlEncode */ /**************************************************************/ #endif /* NOIMP */ /* $Log: html.c,v $ Revision 1.6 2002/08/01 16:41:38 forrest@mibsoftware.com rights=#1 Updated TYPICAL_USE sections. Added NOTLIBROCK section. Moved CVS log to end. Changed LIDESC MD5 to HC. Revision 1.5 2002/04/19 14:58:18 forrest@mibsoftware.com rights=#1 Manual page example correction. Revision 1.4 2002/04/09 03:23:30 forrest@mibsoftware.com rights=#1 FNTYPE decls. Update LICENSE section in manual. Revision 1.3 2002/02/09 16:34:45 forrest@mibsoftware.com rights=#1 Standardized chg log Revision 1.2 2002/01/30 16:08:18 forrest@mibsoftware.com rights=#1 Renamed some .h files Revision 1.1 2002/01/29 14:25:05 forrest@mibsoftware.com rights=#1 initial rights#1 Copyright (c) Forrest J Cavalier III d-b-a Mib Software rights#1 License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */