« Return to Thread: osync_xmlformat_validate() in format plugins

Re: osync_xmlformat_validate() in format plugins

by Daniel Gollub :: Rate this Message:

Reply to Author | View in Thread

On Thursday 26 June 2008 12:58:34 Bjoern Ricks wrote:

> The last days I was thinking about that and it is alway better not to
> use any static variables because of concurrent access. But I don't think
> we could avoid this problem without having more schema instances in the
> memory. If we use your solution every format plugin has to create its
> own instance of each schema which the plugin will support. This will be
> better than today but not really nice.
>
> Maybe you can review my code again and test it. I changed the xmlformat
> test suite to fit with the new solution, too. If my code is ok I will
> commit it. Afterwards I take a look at the format plugins and change
> them if necessary.

(Sorry, for the delayed reply. Compeltely forgot to review this ...)

Ok, let's give it a try...
Some comments about coding style and moving the _schema stuff into seperated
files and introducing reference counting.



[...]

> Index: opensync/xmlformat/opensync_xmlformat.c
> ===================================================================
> --- opensync/xmlformat/opensync_xmlformat.c     (Revision 3381)
> +++ opensync/xmlformat/opensync_xmlformat.c     (Arbeitskopie)
> @@ -97,6 +97,7 @@
>   * @param path The individual schema path. If NULL the default
> OPENSYNC_SCHEMASDIR is used. * @return TRUE if xmlformat valid else FALSE
>   */
> +/*
>  osync_bool _osync_xmlformat_validate(OSyncXMLFormat *xmlformat, const char
> *path) {
>         osync_assert(xmlformat);
> @@ -111,8 +112,141 @@
>         g_free(schemafilepath);
>
>         return res;
> +} */

What about moving the entire osync_xmlformat_schema_* "class" into a seperated
file? e.g.: opensync/xmlformart/opensync_xmlformat_schema(_internals.h).(c|
h)?

--------------- 8< -------------------------

> +
> +/**
> + * @brief Create new OSyncXMLFormatSchema for xmlformat
> + * @param xmlformat The pointer to a xmlformat object. xmlformat->objtype
> is used to identify the schema file + * @param path The individual schema
> path. If NULL the default OPENSYNC_SCHEMASDIR is used. + * @param error The
> error which will hold the info in case of an error + * @return new
> OSyncXMLFormatSchema or NULL in case of an error
> + */
> +OSyncXMLFormatSchema * osync_xmlformat_schema_new(OSyncXMLFormat *
> xmlformat, const char *path, OSyncError **error) { +      
> OSyncXMLFormatSchema * osyncschema = NULL;
> +
> +       osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, xmlformat,
> path, error); +
> +       osync_assert(xmlformat);
> +
> +       osyncschema = osync_try_malloc0(sizeof(OSyncXMLFormatSchema),
> error); +       if(!osyncschema) {
> +               osync_trace(TRACE_EXIT_ERROR, "%s: %s" , __func__,
> osync_error_print(error)); +               // release mutex
> +               return NULL;
> +       }
> +       osyncschema->objtype =
> g_strdup(osync_xmlformat_get_objtype(xmlformat)); +       char
> *schemafilepath = g_strdup_printf("%s%c%s%s%s",
> +               path ? path : OPENSYNC_SCHEMASDIR,
> +               G_DIR_SEPARATOR,
> +               "xmlformat-",
> +               osyncschema->objtype,
> +               ".xsd");
> +
> +       xmlSchemaParserCtxtPtr xmlSchemaParserCtxt;
> +       xmlSchemaPtr xmlSchema;
> +       xmlSchemaValidCtxtPtr xmlSchemaValidCtxt;
> +
> +       xmlSchemaParserCtxt = xmlSchemaNewParserCtxt(schemafilepath);
> +       osyncschema->schema = xmlSchemaParse(xmlSchemaParserCtxt);
> +       xmlSchemaFreeParserCtxt(xmlSchemaParserCtxt);
> +
> +       osyncschema->context = xmlSchemaNewValidCtxt(osyncschema->schema);
> +       if (osyncschema->context == NULL) {
> +               xmlSchemaFree(osyncschema->schema);
> +               g_free(osyncschema->objtype);
> +               g_free(osyncschema);
> +               osyncschema = NULL;
> +               osync_error_set(error, OSYNC_ERROR_GENERIC, "XMLFormat
> validation failed. Could not create Schema Context."); +       }
> +       return osyncschema;
>  }
>
> +/**
> + * @brief Free existing OSyncXMLFormatSchema
> + * @param osyncschema Pointer to the Schema that shoud be freed
> + * @param error The error which will hold the info in case of an error
> + */
> +void osync_xmlformat_schema_free(OSyncXMLFormatSchema * osyncschema) {
> +
> +       osync_assert(osyncschema);
> +
> +       xmlSchemaFreeValidCtxt(osyncschema->context);
> +       xmlSchemaFree(osyncschema->schema);
> +       g_free(osyncschema->objtype);
> +       g_free(osyncschema);
> +
> +}

Instead of having simple _free() functions - what about reference counting?
And adding corresbonding _ref() and _unref() function?

> +
> +/**
> + * @brief Get a  schema for the xmlformat.
> + *
> + * This function creates only one instance of a schema for each objtype.
> If a xmlformat is passed as a parameter with the same + * objtype as a
> xmlformat prior the returned pointer to a OSyncXMLFormatSchema instance is
> the same as before. + *
> + * @param xmlformat The pointer to a xmlformat object
> + * @param error The error which will hold the info in case of an error
> + * @return Pointer to a instance of OSyncXMLFormatSchema
> + */
> +
> +OSyncXMLFormatSchema * osync_xmlformat_schema_get_instance(OSyncXMLFormat
> * xmlformat, OSyncError **error) { +       static GList * schemas = NULL;
> +       static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
> +       OSyncXMLFormatSchema * osyncschema = NULL;
> +       GList * entry;
> +       const char * objtype;
> +
> +       osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, xmlformat, error);
> +
> +       osync_assert(xmlformat);
> +
> +       objtype = osync_xmlformat_get_objtype(xmlformat);
> +       // get mutex
> +       g_static_mutex_lock(&mutex);
> +       // find schema for objtype
> +       for ( entry = schemas; entry != NULL; entry=entry->next) { //
> should be fast enough for only a few objtypes +               osyncschema =
> (OSyncXMLFormatSchema *) entry->data; +               if
> (!strcmp(osyncschema->objtype, objtype) ) {
> +                       return osyncschema;
> +               }
> +               osyncschema = NULL;
> +       }
> +       if ( osyncschema == NULL ) {
> +               osyncschema = osync_xmlformat_schema_new(xmlformat, NULL,
> error); +               if ( osyncschema != NULL ) {
> +                       schemas = g_list_append(schemas, osyncschema);
> +               }
> +       }
> +       // release mutex
> +       g_static_mutex_unlock(&mutex);
> +       return osyncschema;
> +}
> +
> +/**
> + * @brief Validate the xmlformat against its schema
> + * @param xmlformat The pointer to a xmlformat object
> + * @param schema The pointer to a OSyncXMLFormatSchema object.
> + * @param error The error which will hold the info in case of an error
> + * @return TRUE if xmlformat valid else FALSE
> + */
> +
> +osync_bool osync_xmlformat_schema_validate(OSyncXMLFormatSchema * schema,
> OSyncXMLFormat * xmlformat, OSyncError **error)
> +{

Not quite sure if there is a declartion in the CODING style file or not.
But "Type * variable" looks funny - would you mind to change this to "Type
*variable" ... at least i guess the other code looks like this. I hope you
don't mind... actually i'm not that kind of nitpicker ;)

Oh wait - maybe i'm...

> +       osync_assert(xmlformat);
> +       osync_assert(schema);
> +
> +       int rc = 0;
> +
> +       /* Validate the document */
> +       rc = xmlSchemaValidateDoc(schema->context, xmlformat->doc);
> +
> +       if(rc != 0) {
> +               osync_error_set(error, OSYNC_ERROR_GENERIC, "XMLFormat
> validation failed."); +               return FALSE;
> +       }
> +       return TRUE;
> +}
> +
> +
>  /*@}*/


--------------------- >8 ------------------------

>
>  /**
> @@ -394,13 +528,15 @@
>  /**
>   * @brief Validate the xmlformat against its schema
>   * @param xmlformat The pointer to a xmlformat object
> + * @param error The error which will hold the info in case of an error
>   * @return TRUE if xmlformat valid else FALSE
>   */
> -osync_bool osync_xmlformat_validate(OSyncXMLFormat *xmlformat)
> +osync_bool osync_xmlformat_validate(OSyncXMLFormat *xmlformat, OSyncError
> **error) {
>         osync_assert(xmlformat);
> -
> -       return _osync_xmlformat_validate(xmlformat, NULL);
> +
> +       OSyncXMLFormatSchema * schema =
> osync_xmlformat_schema_get_instance(xmlformat, error); +       return
> osync_xmlformat_schema_validate(schema, xmlformat, error); }
>
>  /**
> Index: opensync/xmlformat/opensync_xmlformat_internals.h
> ===================================================================
> --- opensync/xmlformat/opensync_xmlformat_internals.h   (Revision 3381)
> +++ opensync/xmlformat/opensync_xmlformat_internals.h   (Arbeitskopie)
> @@ -23,7 +23,9 @@
>  #ifndef OPENSYNC_XMLFORMAT_INTERNALS_H_
>  #define OPENSYNC_XMLFORMAT_INTERNALS_H_
>
> -#include <opensync/opensync_xml.h>
> +#include <libxml/xpath.h>
> +#include <libxml/xmlschemas.h>
> +#include <libxml/tree.h>
>
>  /**
>   * @brief Represent a XMLFormat object
> @@ -45,7 +47,24 @@
>
>  };
>
------------------ 8< ---------------

> +/**
> + * @brief Represents a Schema object
> + * @ingroup OSyncXMLFormatPrivateAPI
> + */
> +typedef struct OSyncXMLFormatSchema {
> +       /** The schema object */
> +       xmlSchemaPtr schema;
> +       /** The schema validation context */
> +       xmlSchemaValidCtxtPtr context;
> +       /** The object type of OSyncXMLFormat */
> +       char * objtype;
> +} OSyncXMLFormatSchema;
----------------------- >8 ------------
Move this into opensync/xmlformat/opensync_xmlformat_schema_internals.h?


> +
>  int _osync_xmlformat_get_points(OSyncXMLPoints points[], int* cur_pos, int
> basic_points, const char* fieldname); -osync_bool
> _osync_xmlformat_validate(OSyncXMLFormat *xmlformat, const char *path);
>
> +OSyncXMLFormatSchema * osync_xmlformat_schema_get_instance(OSyncXMLFormat
> * xmlformat, OSyncError **error); +OSyncXMLFormatSchema *
> osync_xmlformat_schema_new(OSyncXMLFormat * xmlformat, const char *path,
> OSyncError **error); +void osync_xmlformat_schema_free(OSyncXMLFormatSchema
> * schema);
------------- 8< -------
> +osync_bool osync_xmlformat_schema_validate(OSyncXMLFormatSchema * schema,
> OSyncXMLFormat * xmlformat, OSyncError **error); +
--------- >8 ----------
Move this into opensync/xmlfomrat/opensync_xmlformat_schema.h?

>  #endif /*OPENSYNC_XMLFORMAT_INTERNAL_H_*/
> Index: opensync/xmlformat/opensync_xmlformat.h
> ===================================================================
> --- opensync/xmlformat/opensync_xmlformat.h     (Revision 3381)
> +++ opensync/xmlformat/opensync_xmlformat.h     (Arbeitskopie)
> @@ -48,7 +48,7 @@
>  OSYNC_EXPORT OSyncXMLFieldList
> *osync_xmlformat_search_field(OSyncXMLFormat *xmlformat, const char *name,
> OSyncError **error, ...);
>
>  OSYNC_EXPORT osync_bool osync_xmlformat_assemble(OSyncXMLFormat
> *xmlformat, char **buffer, unsigned int *size); -OSYNC_EXPORT osync_bool
> osync_xmlformat_validate(OSyncXMLFormat *xmlformat); +OSYNC_EXPORT
> osync_bool osync_xmlformat_validate(OSyncXMLFormat *xmlformat, OSyncError
> **error);
>
>  OSYNC_EXPORT void osync_xmlformat_sort(OSyncXMLFormat *xmlformat);
>
> Index: tests/merger-tests/check_xmlformat.c
> ===================================================================
> --- tests/merger-tests/check_xmlformat.c        (Revision 3381)
> +++ tests/merger-tests/check_xmlformat.c        (Arbeitskopie)
> @@ -275,6 +275,7 @@
>         char *buffer;
>         unsigned int size;
>         OSyncError *error = NULL;
> +       OSyncXMLFormatSchema *schema = NULL;
>
>         fail_unless(osync_file_read("event.xml", &buffer, &size, &error),
> NULL); fail_unless(error == NULL, NULL);
> @@ -283,9 +284,13 @@
>         fail_unless(error == NULL, NULL);
>
>         g_free(buffer);
> -
> -       fail_unless(_osync_xmlformat_validate(xmlformat, testbed) != FALSE,
> NULL); -
> +       schema = osync_xmlformat_schema_new(xmlformat, testbed, &error);
> +       fail_if( schema == NULL );
> +       //fail_unless(_osync_xmlformat_validate(xmlformat, testbed) !=
> FALSE, NULL);

Just remove deadcode...

> +       fail_unless( osync_xmlformat_schema_validate(schema,
> xmlformat, &error) ); +
> +       osync_xmlformat_schema_free(schema);
> +
>         osync_xmlformat_unref(xmlformat);
>
>         destroy_testbed(testbed);



-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Opensync-devel mailing list
Opensync-devel@...
https://lists.sourceforge.net/lists/listinfo/opensync-devel

 « Return to Thread: osync_xmlformat_validate() in format plugins