示例#1
0
GimpPlugInProcedure *
file_procedure_find (GSList       *procs,
                     const gchar  *uri,
                     GError      **error)
{
  GimpPlugInProcedure *file_proc;
  GSList              *all_procs = procs;
  gchar               *filename;

  g_return_val_if_fail (procs != NULL, NULL);
  g_return_val_if_fail (uri != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  /* First, check magicless prefixes/suffixes */
  file_proc = file_proc_find_by_name (all_procs, uri, TRUE);

  if (file_proc)
    return file_proc;

  filename = file_utils_filename_from_uri (uri);

  /* Then look for magics */
  if (filename)
    {
      GimpPlugInProcedure *size_matched_proc = NULL;
      FILE                *ifp               = NULL;
      gint                 head_size         = -2;
      gint                 size_match_count  = 0;
      guchar               head[256];

      while (procs)
        {
          file_proc = procs->data;
          procs = procs->next;

          if (file_proc->magics_list)
            {
              if (head_size == -2)
                {
                  head_size = 0;

                  if ((ifp = g_fopen (filename, "rb")) != NULL)
                    {
                      head_size = fread ((gchar *) head, 1, sizeof (head), ifp);
                    }
                  else
                    {
                      g_set_error (error,
                                   G_FILE_ERROR,
                                   g_file_error_from_errno (errno),
                                   g_strerror (errno));
                    }
                }

              if (head_size >= 4)
                {
                  FileMatchType match_val;

                  match_val = file_check_magic_list (file_proc->magics_list,
                                                     head, head_size,
                                                     ifp);

                  if (match_val == FILE_MATCH_SIZE)
                    {
                      /* Use it only if no other magic matches */
                      size_match_count++;
                      size_matched_proc = file_proc;
                    }
                  else if (match_val != FILE_MATCH_NONE)
                    {
                      fclose (ifp);
                      g_free (filename);

                      return file_proc;
                    }
                }
            }
        }

      if (ifp)
        {
          if (ferror (ifp))
            g_set_error (error,
                         G_FILE_ERROR,
                         g_file_error_from_errno (errno),
                         g_strerror (errno));

          fclose (ifp);
        }

      g_free (filename);

      if (size_match_count == 1)
        return size_matched_proc;
    }

  /* As a last resort, try matching by name */
  file_proc = file_proc_find_by_name (all_procs, uri, FALSE);

  if (file_proc)
    {
      /* we found a procedure, clear error that might have been set */
      g_clear_error (error);
    }
  else
    {
      /* set an error message unless one was already set */
      if (error && *error == NULL)
        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("Unknown file type"));
    }

  return file_proc;
}
示例#2
0
GimpPlugInProcedure *
file_procedure_find (GSList       *procs,
                     const gchar  *uri,
                     GError      **error)
{
  GimpPlugInProcedure *file_proc;
  gchar               *filename;

  g_return_val_if_fail (procs != NULL, NULL);
  g_return_val_if_fail (uri != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  /* First, check magicless prefixes/suffixes: */

  if (! file_proc_find_by_extension (procs, uri, FALSE, TRUE))
    {
      /* If there is not any (with or without magic) file proc that
       * can load the URI by extension directly, try to find a proc
       * that can load the prefix
       */
      file_proc = file_proc_find_by_prefix (procs, uri, TRUE);
    }
  else
    {
      /* Otherwise try to find a magicless file proc that handles the
       * extension
       */
      file_proc = file_proc_find_by_extension (procs, uri, TRUE, FALSE);
    }

  if (file_proc)
    return file_proc;

  filename = file_utils_filename_from_uri (uri);

  /* Then look for magics */
  if (filename)
    {
      GSList              *list;
      GimpPlugInProcedure *size_matched_proc = NULL;
      FILE                *ifp               = NULL;
      gboolean             opened            = FALSE;
      gint                 head_size         = 0;
      gint                 size_match_count  = 0;
      guchar               head[256];

      for (list = procs; list; list = g_slist_next (list))
        {
          file_proc = procs->data;

          if (file_proc->magics_list)
            {
              if (G_UNLIKELY (!opened))
                {
                  ifp = g_fopen (filename, "rb");
                  if (ifp != NULL)
                    head_size = fread ((gchar *) head, 1, sizeof (head), ifp);
                  else
                    g_set_error_literal (error,
                                         G_FILE_ERROR,
                                         g_file_error_from_errno (errno),
                                         g_strerror (errno));
                  opened = TRUE;
                }

              if (head_size >= 4)
                {
                  FileMatchType match_val;

                  match_val = file_check_magic_list (file_proc->magics_list,
                                                     head, head_size,
                                                     ifp);

                  if (match_val == FILE_MATCH_SIZE)
                    {
                      /* Use it only if no other magic matches */
                      size_match_count++;
                      size_matched_proc = file_proc;
                    }
                  else if (match_val != FILE_MATCH_NONE)
                    {
                      fclose (ifp);
                      g_free (filename);

                      return file_proc;
                    }
                }
            }
        }

      if (ifp)
        {
          if (ferror (ifp))
            g_set_error_literal (error, G_FILE_ERROR,
                                 g_file_error_from_errno (errno),
                                 g_strerror (errno));

          fclose (ifp);
        }

      g_free (filename);

      if (size_match_count == 1)
        return size_matched_proc;
    }

  /* As a last resort, try matching by name, not skipping magic procs */
  file_proc = file_proc_find_by_name (procs, uri, FALSE);

  if (file_proc)
    {
      /* we found a procedure, clear error that might have been set */
      g_clear_error (error);
    }
  else
    {
      /* set an error message unless one was already set */
      if (error && *error == NULL)
	g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
			     _("Unknown file type"));
    }

  return file_proc;
}