public static DataType convertTypeCodeToDataType(CliElementType typeCode) {
		/*
		TODO:
		ELEMENT_TYPE_VALUETYPE(0x11),
		ELEMENT_TYPE_VAR(0x13), // "Class type variable VAR"
		(0x16),

		ELEMENT_TYPE_MVAR(0x1e), // Method type variable MVAR

		ELEMENT_TYPE_INTERNAL(0x21), // Internal (generated internally, "will not be persisted in any way")
		ELEMENT_TYPE_MAX(0x22),

		*/

		switch (typeCode) {
			case ELEMENT_TYPE_VOID:
				return VoidDataType.dataType;

			case ELEMENT_TYPE_BOOLEAN:
				return BooleanDataType.dataType;
			case ELEMENT_TYPE_CHAR:
				return CharDataType.dataType;
			case ELEMENT_TYPE_I1:
				return SignedByteDataType.dataType;
			case ELEMENT_TYPE_U1:
				return ByteDataType.dataType;

			case ELEMENT_TYPE_I2:
				return ShortDataType.dataType;
			case ELEMENT_TYPE_U2:
				return UnsignedShortDataType.dataType;

			case ELEMENT_TYPE_I4:
				return IntegerDataType.dataType;
			case ELEMENT_TYPE_U4:
				return UnsignedIntegerDataType.dataType;

			case ELEMENT_TYPE_R4:
				return Float4DataType.dataType;
			case ELEMENT_TYPE_R8:
				return Float8DataType.dataType;

			case ELEMENT_TYPE_I8:
				return LongLongDataType.dataType;
			case ELEMENT_TYPE_U8:
				return UnsignedLongLongDataType.dataType;

			// TODO: Does this change for native architectures other than 32-bit?
			case ELEMENT_TYPE_I:
				return IntegerDataType.dataType;
			case ELEMENT_TYPE_U:
				return UnsignedIntegerDataType.dataType;

			case ELEMENT_TYPE_PTR:
				return PointerDataType.dataType;
			case ELEMENT_TYPE_FNPTR:
				return PointerDataType.dataType;

			case ELEMENT_TYPE_STRING:
				return new PointerDataType(new CharDataType());
			case ELEMENT_TYPE_ARRAY:
			case ELEMENT_TYPE_SZARRAY:
			case ELEMENT_TYPE_VAR:
			case ELEMENT_TYPE_MVAR:
				return new PointerDataType(new ByteDataType());

			case ELEMENT_TYPE_OBJECT: // System.Object
			case ELEMENT_TYPE_CLASS:
			case ELEMENT_TYPE_VALUETYPE:
			case ELEMENT_TYPE_GENERICINST:
				return PointerDataType.dataType;

			case ELEMENT_TYPE_SENTINEL:
				return Undefined1DataType.dataType;

			default:
				return VoidDataType.dataType;
		}
	}
This is the method that subclasses should override. If stream is null, the method must not cause a NullPointerException,
i.e. it must handle this as if there was no stream to begin with.
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliAbstractSig.java