+/*
+ * Translates the given 1-based index into the Method, Field, Event, or Param tables
+ * using the *Ptr tables in uncompressed metadata, if they are available.
+ *
+ * FIXME: The caller is not forced to call this function, which is error-prone, since
+ * forgetting to call it would only show up as a bug on uncompressed metadata.
+ */
+guint32
+mono_metadata_translate_token_index (MonoImage *image, int table, guint32 idx)
+{
+ if (!image->uncompressed_metadata)
+ return idx;
+
+ switch (table) {
+ case MONO_TABLE_METHOD:
+ if (image->tables [MONO_TABLE_METHOD_POINTER].rows)
+ return mono_metadata_decode_row_col (&image->tables [MONO_TABLE_METHOD_POINTER], idx - 1, MONO_METHOD_POINTER_METHOD);
+ else
+ return idx;
+ case MONO_TABLE_FIELD:
+ if (image->tables [MONO_TABLE_FIELD_POINTER].rows)
+ return mono_metadata_decode_row_col (&image->tables [MONO_TABLE_FIELD_POINTER], idx - 1, MONO_FIELD_POINTER_FIELD);
+ else
+ return idx;
+ case MONO_TABLE_EVENT:
+ if (image->tables [MONO_TABLE_EVENT_POINTER].rows)
+ return mono_metadata_decode_row_col (&image->tables [MONO_TABLE_EVENT_POINTER], idx - 1, MONO_EVENT_POINTER_EVENT);
+ else
+ return idx;
+ case MONO_TABLE_PROPERTY:
+ if (image->tables [MONO_TABLE_PROPERTY_POINTER].rows)
+ return mono_metadata_decode_row_col (&image->tables [MONO_TABLE_PROPERTY_POINTER], idx - 1, MONO_PROPERTY_POINTER_PROPERTY);
+ else
+ return idx;
+ case MONO_TABLE_PARAM:
+ if (image->tables [MONO_TABLE_PARAM_POINTER].rows)
+ return mono_metadata_decode_row_col (&image->tables [MONO_TABLE_PARAM_POINTER], idx - 1, MONO_PARAM_POINTER_PARAM);
+ else
+ return idx;
+ default:
+ return idx;
+ }
+}
+
+/**
+ * mono_metadata_decode_table_row:
+ *
+ * Same as mono_metadata_decode_row, but takes an IMAGE+TABLE ID pair, and takes
+ * uncompressed metadata into account, so it should be used to access the
+ * Method, Field, Param and Event tables when the access is made from metadata, i.e.
+ * IDX is retrieved from a metadata table, like MONO_TYPEDEF_FIELD_LIST.
+ */
+void
+mono_metadata_decode_table_row (MonoImage *image, int table, int idx, guint32 *res, int res_size)
+{
+ if (image->uncompressed_metadata)
+ idx = mono_metadata_translate_token_index (image, table, idx + 1) - 1;
+
+ mono_metadata_decode_row (&image->tables [table], idx, res, res_size);
+}
+
+/**
+ * mono_metadata_decode_table_row_col:
+ *
+ * Same as mono_metadata_decode_row_col, but takes an IMAGE+TABLE ID pair, and takes
+ * uncompressed metadata into account, so it should be used to access the
+ * Method, Field, Param and Event tables.
+ */
+guint32 mono_metadata_decode_table_row_col (MonoImage *image, int table, int idx, guint col)
+{
+ if (image->uncompressed_metadata)
+ idx = mono_metadata_translate_token_index (image, table, idx + 1) - 1;
+
+ return mono_metadata_decode_row_col (&image->tables [table], idx, col);
+}
+