~ubuntu-branches/ubuntu/trusty/gobject-introspection/trusty

« back to all changes in this revision

Viewing changes to girepository/girepository.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-11-24 12:32:20 UTC
  • mto: (3.3.15 natty) (1.6.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20101124123220-tbyh4pkjldp5ayck
Tags: upstream-0.9.12+git20101124
ImportĀ upstreamĀ versionĀ 0.9.12+git20101124

Show diffs side-by-side

added added

removed removed

Lines of Context:
515
515
  return n_interfaces;
516
516
}
517
517
 
518
 
typedef struct
519
 
{
520
 
  GIRepository *repo;
521
 
  gint index;
522
 
  const gchar *name;
523
 
  gboolean type_firstpass;
524
 
  const gchar *type;
525
 
  GIBaseInfo *iface;
526
 
} IfaceData;
527
 
 
528
 
static void
529
 
find_interface (gpointer key,
530
 
                gpointer value,
531
 
                gpointer data)
532
 
{
533
 
  gint i;
534
 
  GITypelib *typelib = (GITypelib *)value;
535
 
  Header *header = (Header *) typelib->data;
536
 
  IfaceData *iface_data = (IfaceData *)data;
537
 
  gint index;
538
 
  gint n_entries;
539
 
  const gchar *name;
540
 
  const gchar *type;
541
 
  DirEntry *entry;
542
 
 
543
 
  index = 0;
544
 
  n_entries = ((Header *)typelib->data)->n_local_entries;
545
 
 
546
 
  if (iface_data->name)
547
 
    {
548
 
      for (i = 1; i <= n_entries; i++)
549
 
        {
550
 
          entry = g_typelib_get_dir_entry (typelib, i);
551
 
          name = g_typelib_get_string (typelib, entry->name);
552
 
          if (strcmp (name, iface_data->name) == 0)
553
 
            {
554
 
              index = i;
555
 
              break;
556
 
            }
557
 
        }
558
 
    }
559
 
  else if (iface_data->type)
560
 
    {
561
 
      const char *c_prefix;
562
 
      /* Inside each typelib, we include the "C prefix" which acts as
563
 
       * a namespace mechanism.  For GtkTreeView, the C prefix is Gtk.
564
 
       * Given the assumption that GTypes for a library also use the
565
 
       * C prefix, we know we can skip examining a typelib if our
566
 
       * target type does not have this typelib's C prefix.
567
 
       *
568
 
       * However, not every class library necessarily conforms to this,
569
 
       * e.g. Clutter has Cogl inside it.  So, we split this into two
570
 
       * passes.  First we try a lookup, skipping things which don't
571
 
       * have the prefix.  If that fails then we try a global lookup,
572
 
       * ignoring the prefix.
573
 
       *
574
 
       * See http://bugzilla.gnome.org/show_bug.cgi?id=564016
575
 
       */
576
 
      c_prefix = g_typelib_get_string (typelib, header->c_prefix);
577
 
      if (iface_data->type_firstpass && c_prefix != NULL)
578
 
        {
579
 
          if (g_ascii_strncasecmp (c_prefix, iface_data->type, strlen (c_prefix)) != 0)
580
 
            return;
581
 
        }
582
 
 
583
 
      for (i = 1; i <= n_entries; i++)
584
 
        {
585
 
          RegisteredTypeBlob *blob;
586
 
 
587
 
          entry = g_typelib_get_dir_entry (typelib, i);
588
 
          if (!BLOB_IS_REGISTERED_TYPE (entry))
589
 
            continue;
590
 
 
591
 
          blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]);
592
 
          if (!blob->gtype_name)
593
 
            continue;
594
 
 
595
 
          type = g_typelib_get_string (typelib, blob->gtype_name);
596
 
          if (strcmp (type, iface_data->type) == 0)
597
 
            {
598
 
              index = i;
599
 
              break;
600
 
            }
601
 
        }
602
 
    }
603
 
  else if (iface_data->index > n_entries)
604
 
    iface_data->index -= n_entries;
605
 
  else if (iface_data->index > 0)
606
 
    {
607
 
      index = iface_data->index;
608
 
      iface_data->index = 0;
609
 
    }
610
 
 
611
 
  if (index != 0)
612
 
    {
613
 
      entry = g_typelib_get_dir_entry (typelib, index);
614
 
      iface_data->iface = _g_info_new_full (entry->blob_type,
615
 
                                            iface_data->repo,
616
 
                                            NULL, typelib, entry->offset);
617
 
    }
618
 
}
619
 
 
620
518
/**
621
519
 * g_irepository_get_info:
622
520
 * @repository: (allow-none): A #GIRepository, may be %NULL for the default
623
521
 * @namespace_: Namespace to inspect
624
 
 * @index: Offset into namespace metadata for entry
 
522
 * @index: 0-based offset into namespace metadata for entry
625
523
 *
626
524
 * This function returns a particular metadata entry in the
627
525
 * given namespace @namespace_.  The namespace must have
628
526
 * already been loaded before calling this function.
 
527
 * See g_irepository_get_n_infos() to find the maximum number of
 
528
 * entries.
629
529
 *
630
530
 * Returns: (transfer full): #GIBaseInfo containing metadata
631
531
 */
634
534
                        const gchar  *namespace,
635
535
                        gint          index)
636
536
{
637
 
  IfaceData data;
638
537
  GITypelib *typelib;
 
538
  DirEntry *entry;
639
539
 
640
540
  g_return_val_if_fail (namespace != NULL, NULL);
641
541
 
642
542
  repository = get_repository (repository);
643
543
 
644
 
  data.repo = repository;
645
 
  data.name = NULL;
646
 
  data.type = NULL;
647
 
  data.index = index + 1;
648
 
  data.iface = NULL;
649
 
 
650
544
  typelib = get_registered (repository, namespace, NULL);
651
545
 
652
546
  g_return_val_if_fail (typelib != NULL, NULL);
653
547
 
654
 
  find_interface ((void *)namespace, typelib, &data);
655
 
 
656
 
  return data.iface;
 
548
  entry = g_typelib_get_dir_entry (typelib, index + 1);
 
549
  if (entry == NULL)
 
550
    return NULL;
 
551
  return _g_info_new_full (entry->blob_type,
 
552
                           repository,
 
553
                           NULL, typelib, entry->offset);
 
554
}
 
555
 
 
556
typedef struct {
 
557
  GIRepository *repository;
 
558
  GType type;
 
559
 
 
560
  gboolean fastpass;
 
561
  GITypelib *result_typelib;
 
562
  DirEntry *result;
 
563
} FindByGTypeData;
 
564
 
 
565
static void
 
566
find_by_gtype_foreach (gpointer key,
 
567
                       gpointer value,
 
568
                       gpointer datap)
 
569
{
 
570
  GITypelib *typelib = (GITypelib*)value;
 
571
  FindByGTypeData *data = datap;
 
572
 
 
573
  if (data->result != NULL)
 
574
    return;
 
575
 
 
576
  data->result = g_typelib_get_dir_entry_by_gtype (typelib, data->fastpass, data->type);
 
577
  if (data->result)
 
578
    data->result_typelib = typelib;
657
579
}
658
580
 
659
581
/**
674
596
g_irepository_find_by_gtype (GIRepository *repository,
675
597
                             GType         gtype)
676
598
{
677
 
  IfaceData data;
 
599
  FindByGTypeData data;
 
600
  GIBaseInfo *cached;
678
601
 
679
602
  repository = get_repository (repository);
680
603
 
681
 
  data.iface = g_hash_table_lookup (repository->priv->info_by_gtype,
682
 
                                    (gpointer)gtype);
683
 
 
684
 
  if (data.iface)
685
 
    return g_base_info_ref (data.iface);
686
 
 
687
 
  data.repo = repository;
688
 
  data.name = NULL;
689
 
  data.type_firstpass = TRUE;
690
 
  data.type = g_type_name (gtype);
691
 
  data.index = -1;
692
 
  data.iface = NULL;
693
 
 
694
 
  g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
695
 
  g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
 
604
  cached = g_hash_table_lookup (repository->priv->info_by_gtype,
 
605
                                (gpointer)gtype);
 
606
 
 
607
  if (cached != NULL)
 
608
    return g_base_info_ref (cached);
 
609
 
 
610
  data.repository = repository;
 
611
  data.fastpass = TRUE;
 
612
  data.type = gtype;
 
613
  data.result_typelib = NULL;
 
614
  data.result = NULL;
 
615
 
 
616
  g_hash_table_foreach (repository->priv->typelibs, find_by_gtype_foreach, &data);
 
617
  if (data.result == NULL)
 
618
    g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_gtype_foreach, &data);
696
619
 
697
620
  /* We do two passes; see comment in find_interface */
698
 
  if (!data.iface)
699
 
    {
700
 
      data.type_firstpass = FALSE;
701
 
      g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
702
 
      g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
703
 
    }
704
 
 
705
 
  if (data.iface)
706
 
    g_hash_table_insert (repository->priv->info_by_gtype,
707
 
                         (gpointer) gtype,
708
 
                         g_base_info_ref (data.iface));
709
 
 
710
 
  return data.iface;
 
621
  if (data.result == NULL)
 
622
    {
 
623
      data.fastpass = FALSE;
 
624
      g_hash_table_foreach (repository->priv->typelibs, find_by_gtype_foreach, &data);
 
625
    }
 
626
  if (data.result == NULL)
 
627
    g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_gtype_foreach, &data);
 
628
 
 
629
  if (data.result != NULL)
 
630
    {
 
631
      cached = _g_info_new_full (data.result->blob_type,
 
632
                                 repository,
 
633
                                 NULL, data.result_typelib, data.result->offset);
 
634
 
 
635
      g_hash_table_insert (repository->priv->info_by_gtype,
 
636
                           (gpointer) gtype,
 
637
                           g_base_info_ref (cached));
 
638
      return cached;
 
639
    }
 
640
  return NULL;
711
641
}
712
642
 
713
643
/**
728
658
                            const gchar  *namespace,
729
659
                            const gchar  *name)
730
660
{
731
 
  IfaceData data;
732
661
  GITypelib *typelib;
 
662
  DirEntry *entry;
733
663
 
734
664
  g_return_val_if_fail (namespace != NULL, NULL);
735
665
 
736
666
  repository = get_repository (repository);
737
 
 
738
 
  data.repo = repository;
739
 
  data.name = name;
740
 
  data.type = NULL;
741
 
  data.index = -1;
742
 
  data.iface = NULL;
743
 
 
744
667
  typelib = get_registered (repository, namespace, NULL);
745
 
 
746
668
  g_return_val_if_fail (typelib != NULL, NULL);
747
669
 
748
 
  find_interface ((void *)namespace, typelib, &data);
749
 
 
750
 
  return data.iface;
 
670
  entry = g_typelib_get_dir_entry_by_name (typelib, name);
 
671
  if (entry == NULL)
 
672
    return NULL;
 
673
  return _g_info_new_full (entry->blob_type,
 
674
                           repository,
 
675
                           NULL, typelib, entry->offset);
751
676
}
752
677
 
753
678
static void
1483
1408
      return "gfloat";
1484
1409
    case GI_TYPE_TAG_DOUBLE:
1485
1410
      return "gdouble";
 
1411
    case GI_TYPE_TAG_UNICHAR:
 
1412
      return "gunichar";
1486
1413
    case GI_TYPE_TAG_GTYPE:
1487
1414
      return "GType";
1488
1415
    case GI_TYPE_TAG_UTF8: