added xmlSchemaNewMemParserCtxt to parse a schemas from a memory area

* xmlschemas.c include/libxml/xmlschemas.h: added
  xmlSchemaNewMemParserCtxt to parse a schemas from a memory area
* testSchemas.c: added --memory to test the new interface
Daniel
diff --git a/ChangeLog b/ChangeLog
index f2cd807..5e5883f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Oct  9 23:11:02 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xmlschemas.c include/libxml/xmlschemas.h: added
+	  xmlSchemaNewMemParserCtxt to parse a schemas from a memory area
+	* testSchemas.c: added --memory to test the new interface
+
 Wed Oct  9 16:22:54 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
 	* doc/index.py doc/search.php: integrated the XSLT indexing,
diff --git a/include/libxml/xmlschemas.h b/include/libxml/xmlschemas.h
index 6616c29..6a9a26f 100644
--- a/include/libxml/xmlschemas.h
+++ b/include/libxml/xmlschemas.h
@@ -73,7 +73,9 @@
 /*
  * Interfaces for parsing.
  */
-xmlSchemaParserCtxtPtr xmlSchemaNewParserCtxt(const char *URL);
+xmlSchemaParserCtxtPtr xmlSchemaNewParserCtxt	(const char *URL);
+xmlSchemaParserCtxtPtr xmlSchemaNewMemParserCtxt(const char *buffer,
+						 int size);
 void		xmlSchemaFreeParserCtxt	(xmlSchemaParserCtxtPtr ctxt);
 void		xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
 					 xmlSchemaValidityErrorFunc err,
diff --git a/testSchemas.c b/testSchemas.c
index b25a139..54e36d0 100644
--- a/testSchemas.c
+++ b/testSchemas.c
@@ -32,6 +32,13 @@
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+/* seems needed for Solaris */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+#endif
 
 #include <libxml/xmlmemory.h>
 #include <libxml/debugXML.h>
@@ -42,6 +49,9 @@
 static int debug = 0;
 #endif
 static int noout = 0;
+#ifdef HAVE_SYS_MMAN_H
+static int memory = 0;
+#endif
 
 
 int main(int argc, char **argv) {
@@ -55,6 +65,11 @@
 	    debug++;
 	else
 #endif
+#ifdef HAVE_SYS_MMAN_H
+	if ((!strcmp(argv[i], "-memory")) || (!strcmp(argv[i], "--memory"))) {
+	    memory++;
+        } else
+#endif
 	if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) {
 	    noout++;
         }
@@ -65,13 +80,40 @@
 	    if (schema == NULL) {
 		xmlSchemaParserCtxtPtr ctxt;
 
-		ctxt = xmlSchemaNewParserCtxt(argv[i]);
-		xmlSchemaSetParserErrors(ctxt,
-			(xmlSchemaValidityErrorFunc) fprintf,
-			(xmlSchemaValidityWarningFunc) fprintf,
-			stderr);
-		schema = xmlSchemaParse(ctxt);
-		xmlSchemaFreeParserCtxt(ctxt);
+#ifdef HAVE_SYS_MMAN_H
+		if (memory) {
+		    int fd;
+		    struct stat info;
+		    const char *base;
+		    if (stat(argv[i], &info) < 0) 
+			break;
+		    if ((fd = open(argv[i], O_RDONLY)) < 0)
+			break;
+		    base = mmap(NULL, info.st_size, PROT_READ,
+			        MAP_SHARED, fd, 0) ;
+		    if (base == (void *) MAP_FAILED)
+			break;
+
+		    ctxt = xmlSchemaNewMemParserCtxt((char *)base,info.st_size);
+
+		    xmlSchemaSetParserErrors(ctxt,
+			    (xmlSchemaValidityErrorFunc) fprintf,
+			    (xmlSchemaValidityWarningFunc) fprintf,
+			    stderr);
+		    schema = xmlSchemaParse(ctxt);
+		    xmlSchemaFreeParserCtxt(ctxt);
+		    munmap((char *) base, info.st_size);
+		} else
+#endif
+		{
+		    ctxt = xmlSchemaNewParserCtxt(argv[i]);
+		    xmlSchemaSetParserErrors(ctxt,
+			    (xmlSchemaValidityErrorFunc) fprintf,
+			    (xmlSchemaValidityWarningFunc) fprintf,
+			    stderr);
+		    schema = xmlSchemaParse(ctxt);
+		    xmlSchemaFreeParserCtxt(ctxt);
+		}
 #ifdef LIBXML_DEBUG_ENABLED
 		if (debug)
 		    xmlSchemaDump(stdout, schema);
@@ -118,6 +160,9 @@
 	printf("\t--debug : dump a debug tree of the in-memory document\n");
 #endif
 	printf("\t--noout : do not print the result\n");
+#ifdef HAVE_SYS_MMAN_H
+	printf("\t--memory : test the schemas in memory parsing\n");
+#endif
     }
     xmlSchemaCleanupTypes();
     xmlCleanupParser();
diff --git a/xmlschemas.c b/xmlschemas.c
index 5203ad7..e49a0b0 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -68,6 +68,9 @@
     xmlChar	      *URL;
     xmlDocPtr          doc;
 
+    const char     *buffer;
+    int               size;
+
     /*
      * Used to build complex element content models
      */
@@ -3015,6 +3018,35 @@
 }
 
 /**
+ * xmlSchemaNewMemParserCtxt:
+ * @buffer:  a pointer to a char array containing the schemas
+ * @size:  the size of the array
+ *
+ * Create an XML Schemas parse context for that memory buffer expected
+ * to contain an XML Schemas file.
+ *
+ * Returns the parser context or NULL in case of error
+ */
+xmlSchemaParserCtxtPtr
+xmlSchemaNewMemParserCtxt(const char *buffer, int size) {
+    xmlSchemaParserCtxtPtr ret;
+
+    if ((buffer == NULL) || (size <= 0))
+	return(NULL);
+
+    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
+    if (ret == NULL) {
+	xmlGenericError(xmlGenericErrorContext,
+		"Failed to allocate new schama parser context\n");
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
+    ret->buffer = buffer;
+    ret->size = size;
+    return (ret);
+}
+
+/**
  * xmlSchemaFreeParserCtxt:
  * @ctxt:  the schema parser context
  *
@@ -3026,6 +3058,8 @@
 	return;
     if (ctxt->URL != NULL)
 	xmlFree(ctxt->URL);
+    if (ctxt->doc != NULL)
+	xmlFreeDoc(ctxt->doc);
     xmlFree(ctxt);
 }
 
@@ -3795,7 +3829,7 @@
 
     xmlSchemaInitTypes();
 
-    if ((ctxt == NULL) || (ctxt->URL == NULL))
+    if (ctxt == NULL)
         return (NULL);
 
     ctxt->counter = 0;
@@ -3804,12 +3838,29 @@
     /*
      * First step is to parse the input document into an DOM/Infoset
      */
-    doc = xmlParseFile((const char *) ctxt->URL);
-    if (doc == NULL) {
-        if (ctxt->error != NULL)
-            ctxt->error(ctxt->userData,
-                        "xmlSchemaParse: could not load %s\n", ctxt->URL);
-        return (NULL);
+    if (ctxt->URL != NULL) {
+	doc = xmlParseFile((const char *) ctxt->URL);
+	if (doc == NULL) {
+	    if (ctxt->error != NULL)
+		ctxt->error(ctxt->userData,
+			    "xmlSchemaParse: could not load %s\n", ctxt->URL);
+	    return (NULL);
+	}
+    } else if (ctxt->buffer != NULL) {
+	doc = xmlParseMemory(ctxt->buffer, ctxt->size);
+	if (doc == NULL) {
+	    if (ctxt->error != NULL)
+		ctxt->error(ctxt->userData,
+			    "xmlSchemaParse: could not parse schemas\n");
+	    return (NULL);
+	}
+	doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
+	ctxt->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
+    } else {
+	if (ctxt->error != NULL)
+	    ctxt->error(ctxt->userData,
+			"xmlSchemaParse: nothing to parse\n");
+	return (NULL);
     }
 
     /*