File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpd / miniupnpc-async / minixml.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:25:11 2023 UTC (13 months ago) by misho
Branches: miniupnpd, MAIN
CVS tags: v2_3_3p0, HEAD
Version 2.3.3p0

    1: /* $Id: minixml.c,v 1.1.1.1 2023/09/27 11:25:11 misho Exp $ */
    2: /* vim: tabstop=4 shiftwidth=4 noexpandtab
    3:  * minixml.c : the minimum size a xml parser can be ! */
    4: /* Project : miniupnp
    5:  * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    6:  * Author : Thomas Bernard
    7: 
    8: Copyright (c) 2005-2017, Thomas BERNARD
    9: All rights reserved.
   10: 
   11: Redistribution and use in source and binary forms, with or without
   12: modification, are permitted provided that the following conditions are met:
   13: 
   14:     * Redistributions of source code must retain the above copyright notice,
   15:       this list of conditions and the following disclaimer.
   16:     * Redistributions in binary form must reproduce the above copyright notice,
   17:       this list of conditions and the following disclaimer in the documentation
   18:       and/or other materials provided with the distribution.
   19:     * The name of the author may not be used to endorse or promote products
   20: 	  derived from this software without specific prior written permission.
   21: 
   22: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   23: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   26: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   27: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   28: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   29: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   30: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   31: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32: POSSIBILITY OF SUCH DAMAGE.
   33: */
   34: #include <string.h>
   35: #include "minixml.h"
   36: 
   37: /* parseatt : used to parse the argument list
   38:  * return 0 (false) in case of success and -1 (true) if the end
   39:  * of the xmlbuffer is reached. */
   40: static int parseatt(struct xmlparser * p)
   41: {
   42: 	const char * attname;
   43: 	int attnamelen;
   44: 	const char * attvalue;
   45: 	int attvaluelen;
   46: 	while(p->xml < p->xmlend)
   47: 	{
   48: 		if(*p->xml=='/' || *p->xml=='>')
   49: 			return 0;
   50: 		if( !IS_WHITE_SPACE(*p->xml) )
   51: 		{
   52: 			char sep;
   53: 			attname = p->xml;
   54: 			attnamelen = 0;
   55: 			while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
   56: 			{
   57: 				attnamelen++; p->xml++;
   58: 				if(p->xml >= p->xmlend)
   59: 					return -1;
   60: 			}
   61: 			while(*(p->xml++) != '=')
   62: 			{
   63: 				if(p->xml >= p->xmlend)
   64: 					return -1;
   65: 			}
   66: 			while(IS_WHITE_SPACE(*p->xml))
   67: 			{
   68: 				p->xml++;
   69: 				if(p->xml >= p->xmlend)
   70: 					return -1;
   71: 			}
   72: 			sep = *p->xml;
   73: 			if(sep=='\'' || sep=='\"')
   74: 			{
   75: 				p->xml++;
   76: 				if(p->xml >= p->xmlend)
   77: 					return -1;
   78: 				attvalue = p->xml;
   79: 				attvaluelen = 0;
   80: 				while(*p->xml != sep)
   81: 				{
   82: 					attvaluelen++; p->xml++;
   83: 					if(p->xml >= p->xmlend)
   84: 						return -1;
   85: 				}
   86: 			}
   87: 			else
   88: 			{
   89: 				attvalue = p->xml;
   90: 				attvaluelen = 0;
   91: 				while(   !IS_WHITE_SPACE(*p->xml)
   92: 					  && *p->xml != '>' && *p->xml != '/')
   93: 				{
   94: 					attvaluelen++; p->xml++;
   95: 					if(p->xml >= p->xmlend)
   96: 						return -1;
   97: 				}
   98: 			}
   99: 			/*printf("%.*s='%.*s'\n",
  100: 			       attnamelen, attname, attvaluelen, attvalue);*/
  101: 			if(p->attfunc)
  102: 				p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
  103: 		}
  104: 		p->xml++;
  105: 	}
  106: 	return -1;
  107: }
  108: 
  109: /* parseelt parse the xml stream and
  110:  * call the callback functions when needed... */
  111: static void parseelt(struct xmlparser * p)
  112: {
  113: 	int i;
  114: 	const char * elementname;
  115: 	while(p->xml < (p->xmlend - 1))
  116: 	{
  117: 		if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "<!--", 4)))
  118: 		{
  119: 			p->xml += 3;
  120: 			/* ignore comments */
  121: 			do
  122: 			{
  123: 				p->xml++;
  124: 				if ((p->xml + 3) >= p->xmlend)
  125: 					return;
  126: 			}
  127: 			while(memcmp(p->xml, "-->", 3) != 0);
  128: 			p->xml += 3;
  129: 		}
  130: 		else if((p->xml)[0]=='<' && (p->xml)[1]!='?')
  131: 		{
  132: 			i = 0; elementname = ++p->xml;
  133: 			while( !IS_WHITE_SPACE(*p->xml)
  134: 				  && (*p->xml!='>') && (*p->xml!='/')
  135: 				 )
  136: 			{
  137: 				i++; p->xml++;
  138: 				if (p->xml >= p->xmlend)
  139: 					return;
  140: 				/* to ignore namespace : */
  141: 				if(*p->xml==':')
  142: 				{
  143: 					i = 0;
  144: 					elementname = ++p->xml;
  145: 				}
  146: 			}
  147: 			if(i>0)
  148: 			{
  149: 				if(p->starteltfunc)
  150: 					p->starteltfunc(p->data, elementname, i);
  151: 				if(parseatt(p))
  152: 					return;
  153: 				if(*p->xml!='/')
  154: 				{
  155: 					const char * data;
  156: 					i = 0; data = ++p->xml;
  157: 					if (p->xml >= p->xmlend)
  158: 						return;
  159: 					while( IS_WHITE_SPACE(*p->xml) )
  160: 					{
  161: 						i++; p->xml++;
  162: 						if (p->xml >= p->xmlend)
  163: 							return;
  164: 					}
  165: 					/* CDATA are at least 9 + 3 characters long : <![CDATA[ ]]> */
  166: 					if((p->xmlend >= (p->xml + (9 + 3))) && (memcmp(p->xml, "<![CDATA[", 9) == 0))
  167: 					{
  168: 						/* CDATA handling */
  169: 						p->xml += 9;
  170: 						data = p->xml;
  171: 						i = 0;
  172: 						while(memcmp(p->xml, "]]>", 3) != 0)
  173: 						{
  174: 							i++; p->xml++;
  175: 							if ((p->xml + 3) >= p->xmlend)
  176: 								return;
  177: 						}
  178: 						if(i>0 && p->datafunc)
  179: 							p->datafunc(p->data, data, i);
  180: 						while(*p->xml!='<')
  181: 						{
  182: 							p->xml++;
  183: 							if (p->xml >= p->xmlend)
  184: 								return;
  185: 						}
  186: 					}
  187: 					else
  188: 					{
  189: 						while(*p->xml!='<')
  190: 						{
  191: 							i++; p->xml++;
  192: 							if ((p->xml + 1) >= p->xmlend)
  193: 								return;
  194: 						}
  195: 						if(i>0 && p->datafunc && *(p->xml + 1) == '/')
  196: 							p->datafunc(p->data, data, i);
  197: 					}
  198: 				}
  199: 			}
  200: 			else if(*p->xml == '/')
  201: 			{
  202: 				i = 0; elementname = ++p->xml;
  203: 				if (p->xml >= p->xmlend)
  204: 					return;
  205: 				while((*p->xml != '>'))
  206: 				{
  207: 					i++; p->xml++;
  208: 					if (p->xml >= p->xmlend)
  209: 						return;
  210: 				}
  211: 				if(p->endeltfunc)
  212: 					p->endeltfunc(p->data, elementname, i);
  213: 				p->xml++;
  214: 			}
  215: 		}
  216: 		else
  217: 		{
  218: 			p->xml++;
  219: 		}
  220: 	}
  221: }
  222: 
  223: /* the parser must be initialized before calling this function */
  224: void parsexml(struct xmlparser * parser)
  225: {
  226: 	parser->xml = parser->xmlstart;
  227: 	parser->xmlend = parser->xmlstart + parser->xmlsize;
  228: 	parseelt(parser);
  229: }
  230: 
  231: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>