Exemple #1
0
rxml_document_t *rxml_load_document(const char *path)
{
#ifndef RXML_TEST
   RARCH_WARN("Using RXML as drop in for libxml2. Behavior might be very buggy.\n");
#endif

   char *memory_buffer     = NULL;
   char *new_memory_buffer = NULL;
   const char *mem_ptr     = NULL;
   long len                = 0;

   FILE *file = fopen(path, "r");
   if (!file)
      return NULL;

   rxml_document_t *doc = (rxml_document_t*)calloc(1, sizeof(*doc));
   if (!doc)
      goto error;

   fseek(file, 0, SEEK_END);
   len = ftell(file);
   rewind(file);

   memory_buffer = (char*)malloc(len + 1);
   if (!memory_buffer)
      goto error;

   memory_buffer[len] = '\0';
   if (fread(memory_buffer, 1, len, file) != (size_t)len)
      goto error;

   fclose(file);
   file = NULL;

   mem_ptr = memory_buffer;

   if (!validate_header(&mem_ptr))
      goto error;

   new_memory_buffer = purge_xml_comments(mem_ptr);
   if (!new_memory_buffer)
      goto error;

   free(memory_buffer);
   mem_ptr = memory_buffer = new_memory_buffer;

   doc->root_node = rxml_parse_node(&mem_ptr);
   if (!doc->root_node)
      goto error;

   free(memory_buffer);
   return doc;

error:
   free(memory_buffer);
   if (file)
      fclose(file);
   rxml_free_document(doc);
   return NULL;
}
Exemple #2
0
rxml_document_t *rxml_load_document(const char *path)
{
   rxml_document_t *doc;
   char *memory_buffer     = NULL;
   char *new_memory_buffer = NULL;
   const char *mem_ptr     = NULL;
   long len                = 0;
   RFILE *file             = filestream_open(path,
         RETRO_VFS_FILE_ACCESS_READ,
         RETRO_VFS_FILE_ACCESS_HINT_NONE);
   if (!file)
      return NULL;

   doc = (rxml_document_t*)calloc(1, sizeof(*doc));
   if (!doc)
      goto error;

   len           = filestream_get_size(file);
   memory_buffer = (char*)malloc(len + 1);
   if (!memory_buffer)
      goto error;

   memory_buffer[len] = '\0';
   if (filestream_read(file, memory_buffer, len) != (size_t)len)
      goto error;

   filestream_close(file);
   file = NULL;

   mem_ptr = memory_buffer;

   if (!validate_header(&mem_ptr))
      goto error;

   new_memory_buffer = purge_xml_comments(mem_ptr);
   if (!new_memory_buffer)
      goto error;

   free(memory_buffer);
   mem_ptr = memory_buffer = new_memory_buffer;

   doc->root_node = rxml_parse_node(&mem_ptr);
   if (!doc->root_node)
      goto error;

   free(memory_buffer);
   return doc;

error:
   free(memory_buffer);
   filestream_close(file);
   rxml_free_document(doc);
   return NULL;
}
Exemple #3
0
static struct rxml_node *rxml_parse_node(const char **ptr_)
{
   const char *ptr     = NULL;
   const char *closing = NULL;
   char *str           = NULL;
   bool is_closing     = false;

   struct rxml_node *node = (struct rxml_node*)calloc(1, sizeof(*node));
   if (!node)
      return NULL;

   skip_spaces(ptr_);

   ptr = *ptr_;
   if (*ptr != '<')
      goto error;

   closing = strchr(ptr, '>');
   if (!closing)
      goto error;

   str = strdup_range(ptr + 1, closing);
   if (!str)
      goto error;

   if (!rxml_parse_tag(node, str))
      goto error;

   is_closing = strstr(ptr, "/>") + 1 == closing; // Are spaces between / and > allowed?

   // Look for more data. Either child nodes or data.
   if (!is_closing)
   {
      size_t closing_tag_size = strlen(node->name) + 4;
      char *closing_tag = (char*)malloc(closing_tag_size);

      const char *cdata_start = NULL;
      const char *child_start = NULL;
      const char *closing_start = NULL;

      if (!closing_tag)
      {
         free(closing_tag);
         goto error;
      }

      snprintf(closing_tag, closing_tag_size, "</%s>", node->name);

      cdata_start   = strstr(closing + 1, "<![CDATA[");
      child_start   = strchr(closing + 1, '<');
      closing_start = strstr(closing + 1, closing_tag);

      if (!closing_start)
      {
         free(closing_tag);
         goto error;
      }

      if (cdata_start && range_is_space(closing + 1, cdata_start)) // CDATA section
      {
         const char *cdata_end = strstr(cdata_start, "]]>");
         if (!cdata_end)
         {
            free(closing_tag);
            goto error;
         }

         node->data = strdup_range(cdata_start + strlen("<![CDATA["), cdata_end);
      }
      else if (closing_start && closing_start == child_start) // Simple Data
         node->data = strdup_range(closing + 1, closing_start);
      else // Parse all child nodes.
      {
         struct rxml_node *list = NULL;
         struct rxml_node *tail = NULL;

         const char *ptr = child_start;

         const char *first_start   = strchr(ptr, '<');
         const char *first_closing = strstr(ptr, "</");
         while (first_start && first_closing && first_start < first_closing)
         {
            struct rxml_node *new_node = rxml_parse_node(&ptr);
            if (!new_node)
            {
               free(closing_tag);
               goto error;
            }

            if (tail)
            {
               tail->next = new_node;
               tail = new_node;
            }
            else
               list = tail = new_node;

            first_start   = strchr(ptr, '<');
            first_closing = strstr(ptr, "</");
         }

         node->children = list;

         closing_start = strstr(ptr, closing_tag);
         if (!closing_start)
         {
            free(closing_tag);
            goto error;
         }
      }

      *ptr_ = closing_start + strlen(closing_tag);
      free(closing_tag);
   }
   else
      *ptr_ = closing + 1;

   free(str);
   return node;

error:
   free(str);
   rxml_free_node(node);
   return NULL;
}