gperl-i11n-size.c 3.54 KB
Newer Older
1 2
/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/* These three are basically copied from pygi's pygi-info.c. :-( */

static gsize
size_of_type_tag (GITypeTag type_tag)
{
	switch(type_tag) {
	    case GI_TYPE_TAG_BOOLEAN:
		return sizeof (gboolean);
	    case GI_TYPE_TAG_INT8:
	    case GI_TYPE_TAG_UINT8:
		return sizeof (gint8);
	    case GI_TYPE_TAG_INT16:
	    case GI_TYPE_TAG_UINT16:
		return sizeof (gint16);
	    case GI_TYPE_TAG_INT32:
	    case GI_TYPE_TAG_UINT32:
		return sizeof (gint32);
	    case GI_TYPE_TAG_INT64:
	    case GI_TYPE_TAG_UINT64:
		return sizeof (gint64);
	    case GI_TYPE_TAG_FLOAT:
		return sizeof (gfloat);
	    case GI_TYPE_TAG_DOUBLE:
		return sizeof (gdouble);
	    case GI_TYPE_TAG_GTYPE:
		return sizeof (GType);
29 30
	    case GI_TYPE_TAG_UNICHAR:
		return sizeof (gunichar);
31 32 33 34 35 36 37 38 39 40

	    case GI_TYPE_TAG_VOID:
	    case GI_TYPE_TAG_UTF8:
	    case GI_TYPE_TAG_FILENAME:
	    case GI_TYPE_TAG_ARRAY:
	    case GI_TYPE_TAG_INTERFACE:
	    case GI_TYPE_TAG_GLIST:
	    case GI_TYPE_TAG_GSLIST:
	    case GI_TYPE_TAG_GHASH:
	    case GI_TYPE_TAG_ERROR:
41 42 43
		ccroak ("Unable to determine the size of '%s'",
		        g_type_tag_to_string (type_tag));
		break;
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
	}

	return 0;
}

static gsize
size_of_interface (GITypeInfo *type_info)
{
	gsize size = 0;

	GIBaseInfo *info;
	GIInfoType info_type;

	info = g_type_info_get_interface (type_info);
	info_type = g_base_info_get_type (info);

	switch (info_type) {
	    case GI_INFO_TYPE_STRUCT:
		if (g_type_info_is_pointer (type_info)) {
			size = sizeof (gpointer);
		} else {
			/* FIXME: Remove this workaround once
			 * gobject-introspection is fixed:
			 * <https://bugzilla.gnome.org/show_bug.cgi?id=657040>. */
68
			GType type = get_gtype (info);
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
			if (type == G_TYPE_VALUE) {
				size = sizeof (GValue);
			} else {
				size = g_struct_info_get_size ((GIStructInfo *) info);
			}
		}
		break;

	    case GI_INFO_TYPE_UNION:
		if (g_type_info_is_pointer (type_info)) {
			size = sizeof (gpointer);
		} else {
			size = g_union_info_get_size ((GIUnionInfo *) info);
		}
		break;

	    case GI_INFO_TYPE_ENUM:
	    case GI_INFO_TYPE_FLAGS:
		if (g_type_info_is_pointer (type_info)) {
			size = sizeof (gpointer);
		} else {
			GITypeTag type_tag;
			type_tag = g_enum_info_get_storage_type ((GIEnumInfo *) info);
			size = size_of_type_tag (type_tag);
		}
		break;

	    case GI_INFO_TYPE_BOXED:
	    case GI_INFO_TYPE_OBJECT:
	    case GI_INFO_TYPE_INTERFACE:
	    case GI_INFO_TYPE_CALLBACK:
		size = sizeof (gpointer);
		break;

	    default:
		g_assert_not_reached ();
		break;
	}

	g_base_info_unref (info);

	return size;
}

static gsize
size_of_type_info (GITypeInfo *type_info)
{
	GITypeTag type_tag;

	type_tag = g_type_info_get_tag (type_info);
	switch (type_tag) {
	    case GI_TYPE_TAG_BOOLEAN:
	    case GI_TYPE_TAG_INT8:
	    case GI_TYPE_TAG_UINT8:
	    case GI_TYPE_TAG_INT16:
	    case GI_TYPE_TAG_UINT16:
	    case GI_TYPE_TAG_INT32:
	    case GI_TYPE_TAG_UINT32:
	    case GI_TYPE_TAG_INT64:
	    case GI_TYPE_TAG_UINT64:
	    case GI_TYPE_TAG_FLOAT:
	    case GI_TYPE_TAG_DOUBLE:
	    case GI_TYPE_TAG_GTYPE:
132
	    case GI_TYPE_TAG_UNICHAR:
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
		if (g_type_info_is_pointer (type_info)) {
			return sizeof (gpointer);
		} else {
			return size_of_type_tag (type_tag);
		}

	    case GI_TYPE_TAG_INTERFACE:
		return size_of_interface (type_info);

	    case GI_TYPE_TAG_ARRAY:
	    case GI_TYPE_TAG_VOID:
	    case GI_TYPE_TAG_UTF8:
	    case GI_TYPE_TAG_FILENAME:
	    case GI_TYPE_TAG_GLIST:
	    case GI_TYPE_TAG_GSLIST:
	    case GI_TYPE_TAG_GHASH:
	    case GI_TYPE_TAG_ERROR:
		return sizeof (gpointer);
	}

	return 0;
}