Exemplo n.º 1
0
/** Complete the byte offsets of dimensions from the ordered sizes */
static void
pc_schema_calculate_byteoffsets(PCSCHEMA *pcs)
{
	int i;
	size_t byteoffset = 0;
	for ( i = 0; i < pcs->ndims; i++ )
	{
		if ( pcs->dims[i] )
		{
			pcs->dims[i]->byteoffset = byteoffset;
            pcs->dims[i]->size = pc_interpretation_size(pcs->dims[i]->interpretation);
			byteoffset += pcs->dims[i]->size;
		}
	}
    pcs->size = byteoffset;
}
Exemplo n.º 2
0
static void
test_dimension_byteoffsets()
{
	PCDIMENSION *d;
	int i;
	int prev_byteoffset;
	int prev_size;
	int pc_size;

	for ( i = 0; i < schema->ndims; i++ )
	{
		d = pc_schema_get_dimension(schema, i);
		// printf("d=%d name='%s' size=%d byteoffset=%d\n", i, d->name, d->size, d->byteoffset);
		if ( i > 0 )
		{
			CU_ASSERT_EQUAL(prev_size, pc_size);
			CU_ASSERT_EQUAL(prev_size, d->byteoffset - prev_byteoffset);
		}
		prev_byteoffset = d->byteoffset;
		prev_size = d->size;
		pc_size = pc_interpretation_size(d->interpretation);
	}

}
Exemplo n.º 3
0
/** Population a PCSCHEMA struct from the XML representation */
int
pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
{
	xmlDocPtr xml_doc = NULL;
	xmlNodePtr xml_root = NULL;
	xmlNsPtr xml_ns = NULL;
	xmlXPathContextPtr xpath_ctx; 
	xmlXPathObjectPtr xpath_obj; 
	xmlNodeSetPtr nodes;
	PCSCHEMA *s;
	const char *xml_ptr = xml_str;
	
	/* Roll forward to start of XML string */
	while( (*xml_ptr != '\0') && (*xml_ptr != '<') )
	{
		xml_ptr++;
	}
		
	size_t xml_size = strlen(xml_ptr);
	static xmlChar *xpath_str = "/pc:PointCloudSchema/pc:dimension";
	static xmlChar *xpath_metadata_str = "/pc:PointCloudSchema/pc:metadata/Metadata";

	
	/* Parse XML doc */
	*schema = NULL;
	xmlInitParser();
	xml_doc = xmlReadMemory(xml_ptr, xml_size, NULL, NULL, 0);
	if ( ! xml_doc )
	{
		xmlCleanupParser();
		pcwarn("unable to parse schema XML");
		return PC_FAILURE;
	}
	
	/* Capture the namespace */
	xml_root = xmlDocGetRootElement(xml_doc);
	if ( xml_root->ns )
		xml_ns = xml_root->ns;
	
	/* Create xpath evaluation context */
	xpath_ctx = xmlXPathNewContext(xml_doc);
	if( ! xpath_ctx )
	{
		xmlFreeDoc(xml_doc);
		xmlCleanupParser();
		pcwarn("unable to create new XPath context to read schema XML");
		return PC_FAILURE;
	}

	/* Register the root namespace if there is one */
	if ( xml_ns )
		xmlXPathRegisterNs(xpath_ctx, "pc", xml_ns->href);
	
	/* Evaluate xpath expression */
	xpath_obj = xmlXPathEvalExpression(xpath_str, xpath_ctx);
	if( ! xpath_obj )
	{
	    xmlXPathFreeContext(xpath_ctx); 
		xmlFreeDoc(xml_doc);
		xmlCleanupParser();
		pcwarn("unable to evaluate xpath expression \"%s\" against schema XML", xpath_str);
		return PC_FAILURE;
	}

	/* Iterate on the dimensions we found */
	if ( nodes = xpath_obj->nodesetval )
	{
		int ndims = nodes->nodeNr;
		int i;
		s = pc_schema_new(ndims);
		*schema = s;
				
		for ( i = 0; i < ndims; i++ )
		{
			/* This is a "dimension" */
			if( nodes->nodeTab[i]->type == XML_ELEMENT_NODE )
			{
				xmlNodePtr cur = nodes->nodeTab[i];
				xmlNodePtr child;
				PCDIMENSION *d = pc_dimension_new();
				char xydim = 0;
				
				/* These are the values of the dimension */
				for ( child = cur->children; child; child = child->next )
				{
					if( child->type == XML_ELEMENT_NODE )
					{
						if ( strcmp(child->name, "name") == 0 )
						{
							if ( strcasecmp(child->children->content, "X") == 0 ||
							     strcasecmp(child->children->content, "Longitude") == 0 ||
							     strcasecmp(child->children->content, "Lon") == 0 )
							{
								xydim = 'x';
							}
							if ( strcasecmp(child->children->content, "Y") == 0 ||
							     strcasecmp(child->children->content, "Latitude") == 0 ||
							     strcasecmp(child->children->content, "Lat") == 0 )
							{
								xydim = 'y';
							}
							d->name = pcstrdup(child->children->content);
						}
						else if ( strcmp(child->name, "description") == 0 )
							d->description = pcstrdup(child->children->content);
						else if ( strcmp(child->name, "size") == 0 )
							d->size = atoi(child->children->content);
						else if ( strcmp(child->name, "active") == 0 )
							d->active = atoi(child->children->content);
						else if ( strcmp(child->name, "position") == 0 )
							d->position = atoi(child->children->content) - 1;
						else if ( strcmp(child->name, "interpretation") == 0 )
							d->interpretation = pc_interpretation_number(child->children->content);
						else if ( strcmp(child->name, "scale") == 0 )
							d->scale = atof(child->children->content);
						else if ( strcmp(child->name, "offset") == 0 )
							d->offset = atof(child->children->content);
						else if ( strcmp(child->name, "uuid") == 0 )
							/* Ignore this tag for now */ 1;
						else if ( strcmp(child->name, "parent_uuid") == 0 )
							/* Ignore this tag for now */ 1;
						else
							pcinfo("unhandled schema type element \"%s\" encountered", child->name);
					}
				}
				
				/* Convert interprestation to size */
				d->size = pc_interpretation_size(d->interpretation);
				
				/* Store the dimension in the schema */
				if ( d->position >= 0 && d->position < ndims )
				{
					if ( s->dims[d->position] )
					{
						xmlXPathFreeObject(xpath_obj);
					    xmlXPathFreeContext(xpath_ctx); 
						xmlFreeDoc(xml_doc);
						xmlCleanupParser();
						pc_schema_free(s);
						pcwarn("schema dimension at position \"%d\" is declared twice", d->position + 1, ndims);
						return PC_FAILURE;
					}
					if ( xydim == 'x' ) { s->x_position = d->position; }
					if ( xydim == 'y' ) { s->y_position = d->position; }
                    pc_schema_set_dimension(s, d);
				}
				else
				{
					xmlXPathFreeObject(xpath_obj);
				    xmlXPathFreeContext(xpath_ctx); 
					xmlFreeDoc(xml_doc);
					xmlCleanupParser();
					pc_schema_free(s);
					pcwarn("schema dimension states position \"%d\", but number of XML dimensions is \"%d\"", d->position + 1, ndims);
					return PC_FAILURE;
				}
			}
		}
		
		/* Complete the byte offsets of dimensions from the ordered sizes */
		pc_schema_calculate_byteoffsets(s);
		/* Check X/Y positions */
		pc_schema_check_xy(s);
	}
	
	xmlXPathFreeObject(xpath_obj);
	
	/* SEARCH FOR METADATA ENTRIES */
	xpath_obj = xmlXPathEvalExpression(xpath_metadata_str, xpath_ctx);
	if( ! xpath_obj )
	{
	    xmlXPathFreeContext(xpath_ctx); 
		xmlFreeDoc(xml_doc);
		xmlCleanupParser();
		pcwarn("unable to evaluate xpath expression \"%s\" against schema XML", xpath_metadata_str);
		return PC_FAILURE;
	}
	
	/* Iterate on the <Metadata> we find */
	if ( nodes = xpath_obj->nodesetval )
	{
		int i;

		for ( i = 0; i < nodes->nodeNr; i++ )
		{
            char *metadata_name = "";
            char *metadata_value = "";
		    /* Read the metadata name and value from the node */
		    /* <Metadata name="somename">somevalue</Metadata> */
		    xmlNodePtr cur = nodes->nodeTab[i];
            if( cur->type == XML_ELEMENT_NODE && strcmp(cur->name, "Metadata") == 0 )
            {
                metadata_name = xmlGetProp(cur, "name");
                metadata_value = xml_node_get_content(cur);
            }
            
            /* Store the compression type on the schema */
            if ( strcmp(metadata_name, "compression") == 0 )
            {
                int compression = pc_compression_number(metadata_value);
                if ( compression >= 0 )
                {
                    s->compression = compression;
                }
            }
            xmlFree(metadata_name);
        }
	}
	
	xmlXPathFreeObject(xpath_obj);
	
    xmlXPathFreeContext(xpath_ctx); 
	xmlFreeDoc(xml_doc);
	xmlCleanupParser();
	
	return PC_SUCCESS;
}