SizeCalculator.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using System;
  2. using System.Reflection;
  3. namespace Ryujinx.Graphics.Device
  4. {
  5. public static class SizeCalculator
  6. {
  7. public static int SizeOf(Type type)
  8. {
  9. // Is type a enum type?
  10. if (type.IsEnum)
  11. {
  12. type = type.GetEnumUnderlyingType();
  13. }
  14. // Is type a pointer type?
  15. if (type.IsPointer || type == typeof(IntPtr) || type == typeof(UIntPtr))
  16. {
  17. return IntPtr.Size;
  18. }
  19. // Is type a struct type?
  20. if (type.IsValueType && !type.IsPrimitive)
  21. {
  22. // Check if the struct has a explicit size, if so, return that.
  23. if (type.StructLayoutAttribute.Size != 0)
  24. {
  25. return type.StructLayoutAttribute.Size;
  26. }
  27. // Otherwise we calculate the sum of the sizes of all fields.
  28. int size = 0;
  29. var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  30. for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++)
  31. {
  32. size += SizeOf(fields[fieldIndex].FieldType);
  33. }
  34. return size;
  35. }
  36. // Primitive types.
  37. return (Type.GetTypeCode(type)) switch
  38. {
  39. TypeCode.SByte => sizeof(sbyte),
  40. TypeCode.Byte => sizeof(byte),
  41. TypeCode.Int16 => sizeof(short),
  42. TypeCode.UInt16 => sizeof(ushort),
  43. TypeCode.Int32 => sizeof(int),
  44. TypeCode.UInt32 => sizeof(uint),
  45. TypeCode.Int64 => sizeof(long),
  46. TypeCode.UInt64 => sizeof(ulong),
  47. TypeCode.Char => sizeof(char),
  48. TypeCode.Single => sizeof(float),
  49. TypeCode.Double => sizeof(double),
  50. TypeCode.Decimal => sizeof(decimal),
  51. TypeCode.Boolean => sizeof(bool),
  52. _ => throw new ArgumentException($"Length for type \"{type.Name}\" is unknown."),
  53. };
  54. }
  55. }
  56. }