/* 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
*/