private static long GetHdfTypeIdFromType(Type type)
        {
            var elementType = type.IsArray ? type.GetElementType() : type;

            if (elementType == typeof(bool))
            {
                return(H5T.NATIVE_UINT8);
            }

            else if (elementType == typeof(byte))
            {
                return(H5T.NATIVE_UINT8);
            }

            else if (elementType == typeof(sbyte))
            {
                return(H5T.NATIVE_INT8);
            }

            else if (elementType == typeof(ushort))
            {
                return(H5T.NATIVE_UINT16);
            }

            else if (elementType == typeof(short))
            {
                return(H5T.NATIVE_INT16);
            }

            else if (elementType == typeof(uint))
            {
                return(H5T.NATIVE_UINT32);
            }

            else if (elementType == typeof(int))
            {
                return(H5T.NATIVE_INT32);
            }

            else if (elementType == typeof(ulong))
            {
                return(H5T.NATIVE_UINT64);
            }

            else if (elementType == typeof(long))
            {
                return(H5T.NATIVE_INT64);
            }

            else if (elementType == typeof(float))
            {
                return(H5T.NATIVE_FLOAT);
            }

            else if (elementType == typeof(double))
            {
                return(H5T.NATIVE_DOUBLE);
            }

            // issues: https://en.wikipedia.org/wiki/Long_double
            //else if (elementType == typeof(decimal))
            //    return H5T.NATIVE_LDOUBLE;

            else if (elementType.IsEnum)
            {
                var baseTypeId = TestUtils.GetHdfTypeIdFromType(Enum.GetUnderlyingType(elementType));
                var typeId     = H5T.enum_create(baseTypeId);

                foreach (var value in Enum.GetValues(type))
                {
                    var value_converted = Convert.ToInt64(value);
                    var name            = Enum.GetName(type, value_converted);

                    var handle = GCHandle.Alloc(value_converted, GCHandleType.Pinned);
                    H5T.enum_insert(typeId, name, handle.AddrOfPinnedObject());
                }

                return(typeId);
            }

            else if (elementType == typeof(string) || elementType == typeof(IntPtr))
            {
                var typeId = H5T.copy(H5T.C_S1);

                H5T.set_size(typeId, H5T.VARIABLE);
                H5T.set_cset(typeId, H5T.cset_t.UTF8);

                return(typeId);
            }
            else if (elementType.IsValueType && !elementType.IsPrimitive)
            {
                var typeId = H5T.create(H5T.class_t.COMPOUND, new IntPtr(Marshal.SizeOf(elementType)));

                foreach (var fieldInfo in elementType.GetFields())
                {
                    var fieldType    = TestUtils.GetHdfTypeIdFromType(fieldInfo.FieldType);
                    var attribute    = fieldInfo.GetCustomAttribute <H5NameAttribute>(true);
                    var hdfFieldName = attribute is not null ? attribute.Name : fieldInfo.Name;

                    H5T.insert(typeId, hdfFieldName, Marshal.OffsetOf(elementType, fieldInfo.Name), fieldType);

                    if (H5I.is_valid(fieldType) > 0)
                    {
                        H5T.close(fieldType);
                    }
                }

                return(typeId);
            }
            else
            {
                throw new NotSupportedException();
            }
        }