//------------------------------------------------------------------------------ // // This code was generated by a tool. // // TextTransform Samples/Packages/com.unity.collections/Unity.Collections/FixedString.tt // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ using System.Collections.Generic; using System.Collections; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System; using Unity.Collections.LowLevel.Unsafe; using Unity.Mathematics; using UnityEngine.Internal; using UnityEngine; using Unity.Properties; namespace Unity.Collections { // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. This type is 8 byte aligned /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=16)] [GenerateTestsForBurstCompatibility] internal struct FixedBytes16Align8 { /// /// For internal use only. /// [SerializeField] [FieldOffset(0)] public ulong byte0000; /// /// For internal use only. /// [SerializeField] [FieldOffset(8)] public ulong byte0008; } /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=16)] [GenerateTestsForBurstCompatibility] public struct FixedBytes16 { /// /// For internal use only. /// [FieldOffset(0)] public byte byte0000; /// /// For internal use only. /// [FieldOffset(1)] public byte byte0001; /// /// For internal use only. /// [FieldOffset(2)] public byte byte0002; /// /// For internal use only. /// [FieldOffset(3)] public byte byte0003; /// /// For internal use only. /// [FieldOffset(4)] public byte byte0004; /// /// For internal use only. /// [FieldOffset(5)] public byte byte0005; /// /// For internal use only. /// [FieldOffset(6)] public byte byte0006; /// /// For internal use only. /// [FieldOffset(7)] public byte byte0007; /// /// For internal use only. /// [FieldOffset(8)] public byte byte0008; /// /// For internal use only. /// [FieldOffset(9)] public byte byte0009; /// /// For internal use only. /// [FieldOffset(10)] public byte byte0010; /// /// For internal use only. /// [FieldOffset(11)] public byte byte0011; /// /// For internal use only. /// [FieldOffset(12)] public byte byte0012; /// /// For internal use only. /// [FieldOffset(13)] public byte byte0013; /// /// For internal use only. /// [FieldOffset(14)] public byte byte0014; /// /// For internal use only. /// [FieldOffset(15)] public byte byte0015; } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=32)] [GenerateTestsForBurstCompatibility] internal struct FixedBytes32Align8 { /// /// For internal use only. /// [SerializeField] [FieldOffset(0)] internal FixedBytes16Align8 offset0000; /// /// For internal use only. /// [SerializeField] [FieldOffset(16)] internal FixedBytes16Align8 offset0016; } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=64)] [GenerateTestsForBurstCompatibility] internal struct FixedBytes64Align8 { /// /// For internal use only. /// [SerializeField] [FieldOffset(0)] internal FixedBytes16Align8 offset0000; /// /// For internal use only. /// [SerializeField] [FieldOffset(16)] internal FixedBytes16Align8 offset0016; /// /// For internal use only. /// [SerializeField] [FieldOffset(32)] internal FixedBytes16Align8 offset0032; /// /// For internal use only. /// [SerializeField] [FieldOffset(48)] internal FixedBytes16Align8 offset0048; } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=128)] [GenerateTestsForBurstCompatibility] internal struct FixedBytes128Align8 { /// /// For internal use only. /// [SerializeField] [FieldOffset(0)] internal FixedBytes16Align8 offset0000; /// /// For internal use only. /// [SerializeField] [FieldOffset(16)] internal FixedBytes16Align8 offset0016; /// /// For internal use only. /// [SerializeField] [FieldOffset(32)] internal FixedBytes16Align8 offset0032; /// /// For internal use only. /// [SerializeField] [FieldOffset(48)] internal FixedBytes16Align8 offset0048; /// /// For internal use only. /// [SerializeField] [FieldOffset(64)] internal FixedBytes16Align8 offset0064; /// /// For internal use only. /// [SerializeField] [FieldOffset(80)] internal FixedBytes16Align8 offset0080; /// /// For internal use only. /// [SerializeField] [FieldOffset(96)] internal FixedBytes16Align8 offset0096; /// /// For internal use only. /// [SerializeField] [FieldOffset(112)] internal FixedBytes16Align8 offset0112; } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=512)] [GenerateTestsForBurstCompatibility] internal struct FixedBytes512Align8 { /// /// For internal use only. /// [SerializeField] [FieldOffset(0)] internal FixedBytes16Align8 offset0000; /// /// For internal use only. /// [SerializeField] [FieldOffset(16)] internal FixedBytes16Align8 offset0016; /// /// For internal use only. /// [SerializeField] [FieldOffset(32)] internal FixedBytes16Align8 offset0032; /// /// For internal use only. /// [SerializeField] [FieldOffset(48)] internal FixedBytes16Align8 offset0048; /// /// For internal use only. /// [SerializeField] [FieldOffset(64)] internal FixedBytes16Align8 offset0064; /// /// For internal use only. /// [SerializeField] [FieldOffset(80)] internal FixedBytes16Align8 offset0080; /// /// For internal use only. /// [SerializeField] [FieldOffset(96)] internal FixedBytes16Align8 offset0096; /// /// For internal use only. /// [SerializeField] [FieldOffset(112)] internal FixedBytes16Align8 offset0112; /// /// For internal use only. /// [SerializeField] [FieldOffset(128)] internal FixedBytes16Align8 offset0128; /// /// For internal use only. /// [SerializeField] [FieldOffset(144)] internal FixedBytes16Align8 offset0144; /// /// For internal use only. /// [SerializeField] [FieldOffset(160)] internal FixedBytes16Align8 offset0160; /// /// For internal use only. /// [SerializeField] [FieldOffset(176)] internal FixedBytes16Align8 offset0176; /// /// For internal use only. /// [SerializeField] [FieldOffset(192)] internal FixedBytes16Align8 offset0192; /// /// For internal use only. /// [SerializeField] [FieldOffset(208)] internal FixedBytes16Align8 offset0208; /// /// For internal use only. /// [SerializeField] [FieldOffset(224)] internal FixedBytes16Align8 offset0224; /// /// For internal use only. /// [SerializeField] [FieldOffset(240)] internal FixedBytes16Align8 offset0240; /// /// For internal use only. /// [SerializeField] [FieldOffset(256)] internal FixedBytes16Align8 offset0256; /// /// For internal use only. /// [SerializeField] [FieldOffset(272)] internal FixedBytes16Align8 offset0272; /// /// For internal use only. /// [SerializeField] [FieldOffset(288)] internal FixedBytes16Align8 offset0288; /// /// For internal use only. /// [SerializeField] [FieldOffset(304)] internal FixedBytes16Align8 offset0304; /// /// For internal use only. /// [SerializeField] [FieldOffset(320)] internal FixedBytes16Align8 offset0320; /// /// For internal use only. /// [SerializeField] [FieldOffset(336)] internal FixedBytes16Align8 offset0336; /// /// For internal use only. /// [SerializeField] [FieldOffset(352)] internal FixedBytes16Align8 offset0352; /// /// For internal use only. /// [SerializeField] [FieldOffset(368)] internal FixedBytes16Align8 offset0368; /// /// For internal use only. /// [SerializeField] [FieldOffset(384)] internal FixedBytes16Align8 offset0384; /// /// For internal use only. /// [SerializeField] [FieldOffset(400)] internal FixedBytes16Align8 offset0400; /// /// For internal use only. /// [SerializeField] [FieldOffset(416)] internal FixedBytes16Align8 offset0416; /// /// For internal use only. /// [SerializeField] [FieldOffset(432)] internal FixedBytes16Align8 offset0432; /// /// For internal use only. /// [SerializeField] [FieldOffset(448)] internal FixedBytes16Align8 offset0448; /// /// For internal use only. /// [SerializeField] [FieldOffset(464)] internal FixedBytes16Align8 offset0464; /// /// For internal use only. /// [SerializeField] [FieldOffset(480)] internal FixedBytes16Align8 offset0480; /// /// For internal use only. /// [SerializeField] [FieldOffset(496)] internal FixedBytes16Align8 offset0496; } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=4096)] [GenerateTestsForBurstCompatibility] internal struct FixedBytes4096Align8 { /// /// For internal use only. /// [SerializeField] [FieldOffset(0)] internal FixedBytes16Align8 offset0000; /// /// For internal use only. /// [SerializeField] [FieldOffset(16)] internal FixedBytes16Align8 offset0016; /// /// For internal use only. /// [SerializeField] [FieldOffset(32)] internal FixedBytes16Align8 offset0032; /// /// For internal use only. /// [SerializeField] [FieldOffset(48)] internal FixedBytes16Align8 offset0048; /// /// For internal use only. /// [SerializeField] [FieldOffset(64)] internal FixedBytes16Align8 offset0064; /// /// For internal use only. /// [SerializeField] [FieldOffset(80)] internal FixedBytes16Align8 offset0080; /// /// For internal use only. /// [SerializeField] [FieldOffset(96)] internal FixedBytes16Align8 offset0096; /// /// For internal use only. /// [SerializeField] [FieldOffset(112)] internal FixedBytes16Align8 offset0112; /// /// For internal use only. /// [SerializeField] [FieldOffset(128)] internal FixedBytes16Align8 offset0128; /// /// For internal use only. /// [SerializeField] [FieldOffset(144)] internal FixedBytes16Align8 offset0144; /// /// For internal use only. /// [SerializeField] [FieldOffset(160)] internal FixedBytes16Align8 offset0160; /// /// For internal use only. /// [SerializeField] [FieldOffset(176)] internal FixedBytes16Align8 offset0176; /// /// For internal use only. /// [SerializeField] [FieldOffset(192)] internal FixedBytes16Align8 offset0192; /// /// For internal use only. /// [SerializeField] [FieldOffset(208)] internal FixedBytes16Align8 offset0208; /// /// For internal use only. /// [SerializeField] [FieldOffset(224)] internal FixedBytes16Align8 offset0224; /// /// For internal use only. /// [SerializeField] [FieldOffset(240)] internal FixedBytes16Align8 offset0240; /// /// For internal use only. /// [SerializeField] [FieldOffset(256)] internal FixedBytes16Align8 offset0256; /// /// For internal use only. /// [SerializeField] [FieldOffset(272)] internal FixedBytes16Align8 offset0272; /// /// For internal use only. /// [SerializeField] [FieldOffset(288)] internal FixedBytes16Align8 offset0288; /// /// For internal use only. /// [SerializeField] [FieldOffset(304)] internal FixedBytes16Align8 offset0304; /// /// For internal use only. /// [SerializeField] [FieldOffset(320)] internal FixedBytes16Align8 offset0320; /// /// For internal use only. /// [SerializeField] [FieldOffset(336)] internal FixedBytes16Align8 offset0336; /// /// For internal use only. /// [SerializeField] [FieldOffset(352)] internal FixedBytes16Align8 offset0352; /// /// For internal use only. /// [SerializeField] [FieldOffset(368)] internal FixedBytes16Align8 offset0368; /// /// For internal use only. /// [SerializeField] [FieldOffset(384)] internal FixedBytes16Align8 offset0384; /// /// For internal use only. /// [SerializeField] [FieldOffset(400)] internal FixedBytes16Align8 offset0400; /// /// For internal use only. /// [SerializeField] [FieldOffset(416)] internal FixedBytes16Align8 offset0416; /// /// For internal use only. /// [SerializeField] [FieldOffset(432)] internal FixedBytes16Align8 offset0432; /// /// For internal use only. /// [SerializeField] [FieldOffset(448)] internal FixedBytes16Align8 offset0448; /// /// For internal use only. /// [SerializeField] [FieldOffset(464)] internal FixedBytes16Align8 offset0464; /// /// For internal use only. /// [SerializeField] [FieldOffset(480)] internal FixedBytes16Align8 offset0480; /// /// For internal use only. /// [SerializeField] [FieldOffset(496)] internal FixedBytes16Align8 offset0496; /// /// For internal use only. /// [SerializeField] [FieldOffset(512)] internal FixedBytes16Align8 offset0512; /// /// For internal use only. /// [SerializeField] [FieldOffset(528)] internal FixedBytes16Align8 offset0528; /// /// For internal use only. /// [SerializeField] [FieldOffset(544)] internal FixedBytes16Align8 offset0544; /// /// For internal use only. /// [SerializeField] [FieldOffset(560)] internal FixedBytes16Align8 offset0560; /// /// For internal use only. /// [SerializeField] [FieldOffset(576)] internal FixedBytes16Align8 offset0576; /// /// For internal use only. /// [SerializeField] [FieldOffset(592)] internal FixedBytes16Align8 offset0592; /// /// For internal use only. /// [SerializeField] [FieldOffset(608)] internal FixedBytes16Align8 offset0608; /// /// For internal use only. /// [SerializeField] [FieldOffset(624)] internal FixedBytes16Align8 offset0624; /// /// For internal use only. /// [SerializeField] [FieldOffset(640)] internal FixedBytes16Align8 offset0640; /// /// For internal use only. /// [SerializeField] [FieldOffset(656)] internal FixedBytes16Align8 offset0656; /// /// For internal use only. /// [SerializeField] [FieldOffset(672)] internal FixedBytes16Align8 offset0672; /// /// For internal use only. /// [SerializeField] [FieldOffset(688)] internal FixedBytes16Align8 offset0688; /// /// For internal use only. /// [SerializeField] [FieldOffset(704)] internal FixedBytes16Align8 offset0704; /// /// For internal use only. /// [SerializeField] [FieldOffset(720)] internal FixedBytes16Align8 offset0720; /// /// For internal use only. /// [SerializeField] [FieldOffset(736)] internal FixedBytes16Align8 offset0736; /// /// For internal use only. /// [SerializeField] [FieldOffset(752)] internal FixedBytes16Align8 offset0752; /// /// For internal use only. /// [SerializeField] [FieldOffset(768)] internal FixedBytes16Align8 offset0768; /// /// For internal use only. /// [SerializeField] [FieldOffset(784)] internal FixedBytes16Align8 offset0784; /// /// For internal use only. /// [SerializeField] [FieldOffset(800)] internal FixedBytes16Align8 offset0800; /// /// For internal use only. /// [SerializeField] [FieldOffset(816)] internal FixedBytes16Align8 offset0816; /// /// For internal use only. /// [SerializeField] [FieldOffset(832)] internal FixedBytes16Align8 offset0832; /// /// For internal use only. /// [SerializeField] [FieldOffset(848)] internal FixedBytes16Align8 offset0848; /// /// For internal use only. /// [SerializeField] [FieldOffset(864)] internal FixedBytes16Align8 offset0864; /// /// For internal use only. /// [SerializeField] [FieldOffset(880)] internal FixedBytes16Align8 offset0880; /// /// For internal use only. /// [SerializeField] [FieldOffset(896)] internal FixedBytes16Align8 offset0896; /// /// For internal use only. /// [SerializeField] [FieldOffset(912)] internal FixedBytes16Align8 offset0912; /// /// For internal use only. /// [SerializeField] [FieldOffset(928)] internal FixedBytes16Align8 offset0928; /// /// For internal use only. /// [SerializeField] [FieldOffset(944)] internal FixedBytes16Align8 offset0944; /// /// For internal use only. /// [SerializeField] [FieldOffset(960)] internal FixedBytes16Align8 offset0960; /// /// For internal use only. /// [SerializeField] [FieldOffset(976)] internal FixedBytes16Align8 offset0976; /// /// For internal use only. /// [SerializeField] [FieldOffset(992)] internal FixedBytes16Align8 offset0992; /// /// For internal use only. /// [SerializeField] [FieldOffset(1008)] internal FixedBytes16Align8 offset1008; /// /// For internal use only. /// [SerializeField] [FieldOffset(1024)] internal FixedBytes16Align8 offset1024; /// /// For internal use only. /// [SerializeField] [FieldOffset(1040)] internal FixedBytes16Align8 offset1040; /// /// For internal use only. /// [SerializeField] [FieldOffset(1056)] internal FixedBytes16Align8 offset1056; /// /// For internal use only. /// [SerializeField] [FieldOffset(1072)] internal FixedBytes16Align8 offset1072; /// /// For internal use only. /// [SerializeField] [FieldOffset(1088)] internal FixedBytes16Align8 offset1088; /// /// For internal use only. /// [SerializeField] [FieldOffset(1104)] internal FixedBytes16Align8 offset1104; /// /// For internal use only. /// [SerializeField] [FieldOffset(1120)] internal FixedBytes16Align8 offset1120; /// /// For internal use only. /// [SerializeField] [FieldOffset(1136)] internal FixedBytes16Align8 offset1136; /// /// For internal use only. /// [SerializeField] [FieldOffset(1152)] internal FixedBytes16Align8 offset1152; /// /// For internal use only. /// [SerializeField] [FieldOffset(1168)] internal FixedBytes16Align8 offset1168; /// /// For internal use only. /// [SerializeField] [FieldOffset(1184)] internal FixedBytes16Align8 offset1184; /// /// For internal use only. /// [SerializeField] [FieldOffset(1200)] internal FixedBytes16Align8 offset1200; /// /// For internal use only. /// [SerializeField] [FieldOffset(1216)] internal FixedBytes16Align8 offset1216; /// /// For internal use only. /// [SerializeField] [FieldOffset(1232)] internal FixedBytes16Align8 offset1232; /// /// For internal use only. /// [SerializeField] [FieldOffset(1248)] internal FixedBytes16Align8 offset1248; /// /// For internal use only. /// [SerializeField] [FieldOffset(1264)] internal FixedBytes16Align8 offset1264; /// /// For internal use only. /// [SerializeField] [FieldOffset(1280)] internal FixedBytes16Align8 offset1280; /// /// For internal use only. /// [SerializeField] [FieldOffset(1296)] internal FixedBytes16Align8 offset1296; /// /// For internal use only. /// [SerializeField] [FieldOffset(1312)] internal FixedBytes16Align8 offset1312; /// /// For internal use only. /// [SerializeField] [FieldOffset(1328)] internal FixedBytes16Align8 offset1328; /// /// For internal use only. /// [SerializeField] [FieldOffset(1344)] internal FixedBytes16Align8 offset1344; /// /// For internal use only. /// [SerializeField] [FieldOffset(1360)] internal FixedBytes16Align8 offset1360; /// /// For internal use only. /// [SerializeField] [FieldOffset(1376)] internal FixedBytes16Align8 offset1376; /// /// For internal use only. /// [SerializeField] [FieldOffset(1392)] internal FixedBytes16Align8 offset1392; /// /// For internal use only. /// [SerializeField] [FieldOffset(1408)] internal FixedBytes16Align8 offset1408; /// /// For internal use only. /// [SerializeField] [FieldOffset(1424)] internal FixedBytes16Align8 offset1424; /// /// For internal use only. /// [SerializeField] [FieldOffset(1440)] internal FixedBytes16Align8 offset1440; /// /// For internal use only. /// [SerializeField] [FieldOffset(1456)] internal FixedBytes16Align8 offset1456; /// /// For internal use only. /// [SerializeField] [FieldOffset(1472)] internal FixedBytes16Align8 offset1472; /// /// For internal use only. /// [SerializeField] [FieldOffset(1488)] internal FixedBytes16Align8 offset1488; /// /// For internal use only. /// [SerializeField] [FieldOffset(1504)] internal FixedBytes16Align8 offset1504; /// /// For internal use only. /// [SerializeField] [FieldOffset(1520)] internal FixedBytes16Align8 offset1520; /// /// For internal use only. /// [SerializeField] [FieldOffset(1536)] internal FixedBytes16Align8 offset1536; /// /// For internal use only. /// [SerializeField] [FieldOffset(1552)] internal FixedBytes16Align8 offset1552; /// /// For internal use only. /// [SerializeField] [FieldOffset(1568)] internal FixedBytes16Align8 offset1568; /// /// For internal use only. /// [SerializeField] [FieldOffset(1584)] internal FixedBytes16Align8 offset1584; /// /// For internal use only. /// [SerializeField] [FieldOffset(1600)] internal FixedBytes16Align8 offset1600; /// /// For internal use only. /// [SerializeField] [FieldOffset(1616)] internal FixedBytes16Align8 offset1616; /// /// For internal use only. /// [SerializeField] [FieldOffset(1632)] internal FixedBytes16Align8 offset1632; /// /// For internal use only. /// [SerializeField] [FieldOffset(1648)] internal FixedBytes16Align8 offset1648; /// /// For internal use only. /// [SerializeField] [FieldOffset(1664)] internal FixedBytes16Align8 offset1664; /// /// For internal use only. /// [SerializeField] [FieldOffset(1680)] internal FixedBytes16Align8 offset1680; /// /// For internal use only. /// [SerializeField] [FieldOffset(1696)] internal FixedBytes16Align8 offset1696; /// /// For internal use only. /// [SerializeField] [FieldOffset(1712)] internal FixedBytes16Align8 offset1712; /// /// For internal use only. /// [SerializeField] [FieldOffset(1728)] internal FixedBytes16Align8 offset1728; /// /// For internal use only. /// [SerializeField] [FieldOffset(1744)] internal FixedBytes16Align8 offset1744; /// /// For internal use only. /// [SerializeField] [FieldOffset(1760)] internal FixedBytes16Align8 offset1760; /// /// For internal use only. /// [SerializeField] [FieldOffset(1776)] internal FixedBytes16Align8 offset1776; /// /// For internal use only. /// [SerializeField] [FieldOffset(1792)] internal FixedBytes16Align8 offset1792; /// /// For internal use only. /// [SerializeField] [FieldOffset(1808)] internal FixedBytes16Align8 offset1808; /// /// For internal use only. /// [SerializeField] [FieldOffset(1824)] internal FixedBytes16Align8 offset1824; /// /// For internal use only. /// [SerializeField] [FieldOffset(1840)] internal FixedBytes16Align8 offset1840; /// /// For internal use only. /// [SerializeField] [FieldOffset(1856)] internal FixedBytes16Align8 offset1856; /// /// For internal use only. /// [SerializeField] [FieldOffset(1872)] internal FixedBytes16Align8 offset1872; /// /// For internal use only. /// [SerializeField] [FieldOffset(1888)] internal FixedBytes16Align8 offset1888; /// /// For internal use only. /// [SerializeField] [FieldOffset(1904)] internal FixedBytes16Align8 offset1904; /// /// For internal use only. /// [SerializeField] [FieldOffset(1920)] internal FixedBytes16Align8 offset1920; /// /// For internal use only. /// [SerializeField] [FieldOffset(1936)] internal FixedBytes16Align8 offset1936; /// /// For internal use only. /// [SerializeField] [FieldOffset(1952)] internal FixedBytes16Align8 offset1952; /// /// For internal use only. /// [SerializeField] [FieldOffset(1968)] internal FixedBytes16Align8 offset1968; /// /// For internal use only. /// [SerializeField] [FieldOffset(1984)] internal FixedBytes16Align8 offset1984; /// /// For internal use only. /// [SerializeField] [FieldOffset(2000)] internal FixedBytes16Align8 offset2000; /// /// For internal use only. /// [SerializeField] [FieldOffset(2016)] internal FixedBytes16Align8 offset2016; /// /// For internal use only. /// [SerializeField] [FieldOffset(2032)] internal FixedBytes16Align8 offset2032; /// /// For internal use only. /// [SerializeField] [FieldOffset(2048)] internal FixedBytes16Align8 offset2048; /// /// For internal use only. /// [SerializeField] [FieldOffset(2064)] internal FixedBytes16Align8 offset2064; /// /// For internal use only. /// [SerializeField] [FieldOffset(2080)] internal FixedBytes16Align8 offset2080; /// /// For internal use only. /// [SerializeField] [FieldOffset(2096)] internal FixedBytes16Align8 offset2096; /// /// For internal use only. /// [SerializeField] [FieldOffset(2112)] internal FixedBytes16Align8 offset2112; /// /// For internal use only. /// [SerializeField] [FieldOffset(2128)] internal FixedBytes16Align8 offset2128; /// /// For internal use only. /// [SerializeField] [FieldOffset(2144)] internal FixedBytes16Align8 offset2144; /// /// For internal use only. /// [SerializeField] [FieldOffset(2160)] internal FixedBytes16Align8 offset2160; /// /// For internal use only. /// [SerializeField] [FieldOffset(2176)] internal FixedBytes16Align8 offset2176; /// /// For internal use only. /// [SerializeField] [FieldOffset(2192)] internal FixedBytes16Align8 offset2192; /// /// For internal use only. /// [SerializeField] [FieldOffset(2208)] internal FixedBytes16Align8 offset2208; /// /// For internal use only. /// [SerializeField] [FieldOffset(2224)] internal FixedBytes16Align8 offset2224; /// /// For internal use only. /// [SerializeField] [FieldOffset(2240)] internal FixedBytes16Align8 offset2240; /// /// For internal use only. /// [SerializeField] [FieldOffset(2256)] internal FixedBytes16Align8 offset2256; /// /// For internal use only. /// [SerializeField] [FieldOffset(2272)] internal FixedBytes16Align8 offset2272; /// /// For internal use only. /// [SerializeField] [FieldOffset(2288)] internal FixedBytes16Align8 offset2288; /// /// For internal use only. /// [SerializeField] [FieldOffset(2304)] internal FixedBytes16Align8 offset2304; /// /// For internal use only. /// [SerializeField] [FieldOffset(2320)] internal FixedBytes16Align8 offset2320; /// /// For internal use only. /// [SerializeField] [FieldOffset(2336)] internal FixedBytes16Align8 offset2336; /// /// For internal use only. /// [SerializeField] [FieldOffset(2352)] internal FixedBytes16Align8 offset2352; /// /// For internal use only. /// [SerializeField] [FieldOffset(2368)] internal FixedBytes16Align8 offset2368; /// /// For internal use only. /// [SerializeField] [FieldOffset(2384)] internal FixedBytes16Align8 offset2384; /// /// For internal use only. /// [SerializeField] [FieldOffset(2400)] internal FixedBytes16Align8 offset2400; /// /// For internal use only. /// [SerializeField] [FieldOffset(2416)] internal FixedBytes16Align8 offset2416; /// /// For internal use only. /// [SerializeField] [FieldOffset(2432)] internal FixedBytes16Align8 offset2432; /// /// For internal use only. /// [SerializeField] [FieldOffset(2448)] internal FixedBytes16Align8 offset2448; /// /// For internal use only. /// [SerializeField] [FieldOffset(2464)] internal FixedBytes16Align8 offset2464; /// /// For internal use only. /// [SerializeField] [FieldOffset(2480)] internal FixedBytes16Align8 offset2480; /// /// For internal use only. /// [SerializeField] [FieldOffset(2496)] internal FixedBytes16Align8 offset2496; /// /// For internal use only. /// [SerializeField] [FieldOffset(2512)] internal FixedBytes16Align8 offset2512; /// /// For internal use only. /// [SerializeField] [FieldOffset(2528)] internal FixedBytes16Align8 offset2528; /// /// For internal use only. /// [SerializeField] [FieldOffset(2544)] internal FixedBytes16Align8 offset2544; /// /// For internal use only. /// [SerializeField] [FieldOffset(2560)] internal FixedBytes16Align8 offset2560; /// /// For internal use only. /// [SerializeField] [FieldOffset(2576)] internal FixedBytes16Align8 offset2576; /// /// For internal use only. /// [SerializeField] [FieldOffset(2592)] internal FixedBytes16Align8 offset2592; /// /// For internal use only. /// [SerializeField] [FieldOffset(2608)] internal FixedBytes16Align8 offset2608; /// /// For internal use only. /// [SerializeField] [FieldOffset(2624)] internal FixedBytes16Align8 offset2624; /// /// For internal use only. /// [SerializeField] [FieldOffset(2640)] internal FixedBytes16Align8 offset2640; /// /// For internal use only. /// [SerializeField] [FieldOffset(2656)] internal FixedBytes16Align8 offset2656; /// /// For internal use only. /// [SerializeField] [FieldOffset(2672)] internal FixedBytes16Align8 offset2672; /// /// For internal use only. /// [SerializeField] [FieldOffset(2688)] internal FixedBytes16Align8 offset2688; /// /// For internal use only. /// [SerializeField] [FieldOffset(2704)] internal FixedBytes16Align8 offset2704; /// /// For internal use only. /// [SerializeField] [FieldOffset(2720)] internal FixedBytes16Align8 offset2720; /// /// For internal use only. /// [SerializeField] [FieldOffset(2736)] internal FixedBytes16Align8 offset2736; /// /// For internal use only. /// [SerializeField] [FieldOffset(2752)] internal FixedBytes16Align8 offset2752; /// /// For internal use only. /// [SerializeField] [FieldOffset(2768)] internal FixedBytes16Align8 offset2768; /// /// For internal use only. /// [SerializeField] [FieldOffset(2784)] internal FixedBytes16Align8 offset2784; /// /// For internal use only. /// [SerializeField] [FieldOffset(2800)] internal FixedBytes16Align8 offset2800; /// /// For internal use only. /// [SerializeField] [FieldOffset(2816)] internal FixedBytes16Align8 offset2816; /// /// For internal use only. /// [SerializeField] [FieldOffset(2832)] internal FixedBytes16Align8 offset2832; /// /// For internal use only. /// [SerializeField] [FieldOffset(2848)] internal FixedBytes16Align8 offset2848; /// /// For internal use only. /// [SerializeField] [FieldOffset(2864)] internal FixedBytes16Align8 offset2864; /// /// For internal use only. /// [SerializeField] [FieldOffset(2880)] internal FixedBytes16Align8 offset2880; /// /// For internal use only. /// [SerializeField] [FieldOffset(2896)] internal FixedBytes16Align8 offset2896; /// /// For internal use only. /// [SerializeField] [FieldOffset(2912)] internal FixedBytes16Align8 offset2912; /// /// For internal use only. /// [SerializeField] [FieldOffset(2928)] internal FixedBytes16Align8 offset2928; /// /// For internal use only. /// [SerializeField] [FieldOffset(2944)] internal FixedBytes16Align8 offset2944; /// /// For internal use only. /// [SerializeField] [FieldOffset(2960)] internal FixedBytes16Align8 offset2960; /// /// For internal use only. /// [SerializeField] [FieldOffset(2976)] internal FixedBytes16Align8 offset2976; /// /// For internal use only. /// [SerializeField] [FieldOffset(2992)] internal FixedBytes16Align8 offset2992; /// /// For internal use only. /// [SerializeField] [FieldOffset(3008)] internal FixedBytes16Align8 offset3008; /// /// For internal use only. /// [SerializeField] [FieldOffset(3024)] internal FixedBytes16Align8 offset3024; /// /// For internal use only. /// [SerializeField] [FieldOffset(3040)] internal FixedBytes16Align8 offset3040; /// /// For internal use only. /// [SerializeField] [FieldOffset(3056)] internal FixedBytes16Align8 offset3056; /// /// For internal use only. /// [SerializeField] [FieldOffset(3072)] internal FixedBytes16Align8 offset3072; /// /// For internal use only. /// [SerializeField] [FieldOffset(3088)] internal FixedBytes16Align8 offset3088; /// /// For internal use only. /// [SerializeField] [FieldOffset(3104)] internal FixedBytes16Align8 offset3104; /// /// For internal use only. /// [SerializeField] [FieldOffset(3120)] internal FixedBytes16Align8 offset3120; /// /// For internal use only. /// [SerializeField] [FieldOffset(3136)] internal FixedBytes16Align8 offset3136; /// /// For internal use only. /// [SerializeField] [FieldOffset(3152)] internal FixedBytes16Align8 offset3152; /// /// For internal use only. /// [SerializeField] [FieldOffset(3168)] internal FixedBytes16Align8 offset3168; /// /// For internal use only. /// [SerializeField] [FieldOffset(3184)] internal FixedBytes16Align8 offset3184; /// /// For internal use only. /// [SerializeField] [FieldOffset(3200)] internal FixedBytes16Align8 offset3200; /// /// For internal use only. /// [SerializeField] [FieldOffset(3216)] internal FixedBytes16Align8 offset3216; /// /// For internal use only. /// [SerializeField] [FieldOffset(3232)] internal FixedBytes16Align8 offset3232; /// /// For internal use only. /// [SerializeField] [FieldOffset(3248)] internal FixedBytes16Align8 offset3248; /// /// For internal use only. /// [SerializeField] [FieldOffset(3264)] internal FixedBytes16Align8 offset3264; /// /// For internal use only. /// [SerializeField] [FieldOffset(3280)] internal FixedBytes16Align8 offset3280; /// /// For internal use only. /// [SerializeField] [FieldOffset(3296)] internal FixedBytes16Align8 offset3296; /// /// For internal use only. /// [SerializeField] [FieldOffset(3312)] internal FixedBytes16Align8 offset3312; /// /// For internal use only. /// [SerializeField] [FieldOffset(3328)] internal FixedBytes16Align8 offset3328; /// /// For internal use only. /// [SerializeField] [FieldOffset(3344)] internal FixedBytes16Align8 offset3344; /// /// For internal use only. /// [SerializeField] [FieldOffset(3360)] internal FixedBytes16Align8 offset3360; /// /// For internal use only. /// [SerializeField] [FieldOffset(3376)] internal FixedBytes16Align8 offset3376; /// /// For internal use only. /// [SerializeField] [FieldOffset(3392)] internal FixedBytes16Align8 offset3392; /// /// For internal use only. /// [SerializeField] [FieldOffset(3408)] internal FixedBytes16Align8 offset3408; /// /// For internal use only. /// [SerializeField] [FieldOffset(3424)] internal FixedBytes16Align8 offset3424; /// /// For internal use only. /// [SerializeField] [FieldOffset(3440)] internal FixedBytes16Align8 offset3440; /// /// For internal use only. /// [SerializeField] [FieldOffset(3456)] internal FixedBytes16Align8 offset3456; /// /// For internal use only. /// [SerializeField] [FieldOffset(3472)] internal FixedBytes16Align8 offset3472; /// /// For internal use only. /// [SerializeField] [FieldOffset(3488)] internal FixedBytes16Align8 offset3488; /// /// For internal use only. /// [SerializeField] [FieldOffset(3504)] internal FixedBytes16Align8 offset3504; /// /// For internal use only. /// [SerializeField] [FieldOffset(3520)] internal FixedBytes16Align8 offset3520; /// /// For internal use only. /// [SerializeField] [FieldOffset(3536)] internal FixedBytes16Align8 offset3536; /// /// For internal use only. /// [SerializeField] [FieldOffset(3552)] internal FixedBytes16Align8 offset3552; /// /// For internal use only. /// [SerializeField] [FieldOffset(3568)] internal FixedBytes16Align8 offset3568; /// /// For internal use only. /// [SerializeField] [FieldOffset(3584)] internal FixedBytes16Align8 offset3584; /// /// For internal use only. /// [SerializeField] [FieldOffset(3600)] internal FixedBytes16Align8 offset3600; /// /// For internal use only. /// [SerializeField] [FieldOffset(3616)] internal FixedBytes16Align8 offset3616; /// /// For internal use only. /// [SerializeField] [FieldOffset(3632)] internal FixedBytes16Align8 offset3632; /// /// For internal use only. /// [SerializeField] [FieldOffset(3648)] internal FixedBytes16Align8 offset3648; /// /// For internal use only. /// [SerializeField] [FieldOffset(3664)] internal FixedBytes16Align8 offset3664; /// /// For internal use only. /// [SerializeField] [FieldOffset(3680)] internal FixedBytes16Align8 offset3680; /// /// For internal use only. /// [SerializeField] [FieldOffset(3696)] internal FixedBytes16Align8 offset3696; /// /// For internal use only. /// [SerializeField] [FieldOffset(3712)] internal FixedBytes16Align8 offset3712; /// /// For internal use only. /// [SerializeField] [FieldOffset(3728)] internal FixedBytes16Align8 offset3728; /// /// For internal use only. /// [SerializeField] [FieldOffset(3744)] internal FixedBytes16Align8 offset3744; /// /// For internal use only. /// [SerializeField] [FieldOffset(3760)] internal FixedBytes16Align8 offset3760; /// /// For internal use only. /// [SerializeField] [FieldOffset(3776)] internal FixedBytes16Align8 offset3776; /// /// For internal use only. /// [SerializeField] [FieldOffset(3792)] internal FixedBytes16Align8 offset3792; /// /// For internal use only. /// [SerializeField] [FieldOffset(3808)] internal FixedBytes16Align8 offset3808; /// /// For internal use only. /// [SerializeField] [FieldOffset(3824)] internal FixedBytes16Align8 offset3824; /// /// For internal use only. /// [SerializeField] [FieldOffset(3840)] internal FixedBytes16Align8 offset3840; /// /// For internal use only. /// [SerializeField] [FieldOffset(3856)] internal FixedBytes16Align8 offset3856; /// /// For internal use only. /// [SerializeField] [FieldOffset(3872)] internal FixedBytes16Align8 offset3872; /// /// For internal use only. /// [SerializeField] [FieldOffset(3888)] internal FixedBytes16Align8 offset3888; /// /// For internal use only. /// [SerializeField] [FieldOffset(3904)] internal FixedBytes16Align8 offset3904; /// /// For internal use only. /// [SerializeField] [FieldOffset(3920)] internal FixedBytes16Align8 offset3920; /// /// For internal use only. /// [SerializeField] [FieldOffset(3936)] internal FixedBytes16Align8 offset3936; /// /// For internal use only. /// [SerializeField] [FieldOffset(3952)] internal FixedBytes16Align8 offset3952; /// /// For internal use only. /// [SerializeField] [FieldOffset(3968)] internal FixedBytes16Align8 offset3968; /// /// For internal use only. /// [SerializeField] [FieldOffset(3984)] internal FixedBytes16Align8 offset3984; /// /// For internal use only. /// [SerializeField] [FieldOffset(4000)] internal FixedBytes16Align8 offset4000; /// /// For internal use only. /// [SerializeField] [FieldOffset(4016)] internal FixedBytes16Align8 offset4016; /// /// For internal use only. /// [SerializeField] [FieldOffset(4032)] internal FixedBytes16Align8 offset4032; /// /// For internal use only. /// [SerializeField] [FieldOffset(4048)] internal FixedBytes16Align8 offset4048; /// /// For internal use only. /// [SerializeField] [FieldOffset(4064)] internal FixedBytes16Align8 offset4064; /// /// For internal use only. /// [SerializeField] [FieldOffset(4080)] internal FixedBytes16Align8 offset4080; } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=30)] [GenerateTestsForBurstCompatibility] public struct FixedBytes30 { /// /// For internal use only. /// [FieldOffset(0)] public FixedBytes16 offset0000; /// /// For internal use only. /// [FieldOffset(16)] public byte byte0016; /// /// For internal use only. /// [FieldOffset(17)] public byte byte0017; /// /// For internal use only. /// [FieldOffset(18)] public byte byte0018; /// /// For internal use only. /// [FieldOffset(19)] public byte byte0019; /// /// For internal use only. /// [FieldOffset(20)] public byte byte0020; /// /// For internal use only. /// [FieldOffset(21)] public byte byte0021; /// /// For internal use only. /// [FieldOffset(22)] public byte byte0022; /// /// For internal use only. /// [FieldOffset(23)] public byte byte0023; /// /// For internal use only. /// [FieldOffset(24)] public byte byte0024; /// /// For internal use only. /// [FieldOffset(25)] public byte byte0025; /// /// For internal use only. /// [FieldOffset(26)] public byte byte0026; /// /// For internal use only. /// [FieldOffset(27)] public byte byte0027; /// /// For internal use only. /// [FieldOffset(28)] public byte byte0028; /// /// For internal use only. /// [FieldOffset(29)] public byte byte0029; } /// /// An unmanaged UTF-8 string whose content is stored directly in the 32-byte struct. /// /// /// The binary layout of this string is guaranteed, for now and all time, to be a length (a little-endian two byte integer) /// followed by the bytes of the characters (with no padding). A zero byte always immediately follows the last character. /// Effectively, the number of bytes for storing characters is 3 less than 32 (two length bytes and one null byte). /// /// This layout is identical to a of bytes, thus allowing reinterpretation between FixedString32Bytes and FixedList32Bytes. /// /// By virtue of being an unmanaged, non-allocated struct with no pointers, this string is fully compatible with jobs and Burst compilation. /// Unlike managed string types, these strings can be put in any unmanaged ECS components, FixedList, or any other unmanaged structs. /// [Serializable] [StructLayout(LayoutKind.Sequential, Size=32)] [GenerateTestsForBurstCompatibility] public partial struct FixedString32Bytes : INativeList , IUTF8Bytes , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable { internal const ushort utf8MaxLengthInBytes = 29; [SerializeField] internal ushort utf8LengthInBytes; [SerializeField] internal FixedBytes30 bytes; /// /// Returns the maximum number of UTF-8 bytes that can be stored in this string. /// /// /// The maximum number of UTF-8 bytes that can be stored in this string. /// public static int UTF8MaxLengthInBytes => utf8MaxLengthInBytes; /// /// For internal use only. Use instead. /// /// For internal use only. Use instead. [CreateProperty] [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] [ExcludeFromBurstCompatTesting("Returns managed string")] public string Value => ToString(); /// /// Returns a pointer to the character bytes. /// /// /// The pointer returned by this method points into the internals of the target FixedString object. It is the /// caller's responsibility to ensure that the pointer is not used after the FixedString object is destroyed or goes /// out of scope. /// /// A pointer to the character bytes. [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly unsafe byte* GetUnsafePtr() { fixed(void* b = &bytes) return (byte*)b; } /// /// The current length in bytes of this string's content. /// /// /// The length value does not include the null-terminator byte. /// /// The new length in bytes of the string's content. /// Thrown if the new length is out of bounds. /// /// The current length in bytes of this string's content. /// public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8LengthInBytes; } set { CheckLengthInRange(value); utf8LengthInBytes = (ushort)value; unsafe { GetUnsafePtr()[utf8LengthInBytes] = 0; } } } /// /// The number of bytes this string has for storing UTF-8 characters. /// /// The number of bytes this string has for storing UTF-8 characters. /// /// Does not include the null-terminator byte. /// /// A setter is included for conformity with , but is fixed at 29. /// Setting the value to anything other than 29 throws an exception. /// /// In UTF-8 encoding, each Unicode code point (character) requires 1 to 4 bytes, /// so the number of characters that can be stored may be less than the capacity. /// /// Thrown if attempting to set the capacity to anything other than 29. public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8MaxLengthInBytes; } set { CheckCapacityInRange(value); } } /// /// Attempts to set the length in bytes. Does nothing if the new length is invalid. /// /// The desired length. /// Whether added or removed bytes should be cleared (zeroed). (Increasing the length adds bytes; decreasing the length removes bytes.) /// True if the new length is valid. public bool TryResize(int newLength, NativeArrayOptions clearOptions = NativeArrayOptions.ClearMemory) { if (newLength < 0 || newLength > utf8MaxLengthInBytes) return false; if (newLength == utf8LengthInBytes) return true; unsafe { if (clearOptions == NativeArrayOptions.ClearMemory) { if (newLength > utf8LengthInBytes) UnsafeUtility.MemClear(GetUnsafePtr() + utf8LengthInBytes, newLength - utf8LengthInBytes); else UnsafeUtility.MemClear(GetUnsafePtr() + newLength, utf8LengthInBytes - newLength); } utf8LengthInBytes = (ushort)newLength; // always null terminate GetUnsafePtr()[utf8LengthInBytes] = 0; } return true; } /// /// Returns true if this string is empty (has no characters). /// /// True if this string is empty (has no characters). public readonly bool IsEmpty { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => utf8LengthInBytes == 0; } /// /// Returns the byte (not character) at an index. /// /// A byte index. /// The byte at the index. /// Thrown if the index is out of bounds. public byte this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { unsafe { CheckIndexInRange(index); return GetUnsafePtr()[index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { unsafe { CheckIndexInRange(index); GetUnsafePtr()[index] = value; } } } /// /// Returns the reference to a byte (not character) at an index. /// /// A byte index. /// A reference to the byte at the index. /// Thrown if the index is out of bounds. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref byte ElementAt(int index) { unsafe { CheckIndexInRange(index); return ref GetUnsafePtr()[index]; } } /// /// Sets the length to 0. /// public void Clear() { Length = 0; } /// /// Appends a byte. /// /// /// A zero byte will always follow the newly appended byte. /// /// No validation is performed: it is your responsibility for the bytes of the string to form valid UTF-8 when you're done appending bytes. /// /// A byte to append. public void Add(in byte value) { this[Length++] = value; } /// /// An enumerator over the characters (not bytes) of a FixedString32Bytes. /// /// /// In an enumerator's initial state, is not valid to read. /// The first call advances the enumerator's index to the first character. /// public struct Enumerator : IEnumerator { FixedString32Bytes target; int offset; Unicode.Rune current; /// /// Initializes and returns an instance of FixedString32Bytes.Enumerator. /// /// A FixeString32 for which to create an enumerator. public Enumerator(FixedString32Bytes other) { target = other; offset = 0; current = default; } /// /// Does nothing. /// public void Dispose() { } /// /// Advances the enumerator to the next character. /// /// True if is valid to read after the call. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { if (offset >= target.Length) return false; unsafe { Unicode.Utf8ToUcs(out current, target.GetUnsafePtr(), ref offset, target.Length); } return true; } /// /// Resets the enumerator to its initial state. /// public void Reset() { offset = 0; current = default; } /// /// The current character. /// /// /// In an enumerator's initial state, is not valid to read. /// /// The current character. public Unicode.Rune Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => current; } object IEnumerator.Current => Current; } /// /// Returns an enumerator for iterating over the characters of this string. /// /// An enumerator for iterating over the characters of the FixedString32Bytes. public Enumerator GetEnumerator() { return new Enumerator(this); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A `System.String` to compare with. /// An integer denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other string.
/// +1 denotes that this string should be sorted to follow the other string.
///
[ExcludeFromBurstCompatTesting("Takes managed string")] public int CompareTo(String other) { return ToString().CompareTo(other); } /// /// Returns true if this string and another have the same length and all the same characters. /// /// A string to compare for equality. /// True if this string and the other have the same length and all the same characters. [ExcludeFromBurstCompatTesting("Takes managed string")] public bool Equals(String other) { unsafe { int alen = utf8LengthInBytes; int blen = other.Length; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(bytes); fixed(char* bptr = other) { return UTF8ArrayUnsafeUtility.StrCmp(aptr, alen, bptr, blen) == 0; } } } /// /// Returns a reference to a FixedList32Bytes<byte> representation of this string. /// /// /// The referenced FixedListByte32 is the very same bytes as the original FixedString32Bytes, /// so it is only valid as long as the original FixedString32Bytes is valid. /// /// A ref to a FixedListByte32 representation of the FixedString32Bytes. public unsafe ref FixedList32Bytes AsFixedList() { return ref UnsafeUtility.AsRef>(UnsafeUtility.AddressOf(ref this)); } /// /// Initializes and returns an instance of FixedString32Bytes with the characters copied from a string. /// /// The source string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public FixedString32Bytes(String source) { this = default; var error = Initialize(source); CheckCopyError(error, source); } /// /// Initializes an instance of FixedString32Bytes with the characters copied from a string. /// /// The source string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, only the portion that fits is copied in and CopyError.Truncation is returned. [ExcludeFromBurstCompatTesting("Takes managed string")] internal CopyError Initialize(String source) { return this.CopyFromTruncated(source); } /// /// Initializes and returns an instance of FixedString32Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. public FixedString32Bytes(Unicode.Rune rune, int count = 1) { this = default; Initialize(rune, count); } /// /// Initializes an instance of FixedString32Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. internal FormatError Initialize(Unicode.Rune rune, int count = 1) { this = default; return this.Append(rune, count); } /// /// Initializes an instance of FixedString32Bytes that is a copy of another string. /// /// The source buffer. /// The number of bytes to read from the source. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(byte* srcBytes, int srcLength) { bytes = default; utf8LengthInBytes = 0; unsafe { int len = 0; byte* dstBytes = GetUnsafePtr(); var error = UTF8ArrayUnsafeUtility.AppendUTF8Bytes(dstBytes, ref len, utf8MaxLengthInBytes, srcBytes, srcLength); if(error != FormatError.None) return error; this.Length = len; } return FormatError.None; } /// /// Initializes and returns an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. unsafe public FixedString32Bytes(NativeText.ReadOnly other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Initializes and returns an instance of FixedString32Bytes that is a copy of another string. /// /// The UnsafeText to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. unsafe public FixedString32Bytes(in UnsafeText other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString32Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. public FixedString32Bytes(in FixedString32Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString32Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString32Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString32Bytes a, in FixedString32Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString32Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for inequality. /// A FixedString32Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString32Bytes a, in FixedString32Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString32Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString64Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. public FixedString32Bytes(in FixedString64Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString64Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString32Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString32Bytes a, in FixedString64Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString32Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for inequality. /// A FixedString64Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString32Bytes a, in FixedString64Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString64Bytes other) { return this == other; } /// /// Returns a new FixedString64Bytes that is a copy of another string. /// /// A FixedString32Bytes to copy. /// A new FixedString64Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. public static implicit operator FixedString64Bytes(in FixedString32Bytes fs) => new FixedString64Bytes(in fs); /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString128Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. public FixedString32Bytes(in FixedString128Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString128Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString32Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString32Bytes a, in FixedString128Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString32Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for inequality. /// A FixedString128Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString32Bytes a, in FixedString128Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString128Bytes other) { return this == other; } /// /// Returns a new FixedString128Bytes that is a copy of another string. /// /// A FixedString32Bytes to copy. /// A new FixedString128Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. public static implicit operator FixedString128Bytes(in FixedString32Bytes fs) => new FixedString128Bytes(in fs); /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString512Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. public FixedString32Bytes(in FixedString512Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString512Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString32Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString32Bytes a, in FixedString512Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString32Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for inequality. /// A FixedString512Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString32Bytes a, in FixedString512Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString512Bytes other) { return this == other; } /// /// Returns a new FixedString512Bytes that is a copy of another string. /// /// A FixedString32Bytes to copy. /// A new FixedString512Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public static implicit operator FixedString512Bytes(in FixedString32Bytes fs) => new FixedString512Bytes(in fs); /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString4096Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. public FixedString32Bytes(in FixedString4096Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString32Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString4096Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString32Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString32Bytes a, in FixedString4096Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString32Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for inequality. /// A FixedString4096Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString32Bytes a, in FixedString4096Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString4096Bytes other) { return this == other; } /// /// Returns a new FixedString4096Bytes that is a copy of another string. /// /// A FixedString32Bytes to copy. /// A new FixedString4096Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public static implicit operator FixedString4096Bytes(in FixedString32Bytes fs) => new FixedString4096Bytes(in fs); /// /// Returns a new FixedString32Bytes that is a copy of another string. /// /// A string to copy. /// A new FixedString32Bytes that is a copy of another string. /// Thrown if the string to copy's length exceeds the capacity of FixedString32Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public static implicit operator FixedString32Bytes(string b) => new FixedString32Bytes(b); /// /// Returns a new managed string that is a copy of this string. /// /// A new managed string that is a copy of this string. [ExcludeFromBurstCompatTesting("Returns managed string")] public override String ToString() { return this.ConvertToString(); } /// /// Returns a hash code of this string. /// /// Only the character bytes are included in the hash: any bytes beyond are not part of the hash. /// The hash code of this string. public override int GetHashCode() { return this.ComputeHashCode(); } /// /// Returns true if this string and an object are equal. /// /// /// Returns false if the object is neither a System.String or a FixedString. /// /// Two strings are equal if they have equal length and all their characters match. /// An object to compare for equality. /// True if this string and the object are equal. [ExcludeFromBurstCompatTesting("Takes managed object")] public override bool Equals(object obj) { if(ReferenceEquals(null, obj)) return false; if(obj is String aString) return Equals(aString); if(obj is FixedString32Bytes aFixedString32Bytes) return Equals(aFixedString32Bytes); if(obj is FixedString64Bytes aFixedString64Bytes) return Equals(aFixedString64Bytes); if(obj is FixedString128Bytes aFixedString128Bytes) return Equals(aFixedString128Bytes); if(obj is FixedString512Bytes aFixedString512Bytes) return Equals(aFixedString512Bytes); if(obj is FixedString4096Bytes aFixedString4096Bytes) return Equals(aFixedString4096Bytes); return false; } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly void CheckIndexInRange(int index) { if (index < 0) throw new IndexOutOfRangeException($"Index {index} must be positive."); if (index >= utf8LengthInBytes) throw new IndexOutOfRangeException($"Index {index} is out of range in FixedString32Bytes of '{utf8LengthInBytes}' Length."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckLengthInRange(int length) { if (length < 0) throw new ArgumentOutOfRangeException($"Length {length} must be positive."); if (length > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Length {length} is out of range in FixedString32Bytes of '{utf8MaxLengthInBytes}' Capacity."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckCapacityInRange(int capacity) { if (capacity > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Capacity {capacity} must be lower than {utf8MaxLengthInBytes}."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckCopyError(CopyError error, String source) { if (error != CopyError.None) throw new ArgumentException($"FixedString32Bytes: {error} while copying \"{source}\""); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckFormatError(FormatError error) { if (error != FormatError.None) throw new ArgumentException("Source is too long to fit into fixed string of this size"); } } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=62)] [GenerateTestsForBurstCompatibility] public struct FixedBytes62 { /// /// For internal use only. /// [FieldOffset(0)] public FixedBytes16 offset0000; /// /// For internal use only. /// [FieldOffset(16)] public FixedBytes16 offset0016; /// /// For internal use only. /// [FieldOffset(32)] public FixedBytes16 offset0032; /// /// For internal use only. /// [FieldOffset(48)] public byte byte0048; /// /// For internal use only. /// [FieldOffset(49)] public byte byte0049; /// /// For internal use only. /// [FieldOffset(50)] public byte byte0050; /// /// For internal use only. /// [FieldOffset(51)] public byte byte0051; /// /// For internal use only. /// [FieldOffset(52)] public byte byte0052; /// /// For internal use only. /// [FieldOffset(53)] public byte byte0053; /// /// For internal use only. /// [FieldOffset(54)] public byte byte0054; /// /// For internal use only. /// [FieldOffset(55)] public byte byte0055; /// /// For internal use only. /// [FieldOffset(56)] public byte byte0056; /// /// For internal use only. /// [FieldOffset(57)] public byte byte0057; /// /// For internal use only. /// [FieldOffset(58)] public byte byte0058; /// /// For internal use only. /// [FieldOffset(59)] public byte byte0059; /// /// For internal use only. /// [FieldOffset(60)] public byte byte0060; /// /// For internal use only. /// [FieldOffset(61)] public byte byte0061; } /// /// An unmanaged UTF-8 string whose content is stored directly in the 64-byte struct. /// /// /// The binary layout of this string is guaranteed, for now and all time, to be a length (a little-endian two byte integer) /// followed by the bytes of the characters (with no padding). A zero byte always immediately follows the last character. /// Effectively, the number of bytes for storing characters is 3 less than 64 (two length bytes and one null byte). /// /// This layout is identical to a of bytes, thus allowing reinterpretation between FixedString64Bytes and FixedList64Bytes. /// /// By virtue of being an unmanaged, non-allocated struct with no pointers, this string is fully compatible with jobs and Burst compilation. /// Unlike managed string types, these strings can be put in any unmanaged ECS components, FixedList, or any other unmanaged structs. /// [Serializable] [StructLayout(LayoutKind.Sequential, Size=64)] [GenerateTestsForBurstCompatibility] public partial struct FixedString64Bytes : INativeList , IUTF8Bytes , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable { internal const ushort utf8MaxLengthInBytes = 61; [SerializeField] internal ushort utf8LengthInBytes; [SerializeField] internal FixedBytes62 bytes; /// /// Returns the maximum number of UTF-8 bytes that can be stored in this string. /// /// /// The maximum number of UTF-8 bytes that can be stored in this string. /// public static int UTF8MaxLengthInBytes => utf8MaxLengthInBytes; /// /// For internal use only. Use instead. /// /// For internal use only. Use instead. [CreateProperty] [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] [ExcludeFromBurstCompatTesting("Returns managed string")] public string Value => ToString(); /// /// Returns a pointer to the character bytes. /// /// /// The pointer returned by this method points into the internals of the target FixedString object. It is the /// caller's responsibility to ensure that the pointer is not used after the FixedString object is destroyed or goes /// out of scope. /// /// A pointer to the character bytes. [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly unsafe byte* GetUnsafePtr() { fixed(void* b = &bytes) return (byte*)b; } /// /// The current length in bytes of this string's content. /// /// /// The length value does not include the null-terminator byte. /// /// The new length in bytes of the string's content. /// Thrown if the new length is out of bounds. /// /// The current length in bytes of this string's content. /// public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8LengthInBytes; } set { CheckLengthInRange(value); utf8LengthInBytes = (ushort)value; unsafe { GetUnsafePtr()[utf8LengthInBytes] = 0; } } } /// /// The number of bytes this string has for storing UTF-8 characters. /// /// The number of bytes this string has for storing UTF-8 characters. /// /// Does not include the null-terminator byte. /// /// A setter is included for conformity with , but is fixed at 61. /// Setting the value to anything other than 61 throws an exception. /// /// In UTF-8 encoding, each Unicode code point (character) requires 1 to 4 bytes, /// so the number of characters that can be stored may be less than the capacity. /// /// Thrown if attempting to set the capacity to anything other than 61. public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8MaxLengthInBytes; } set { CheckCapacityInRange(value); } } /// /// Attempts to set the length in bytes. Does nothing if the new length is invalid. /// /// The desired length. /// Whether added or removed bytes should be cleared (zeroed). (Increasing the length adds bytes; decreasing the length removes bytes.) /// True if the new length is valid. public bool TryResize(int newLength, NativeArrayOptions clearOptions = NativeArrayOptions.ClearMemory) { if (newLength < 0 || newLength > utf8MaxLengthInBytes) return false; if (newLength == utf8LengthInBytes) return true; unsafe { if (clearOptions == NativeArrayOptions.ClearMemory) { if (newLength > utf8LengthInBytes) UnsafeUtility.MemClear(GetUnsafePtr() + utf8LengthInBytes, newLength - utf8LengthInBytes); else UnsafeUtility.MemClear(GetUnsafePtr() + newLength, utf8LengthInBytes - newLength); } utf8LengthInBytes = (ushort)newLength; // always null terminate GetUnsafePtr()[utf8LengthInBytes] = 0; } return true; } /// /// Returns true if this string is empty (has no characters). /// /// True if this string is empty (has no characters). public readonly bool IsEmpty { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => utf8LengthInBytes == 0; } /// /// Returns the byte (not character) at an index. /// /// A byte index. /// The byte at the index. /// Thrown if the index is out of bounds. public byte this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { unsafe { CheckIndexInRange(index); return GetUnsafePtr()[index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { unsafe { CheckIndexInRange(index); GetUnsafePtr()[index] = value; } } } /// /// Returns the reference to a byte (not character) at an index. /// /// A byte index. /// A reference to the byte at the index. /// Thrown if the index is out of bounds. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref byte ElementAt(int index) { unsafe { CheckIndexInRange(index); return ref GetUnsafePtr()[index]; } } /// /// Sets the length to 0. /// public void Clear() { Length = 0; } /// /// Appends a byte. /// /// /// A zero byte will always follow the newly appended byte. /// /// No validation is performed: it is your responsibility for the bytes of the string to form valid UTF-8 when you're done appending bytes. /// /// A byte to append. public void Add(in byte value) { this[Length++] = value; } /// /// An enumerator over the characters (not bytes) of a FixedString64Bytes. /// /// /// In an enumerator's initial state, is not valid to read. /// The first call advances the enumerator's index to the first character. /// public struct Enumerator : IEnumerator { FixedString64Bytes target; int offset; Unicode.Rune current; /// /// Initializes and returns an instance of FixedString64Bytes.Enumerator. /// /// A FixeString64 for which to create an enumerator. public Enumerator(FixedString64Bytes other) { target = other; offset = 0; current = default; } /// /// Does nothing. /// public void Dispose() { } /// /// Advances the enumerator to the next character. /// /// True if is valid to read after the call. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { if (offset >= target.Length) return false; unsafe { Unicode.Utf8ToUcs(out current, target.GetUnsafePtr(), ref offset, target.Length); } return true; } /// /// Resets the enumerator to its initial state. /// public void Reset() { offset = 0; current = default; } /// /// The current character. /// /// /// In an enumerator's initial state, is not valid to read. /// /// The current character. public Unicode.Rune Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => current; } object IEnumerator.Current => Current; } /// /// Returns an enumerator for iterating over the characters of this string. /// /// An enumerator for iterating over the characters of the FixedString64Bytes. public Enumerator GetEnumerator() { return new Enumerator(this); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A `System.String` to compare with. /// An integer denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other string.
/// +1 denotes that this string should be sorted to follow the other string.
///
[ExcludeFromBurstCompatTesting("Takes managed string")] public int CompareTo(String other) { return ToString().CompareTo(other); } /// /// Returns true if this string and another have the same length and all the same characters. /// /// A string to compare for equality. /// True if this string and the other have the same length and all the same characters. [ExcludeFromBurstCompatTesting("Takes managed string")] public bool Equals(String other) { unsafe { int alen = utf8LengthInBytes; int blen = other.Length; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(bytes); fixed(char* bptr = other) { return UTF8ArrayUnsafeUtility.StrCmp(aptr, alen, bptr, blen) == 0; } } } /// /// Returns a reference to a FixedList64Bytes<byte> representation of this string. /// /// /// The referenced FixedListByte64 is the very same bytes as the original FixedString64Bytes, /// so it is only valid as long as the original FixedString64Bytes is valid. /// /// A ref to a FixedListByte64 representation of the FixedString64Bytes. public unsafe ref FixedList64Bytes AsFixedList() { return ref UnsafeUtility.AsRef>(UnsafeUtility.AddressOf(ref this)); } /// /// Initializes and returns an instance of FixedString64Bytes with the characters copied from a string. /// /// The source string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public FixedString64Bytes(String source) { this = default; var error = Initialize(source); CheckCopyError(error, source); } /// /// Initializes an instance of FixedString64Bytes with the characters copied from a string. /// /// The source string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, only the portion that fits is copied in and CopyError.Truncation is returned. [ExcludeFromBurstCompatTesting("Takes managed string")] internal CopyError Initialize(String source) { return this.CopyFromTruncated(source); } /// /// Initializes and returns an instance of FixedString64Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. public FixedString64Bytes(Unicode.Rune rune, int count = 1) { this = default; Initialize(rune, count); } /// /// Initializes an instance of FixedString64Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. internal FormatError Initialize(Unicode.Rune rune, int count = 1) { this = default; return this.Append(rune, count); } /// /// Initializes an instance of FixedString64Bytes that is a copy of another string. /// /// The source buffer. /// The number of bytes to read from the source. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(byte* srcBytes, int srcLength) { bytes = default; utf8LengthInBytes = 0; unsafe { int len = 0; byte* dstBytes = GetUnsafePtr(); var error = UTF8ArrayUnsafeUtility.AppendUTF8Bytes(dstBytes, ref len, utf8MaxLengthInBytes, srcBytes, srcLength); if(error != FormatError.None) return error; this.Length = len; } return FormatError.None; } /// /// Initializes and returns an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. unsafe public FixedString64Bytes(NativeText.ReadOnly other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Initializes and returns an instance of FixedString64Bytes that is a copy of another string. /// /// The UnsafeText to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. unsafe public FixedString64Bytes(in UnsafeText other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString32Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. public FixedString64Bytes(in FixedString32Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString32Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString64Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString64Bytes a, in FixedString32Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString64Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for inequality. /// A FixedString32Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString64Bytes a, in FixedString32Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString32Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString64Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. public FixedString64Bytes(in FixedString64Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString64Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString64Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString64Bytes a, in FixedString64Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString64Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for inequality. /// A FixedString64Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString64Bytes a, in FixedString64Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString64Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString128Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. public FixedString64Bytes(in FixedString128Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString128Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString64Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString64Bytes a, in FixedString128Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString64Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for inequality. /// A FixedString128Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString64Bytes a, in FixedString128Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString128Bytes other) { return this == other; } /// /// Returns a new FixedString128Bytes that is a copy of another string. /// /// A FixedString64Bytes to copy. /// A new FixedString128Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. public static implicit operator FixedString128Bytes(in FixedString64Bytes fs) => new FixedString128Bytes(in fs); /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString512Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. public FixedString64Bytes(in FixedString512Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString512Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString64Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString64Bytes a, in FixedString512Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString64Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for inequality. /// A FixedString512Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString64Bytes a, in FixedString512Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString512Bytes other) { return this == other; } /// /// Returns a new FixedString512Bytes that is a copy of another string. /// /// A FixedString64Bytes to copy. /// A new FixedString512Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public static implicit operator FixedString512Bytes(in FixedString64Bytes fs) => new FixedString512Bytes(in fs); /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString4096Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. public FixedString64Bytes(in FixedString4096Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString64Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString4096Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString64Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString64Bytes a, in FixedString4096Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString64Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for inequality. /// A FixedString4096Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString64Bytes a, in FixedString4096Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString4096Bytes other) { return this == other; } /// /// Returns a new FixedString4096Bytes that is a copy of another string. /// /// A FixedString64Bytes to copy. /// A new FixedString4096Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public static implicit operator FixedString4096Bytes(in FixedString64Bytes fs) => new FixedString4096Bytes(in fs); /// /// Returns a new FixedString64Bytes that is a copy of another string. /// /// A string to copy. /// A new FixedString64Bytes that is a copy of another string. /// Thrown if the string to copy's length exceeds the capacity of FixedString64Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public static implicit operator FixedString64Bytes(string b) => new FixedString64Bytes(b); /// /// Returns a new managed string that is a copy of this string. /// /// A new managed string that is a copy of this string. [ExcludeFromBurstCompatTesting("Returns managed string")] public override String ToString() { return this.ConvertToString(); } /// /// Returns a hash code of this string. /// /// Only the character bytes are included in the hash: any bytes beyond are not part of the hash. /// The hash code of this string. public override int GetHashCode() { return this.ComputeHashCode(); } /// /// Returns true if this string and an object are equal. /// /// /// Returns false if the object is neither a System.String or a FixedString. /// /// Two strings are equal if they have equal length and all their characters match. /// An object to compare for equality. /// True if this string and the object are equal. [ExcludeFromBurstCompatTesting("Takes managed object")] public override bool Equals(object obj) { if(ReferenceEquals(null, obj)) return false; if(obj is String aString) return Equals(aString); if(obj is FixedString32Bytes aFixedString32Bytes) return Equals(aFixedString32Bytes); if(obj is FixedString64Bytes aFixedString64Bytes) return Equals(aFixedString64Bytes); if(obj is FixedString128Bytes aFixedString128Bytes) return Equals(aFixedString128Bytes); if(obj is FixedString512Bytes aFixedString512Bytes) return Equals(aFixedString512Bytes); if(obj is FixedString4096Bytes aFixedString4096Bytes) return Equals(aFixedString4096Bytes); return false; } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly void CheckIndexInRange(int index) { if (index < 0) throw new IndexOutOfRangeException($"Index {index} must be positive."); if (index >= utf8LengthInBytes) throw new IndexOutOfRangeException($"Index {index} is out of range in FixedString64Bytes of '{utf8LengthInBytes}' Length."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckLengthInRange(int length) { if (length < 0) throw new ArgumentOutOfRangeException($"Length {length} must be positive."); if (length > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Length {length} is out of range in FixedString64Bytes of '{utf8MaxLengthInBytes}' Capacity."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckCapacityInRange(int capacity) { if (capacity > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Capacity {capacity} must be lower than {utf8MaxLengthInBytes}."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckCopyError(CopyError error, String source) { if (error != CopyError.None) throw new ArgumentException($"FixedString64Bytes: {error} while copying \"{source}\""); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckFormatError(FormatError error) { if (error != FormatError.None) throw new ArgumentException("Source is too long to fit into fixed string of this size"); } } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=126)] [GenerateTestsForBurstCompatibility] public struct FixedBytes126 { /// /// For internal use only. /// [FieldOffset(0)] public FixedBytes16 offset0000; /// /// For internal use only. /// [FieldOffset(16)] public FixedBytes16 offset0016; /// /// For internal use only. /// [FieldOffset(32)] public FixedBytes16 offset0032; /// /// For internal use only. /// [FieldOffset(48)] public FixedBytes16 offset0048; /// /// For internal use only. /// [FieldOffset(64)] public FixedBytes16 offset0064; /// /// For internal use only. /// [FieldOffset(80)] public FixedBytes16 offset0080; /// /// For internal use only. /// [FieldOffset(96)] public FixedBytes16 offset0096; /// /// For internal use only. /// [FieldOffset(112)] public byte byte0112; /// /// For internal use only. /// [FieldOffset(113)] public byte byte0113; /// /// For internal use only. /// [FieldOffset(114)] public byte byte0114; /// /// For internal use only. /// [FieldOffset(115)] public byte byte0115; /// /// For internal use only. /// [FieldOffset(116)] public byte byte0116; /// /// For internal use only. /// [FieldOffset(117)] public byte byte0117; /// /// For internal use only. /// [FieldOffset(118)] public byte byte0118; /// /// For internal use only. /// [FieldOffset(119)] public byte byte0119; /// /// For internal use only. /// [FieldOffset(120)] public byte byte0120; /// /// For internal use only. /// [FieldOffset(121)] public byte byte0121; /// /// For internal use only. /// [FieldOffset(122)] public byte byte0122; /// /// For internal use only. /// [FieldOffset(123)] public byte byte0123; /// /// For internal use only. /// [FieldOffset(124)] public byte byte0124; /// /// For internal use only. /// [FieldOffset(125)] public byte byte0125; } /// /// An unmanaged UTF-8 string whose content is stored directly in the 128-byte struct. /// /// /// The binary layout of this string is guaranteed, for now and all time, to be a length (a little-endian two byte integer) /// followed by the bytes of the characters (with no padding). A zero byte always immediately follows the last character. /// Effectively, the number of bytes for storing characters is 3 less than 128 (two length bytes and one null byte). /// /// This layout is identical to a of bytes, thus allowing reinterpretation between FixedString128Bytes and FixedList128Bytes. /// /// By virtue of being an unmanaged, non-allocated struct with no pointers, this string is fully compatible with jobs and Burst compilation. /// Unlike managed string types, these strings can be put in any unmanaged ECS components, FixedList, or any other unmanaged structs. /// [Serializable] [StructLayout(LayoutKind.Sequential, Size=128)] [GenerateTestsForBurstCompatibility] public partial struct FixedString128Bytes : INativeList , IUTF8Bytes , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable { internal const ushort utf8MaxLengthInBytes = 125; [SerializeField] internal ushort utf8LengthInBytes; [SerializeField] internal FixedBytes126 bytes; /// /// Returns the maximum number of UTF-8 bytes that can be stored in this string. /// /// /// The maximum number of UTF-8 bytes that can be stored in this string. /// public static int UTF8MaxLengthInBytes => utf8MaxLengthInBytes; /// /// For internal use only. Use instead. /// /// For internal use only. Use instead. [CreateProperty] [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] [ExcludeFromBurstCompatTesting("Returns managed string")] public string Value => ToString(); /// /// Returns a pointer to the character bytes. /// /// /// The pointer returned by this method points into the internals of the target FixedString object. It is the /// caller's responsibility to ensure that the pointer is not used after the FixedString object is destroyed or goes /// out of scope. /// /// A pointer to the character bytes. [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly unsafe byte* GetUnsafePtr() { fixed(void* b = &bytes) return (byte*)b; } /// /// The current length in bytes of this string's content. /// /// /// The length value does not include the null-terminator byte. /// /// The new length in bytes of the string's content. /// Thrown if the new length is out of bounds. /// /// The current length in bytes of this string's content. /// public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8LengthInBytes; } set { CheckLengthInRange(value); utf8LengthInBytes = (ushort)value; unsafe { GetUnsafePtr()[utf8LengthInBytes] = 0; } } } /// /// The number of bytes this string has for storing UTF-8 characters. /// /// The number of bytes this string has for storing UTF-8 characters. /// /// Does not include the null-terminator byte. /// /// A setter is included for conformity with , but is fixed at 125. /// Setting the value to anything other than 125 throws an exception. /// /// In UTF-8 encoding, each Unicode code point (character) requires 1 to 4 bytes, /// so the number of characters that can be stored may be less than the capacity. /// /// Thrown if attempting to set the capacity to anything other than 125. public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8MaxLengthInBytes; } set { CheckCapacityInRange(value); } } /// /// Attempts to set the length in bytes. Does nothing if the new length is invalid. /// /// The desired length. /// Whether added or removed bytes should be cleared (zeroed). (Increasing the length adds bytes; decreasing the length removes bytes.) /// True if the new length is valid. public bool TryResize(int newLength, NativeArrayOptions clearOptions = NativeArrayOptions.ClearMemory) { if (newLength < 0 || newLength > utf8MaxLengthInBytes) return false; if (newLength == utf8LengthInBytes) return true; unsafe { if (clearOptions == NativeArrayOptions.ClearMemory) { if (newLength > utf8LengthInBytes) UnsafeUtility.MemClear(GetUnsafePtr() + utf8LengthInBytes, newLength - utf8LengthInBytes); else UnsafeUtility.MemClear(GetUnsafePtr() + newLength, utf8LengthInBytes - newLength); } utf8LengthInBytes = (ushort)newLength; // always null terminate GetUnsafePtr()[utf8LengthInBytes] = 0; } return true; } /// /// Returns true if this string is empty (has no characters). /// /// True if this string is empty (has no characters). public readonly bool IsEmpty { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => utf8LengthInBytes == 0; } /// /// Returns the byte (not character) at an index. /// /// A byte index. /// The byte at the index. /// Thrown if the index is out of bounds. public byte this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { unsafe { CheckIndexInRange(index); return GetUnsafePtr()[index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { unsafe { CheckIndexInRange(index); GetUnsafePtr()[index] = value; } } } /// /// Returns the reference to a byte (not character) at an index. /// /// A byte index. /// A reference to the byte at the index. /// Thrown if the index is out of bounds. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref byte ElementAt(int index) { unsafe { CheckIndexInRange(index); return ref GetUnsafePtr()[index]; } } /// /// Sets the length to 0. /// public void Clear() { Length = 0; } /// /// Appends a byte. /// /// /// A zero byte will always follow the newly appended byte. /// /// No validation is performed: it is your responsibility for the bytes of the string to form valid UTF-8 when you're done appending bytes. /// /// A byte to append. public void Add(in byte value) { this[Length++] = value; } /// /// An enumerator over the characters (not bytes) of a FixedString128Bytes. /// /// /// In an enumerator's initial state, is not valid to read. /// The first call advances the enumerator's index to the first character. /// public struct Enumerator : IEnumerator { FixedString128Bytes target; int offset; Unicode.Rune current; /// /// Initializes and returns an instance of FixedString128Bytes.Enumerator. /// /// A FixeString128 for which to create an enumerator. public Enumerator(FixedString128Bytes other) { target = other; offset = 0; current = default; } /// /// Does nothing. /// public void Dispose() { } /// /// Advances the enumerator to the next character. /// /// True if is valid to read after the call. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { if (offset >= target.Length) return false; unsafe { Unicode.Utf8ToUcs(out current, target.GetUnsafePtr(), ref offset, target.Length); } return true; } /// /// Resets the enumerator to its initial state. /// public void Reset() { offset = 0; current = default; } /// /// The current character. /// /// /// In an enumerator's initial state, is not valid to read. /// /// The current character. public Unicode.Rune Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => current; } object IEnumerator.Current => Current; } /// /// Returns an enumerator for iterating over the characters of this string. /// /// An enumerator for iterating over the characters of the FixedString128Bytes. public Enumerator GetEnumerator() { return new Enumerator(this); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A `System.String` to compare with. /// An integer denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other string.
/// +1 denotes that this string should be sorted to follow the other string.
///
[ExcludeFromBurstCompatTesting("Takes managed string")] public int CompareTo(String other) { return ToString().CompareTo(other); } /// /// Returns true if this string and another have the same length and all the same characters. /// /// A string to compare for equality. /// True if this string and the other have the same length and all the same characters. [ExcludeFromBurstCompatTesting("Takes managed string")] public bool Equals(String other) { unsafe { int alen = utf8LengthInBytes; int blen = other.Length; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(bytes); fixed(char* bptr = other) { return UTF8ArrayUnsafeUtility.StrCmp(aptr, alen, bptr, blen) == 0; } } } /// /// Returns a reference to a FixedList128Bytes<byte> representation of this string. /// /// /// The referenced FixedListByte128 is the very same bytes as the original FixedString128Bytes, /// so it is only valid as long as the original FixedString128Bytes is valid. /// /// A ref to a FixedListByte128 representation of the FixedString128Bytes. public unsafe ref FixedList128Bytes AsFixedList() { return ref UnsafeUtility.AsRef>(UnsafeUtility.AddressOf(ref this)); } /// /// Initializes and returns an instance of FixedString128Bytes with the characters copied from a string. /// /// The source string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public FixedString128Bytes(String source) { this = default; var error = Initialize(source); CheckCopyError(error, source); } /// /// Initializes an instance of FixedString128Bytes with the characters copied from a string. /// /// The source string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, only the portion that fits is copied in and CopyError.Truncation is returned. [ExcludeFromBurstCompatTesting("Takes managed string")] internal CopyError Initialize(String source) { return this.CopyFromTruncated(source); } /// /// Initializes and returns an instance of FixedString128Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. public FixedString128Bytes(Unicode.Rune rune, int count = 1) { this = default; Initialize(rune, count); } /// /// Initializes an instance of FixedString128Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. internal FormatError Initialize(Unicode.Rune rune, int count = 1) { this = default; return this.Append(rune, count); } /// /// Initializes an instance of FixedString128Bytes that is a copy of another string. /// /// The source buffer. /// The number of bytes to read from the source. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(byte* srcBytes, int srcLength) { bytes = default; utf8LengthInBytes = 0; unsafe { int len = 0; byte* dstBytes = GetUnsafePtr(); var error = UTF8ArrayUnsafeUtility.AppendUTF8Bytes(dstBytes, ref len, utf8MaxLengthInBytes, srcBytes, srcLength); if(error != FormatError.None) return error; this.Length = len; } return FormatError.None; } /// /// Initializes and returns an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. unsafe public FixedString128Bytes(NativeText.ReadOnly other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Initializes and returns an instance of FixedString128Bytes that is a copy of another string. /// /// The UnsafeText to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. unsafe public FixedString128Bytes(in UnsafeText other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString32Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. public FixedString128Bytes(in FixedString32Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString32Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString128Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString128Bytes a, in FixedString32Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString128Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for inequality. /// A FixedString32Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString128Bytes a, in FixedString32Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString32Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString64Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. public FixedString128Bytes(in FixedString64Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString64Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString128Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString128Bytes a, in FixedString64Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString128Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for inequality. /// A FixedString64Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString128Bytes a, in FixedString64Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString64Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString128Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. public FixedString128Bytes(in FixedString128Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString128Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString128Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString128Bytes a, in FixedString128Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString128Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for inequality. /// A FixedString128Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString128Bytes a, in FixedString128Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString128Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString512Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. public FixedString128Bytes(in FixedString512Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString512Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString128Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString128Bytes a, in FixedString512Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString128Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for inequality. /// A FixedString512Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString128Bytes a, in FixedString512Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString512Bytes other) { return this == other; } /// /// Returns a new FixedString512Bytes that is a copy of another string. /// /// A FixedString128Bytes to copy. /// A new FixedString512Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public static implicit operator FixedString512Bytes(in FixedString128Bytes fs) => new FixedString512Bytes(in fs); /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString4096Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. public FixedString128Bytes(in FixedString4096Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString128Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString4096Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString128Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString128Bytes a, in FixedString4096Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString128Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for inequality. /// A FixedString4096Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString128Bytes a, in FixedString4096Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString4096Bytes other) { return this == other; } /// /// Returns a new FixedString4096Bytes that is a copy of another string. /// /// A FixedString128Bytes to copy. /// A new FixedString4096Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public static implicit operator FixedString4096Bytes(in FixedString128Bytes fs) => new FixedString4096Bytes(in fs); /// /// Returns a new FixedString128Bytes that is a copy of another string. /// /// A string to copy. /// A new FixedString128Bytes that is a copy of another string. /// Thrown if the string to copy's length exceeds the capacity of FixedString128Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public static implicit operator FixedString128Bytes(string b) => new FixedString128Bytes(b); /// /// Returns a new managed string that is a copy of this string. /// /// A new managed string that is a copy of this string. [ExcludeFromBurstCompatTesting("Returns managed string")] public override String ToString() { return this.ConvertToString(); } /// /// Returns a hash code of this string. /// /// Only the character bytes are included in the hash: any bytes beyond are not part of the hash. /// The hash code of this string. public override int GetHashCode() { return this.ComputeHashCode(); } /// /// Returns true if this string and an object are equal. /// /// /// Returns false if the object is neither a System.String or a FixedString. /// /// Two strings are equal if they have equal length and all their characters match. /// An object to compare for equality. /// True if this string and the object are equal. [ExcludeFromBurstCompatTesting("Takes managed object")] public override bool Equals(object obj) { if(ReferenceEquals(null, obj)) return false; if(obj is String aString) return Equals(aString); if(obj is FixedString32Bytes aFixedString32Bytes) return Equals(aFixedString32Bytes); if(obj is FixedString64Bytes aFixedString64Bytes) return Equals(aFixedString64Bytes); if(obj is FixedString128Bytes aFixedString128Bytes) return Equals(aFixedString128Bytes); if(obj is FixedString512Bytes aFixedString512Bytes) return Equals(aFixedString512Bytes); if(obj is FixedString4096Bytes aFixedString4096Bytes) return Equals(aFixedString4096Bytes); return false; } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly void CheckIndexInRange(int index) { if (index < 0) throw new IndexOutOfRangeException($"Index {index} must be positive."); if (index >= utf8LengthInBytes) throw new IndexOutOfRangeException($"Index {index} is out of range in FixedString128Bytes of '{utf8LengthInBytes}' Length."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckLengthInRange(int length) { if (length < 0) throw new ArgumentOutOfRangeException($"Length {length} must be positive."); if (length > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Length {length} is out of range in FixedString128Bytes of '{utf8MaxLengthInBytes}' Capacity."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckCapacityInRange(int capacity) { if (capacity > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Capacity {capacity} must be lower than {utf8MaxLengthInBytes}."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckCopyError(CopyError error, String source) { if (error != CopyError.None) throw new ArgumentException($"FixedString128Bytes: {error} while copying \"{source}\""); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckFormatError(FormatError error) { if (error != FormatError.None) throw new ArgumentException("Source is too long to fit into fixed string of this size"); } } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=510)] [GenerateTestsForBurstCompatibility] public struct FixedBytes510 { /// /// For internal use only. /// [FieldOffset(0)] public FixedBytes16 offset0000; /// /// For internal use only. /// [FieldOffset(16)] public FixedBytes16 offset0016; /// /// For internal use only. /// [FieldOffset(32)] public FixedBytes16 offset0032; /// /// For internal use only. /// [FieldOffset(48)] public FixedBytes16 offset0048; /// /// For internal use only. /// [FieldOffset(64)] public FixedBytes16 offset0064; /// /// For internal use only. /// [FieldOffset(80)] public FixedBytes16 offset0080; /// /// For internal use only. /// [FieldOffset(96)] public FixedBytes16 offset0096; /// /// For internal use only. /// [FieldOffset(112)] public FixedBytes16 offset0112; /// /// For internal use only. /// [FieldOffset(128)] public FixedBytes16 offset0128; /// /// For internal use only. /// [FieldOffset(144)] public FixedBytes16 offset0144; /// /// For internal use only. /// [FieldOffset(160)] public FixedBytes16 offset0160; /// /// For internal use only. /// [FieldOffset(176)] public FixedBytes16 offset0176; /// /// For internal use only. /// [FieldOffset(192)] public FixedBytes16 offset0192; /// /// For internal use only. /// [FieldOffset(208)] public FixedBytes16 offset0208; /// /// For internal use only. /// [FieldOffset(224)] public FixedBytes16 offset0224; /// /// For internal use only. /// [FieldOffset(240)] public FixedBytes16 offset0240; /// /// For internal use only. /// [FieldOffset(256)] public FixedBytes16 offset0256; /// /// For internal use only. /// [FieldOffset(272)] public FixedBytes16 offset0272; /// /// For internal use only. /// [FieldOffset(288)] public FixedBytes16 offset0288; /// /// For internal use only. /// [FieldOffset(304)] public FixedBytes16 offset0304; /// /// For internal use only. /// [FieldOffset(320)] public FixedBytes16 offset0320; /// /// For internal use only. /// [FieldOffset(336)] public FixedBytes16 offset0336; /// /// For internal use only. /// [FieldOffset(352)] public FixedBytes16 offset0352; /// /// For internal use only. /// [FieldOffset(368)] public FixedBytes16 offset0368; /// /// For internal use only. /// [FieldOffset(384)] public FixedBytes16 offset0384; /// /// For internal use only. /// [FieldOffset(400)] public FixedBytes16 offset0400; /// /// For internal use only. /// [FieldOffset(416)] public FixedBytes16 offset0416; /// /// For internal use only. /// [FieldOffset(432)] public FixedBytes16 offset0432; /// /// For internal use only. /// [FieldOffset(448)] public FixedBytes16 offset0448; /// /// For internal use only. /// [FieldOffset(464)] public FixedBytes16 offset0464; /// /// For internal use only. /// [FieldOffset(480)] public FixedBytes16 offset0480; /// /// For internal use only. /// [FieldOffset(496)] public byte byte0496; /// /// For internal use only. /// [FieldOffset(497)] public byte byte0497; /// /// For internal use only. /// [FieldOffset(498)] public byte byte0498; /// /// For internal use only. /// [FieldOffset(499)] public byte byte0499; /// /// For internal use only. /// [FieldOffset(500)] public byte byte0500; /// /// For internal use only. /// [FieldOffset(501)] public byte byte0501; /// /// For internal use only. /// [FieldOffset(502)] public byte byte0502; /// /// For internal use only. /// [FieldOffset(503)] public byte byte0503; /// /// For internal use only. /// [FieldOffset(504)] public byte byte0504; /// /// For internal use only. /// [FieldOffset(505)] public byte byte0505; /// /// For internal use only. /// [FieldOffset(506)] public byte byte0506; /// /// For internal use only. /// [FieldOffset(507)] public byte byte0507; /// /// For internal use only. /// [FieldOffset(508)] public byte byte0508; /// /// For internal use only. /// [FieldOffset(509)] public byte byte0509; } /// /// An unmanaged UTF-8 string whose content is stored directly in the 512-byte struct. /// /// /// The binary layout of this string is guaranteed, for now and all time, to be a length (a little-endian two byte integer) /// followed by the bytes of the characters (with no padding). A zero byte always immediately follows the last character. /// Effectively, the number of bytes for storing characters is 3 less than 512 (two length bytes and one null byte). /// /// This layout is identical to a of bytes, thus allowing reinterpretation between FixedString512Bytes and FixedList512Bytes. /// /// By virtue of being an unmanaged, non-allocated struct with no pointers, this string is fully compatible with jobs and Burst compilation. /// Unlike managed string types, these strings can be put in any unmanaged ECS components, FixedList, or any other unmanaged structs. /// [Serializable] [StructLayout(LayoutKind.Sequential, Size=512)] [GenerateTestsForBurstCompatibility] public partial struct FixedString512Bytes : INativeList , IUTF8Bytes , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable { internal const ushort utf8MaxLengthInBytes = 509; [SerializeField] internal ushort utf8LengthInBytes; [SerializeField] internal FixedBytes510 bytes; /// /// Returns the maximum number of UTF-8 bytes that can be stored in this string. /// /// /// The maximum number of UTF-8 bytes that can be stored in this string. /// public static int UTF8MaxLengthInBytes => utf8MaxLengthInBytes; /// /// For internal use only. Use instead. /// /// For internal use only. Use instead. [CreateProperty] [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] [ExcludeFromBurstCompatTesting("Returns managed string")] public string Value => ToString(); /// /// Returns a pointer to the character bytes. /// /// /// The pointer returned by this method points into the internals of the target FixedString object. It is the /// caller's responsibility to ensure that the pointer is not used after the FixedString object is destroyed or goes /// out of scope. /// /// A pointer to the character bytes. [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly unsafe byte* GetUnsafePtr() { fixed(void* b = &bytes) return (byte*)b; } /// /// The current length in bytes of this string's content. /// /// /// The length value does not include the null-terminator byte. /// /// The new length in bytes of the string's content. /// Thrown if the new length is out of bounds. /// /// The current length in bytes of this string's content. /// public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8LengthInBytes; } set { CheckLengthInRange(value); utf8LengthInBytes = (ushort)value; unsafe { GetUnsafePtr()[utf8LengthInBytes] = 0; } } } /// /// The number of bytes this string has for storing UTF-8 characters. /// /// The number of bytes this string has for storing UTF-8 characters. /// /// Does not include the null-terminator byte. /// /// A setter is included for conformity with , but is fixed at 509. /// Setting the value to anything other than 509 throws an exception. /// /// In UTF-8 encoding, each Unicode code point (character) requires 1 to 4 bytes, /// so the number of characters that can be stored may be less than the capacity. /// /// Thrown if attempting to set the capacity to anything other than 509. public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8MaxLengthInBytes; } set { CheckCapacityInRange(value); } } /// /// Attempts to set the length in bytes. Does nothing if the new length is invalid. /// /// The desired length. /// Whether added or removed bytes should be cleared (zeroed). (Increasing the length adds bytes; decreasing the length removes bytes.) /// True if the new length is valid. public bool TryResize(int newLength, NativeArrayOptions clearOptions = NativeArrayOptions.ClearMemory) { if (newLength < 0 || newLength > utf8MaxLengthInBytes) return false; if (newLength == utf8LengthInBytes) return true; unsafe { if (clearOptions == NativeArrayOptions.ClearMemory) { if (newLength > utf8LengthInBytes) UnsafeUtility.MemClear(GetUnsafePtr() + utf8LengthInBytes, newLength - utf8LengthInBytes); else UnsafeUtility.MemClear(GetUnsafePtr() + newLength, utf8LengthInBytes - newLength); } utf8LengthInBytes = (ushort)newLength; // always null terminate GetUnsafePtr()[utf8LengthInBytes] = 0; } return true; } /// /// Returns true if this string is empty (has no characters). /// /// True if this string is empty (has no characters). public readonly bool IsEmpty { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => utf8LengthInBytes == 0; } /// /// Returns the byte (not character) at an index. /// /// A byte index. /// The byte at the index. /// Thrown if the index is out of bounds. public byte this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { unsafe { CheckIndexInRange(index); return GetUnsafePtr()[index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { unsafe { CheckIndexInRange(index); GetUnsafePtr()[index] = value; } } } /// /// Returns the reference to a byte (not character) at an index. /// /// A byte index. /// A reference to the byte at the index. /// Thrown if the index is out of bounds. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref byte ElementAt(int index) { unsafe { CheckIndexInRange(index); return ref GetUnsafePtr()[index]; } } /// /// Sets the length to 0. /// public void Clear() { Length = 0; } /// /// Appends a byte. /// /// /// A zero byte will always follow the newly appended byte. /// /// No validation is performed: it is your responsibility for the bytes of the string to form valid UTF-8 when you're done appending bytes. /// /// A byte to append. public void Add(in byte value) { this[Length++] = value; } /// /// An enumerator over the characters (not bytes) of a FixedString512Bytes. /// /// /// In an enumerator's initial state, is not valid to read. /// The first call advances the enumerator's index to the first character. /// public struct Enumerator : IEnumerator { FixedString512Bytes target; int offset; Unicode.Rune current; /// /// Initializes and returns an instance of FixedString512Bytes.Enumerator. /// /// A FixeString512 for which to create an enumerator. public Enumerator(FixedString512Bytes other) { target = other; offset = 0; current = default; } /// /// Does nothing. /// public void Dispose() { } /// /// Advances the enumerator to the next character. /// /// True if is valid to read after the call. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { if (offset >= target.Length) return false; unsafe { Unicode.Utf8ToUcs(out current, target.GetUnsafePtr(), ref offset, target.Length); } return true; } /// /// Resets the enumerator to its initial state. /// public void Reset() { offset = 0; current = default; } /// /// The current character. /// /// /// In an enumerator's initial state, is not valid to read. /// /// The current character. public Unicode.Rune Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => current; } object IEnumerator.Current => Current; } /// /// Returns an enumerator for iterating over the characters of this string. /// /// An enumerator for iterating over the characters of the FixedString512Bytes. public Enumerator GetEnumerator() { return new Enumerator(this); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A `System.String` to compare with. /// An integer denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other string.
/// +1 denotes that this string should be sorted to follow the other string.
///
[ExcludeFromBurstCompatTesting("Takes managed string")] public int CompareTo(String other) { return ToString().CompareTo(other); } /// /// Returns true if this string and another have the same length and all the same characters. /// /// A string to compare for equality. /// True if this string and the other have the same length and all the same characters. [ExcludeFromBurstCompatTesting("Takes managed string")] public bool Equals(String other) { unsafe { int alen = utf8LengthInBytes; int blen = other.Length; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(bytes); fixed(char* bptr = other) { return UTF8ArrayUnsafeUtility.StrCmp(aptr, alen, bptr, blen) == 0; } } } /// /// Returns a reference to a FixedList512Bytes<byte> representation of this string. /// /// /// The referenced FixedListByte512 is the very same bytes as the original FixedString512Bytes, /// so it is only valid as long as the original FixedString512Bytes is valid. /// /// A ref to a FixedListByte512 representation of the FixedString512Bytes. public unsafe ref FixedList512Bytes AsFixedList() { return ref UnsafeUtility.AsRef>(UnsafeUtility.AddressOf(ref this)); } /// /// Initializes and returns an instance of FixedString512Bytes with the characters copied from a string. /// /// The source string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public FixedString512Bytes(String source) { this = default; var error = Initialize(source); CheckCopyError(error, source); } /// /// Initializes an instance of FixedString512Bytes with the characters copied from a string. /// /// The source string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, only the portion that fits is copied in and CopyError.Truncation is returned. [ExcludeFromBurstCompatTesting("Takes managed string")] internal CopyError Initialize(String source) { return this.CopyFromTruncated(source); } /// /// Initializes and returns an instance of FixedString512Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. public FixedString512Bytes(Unicode.Rune rune, int count = 1) { this = default; Initialize(rune, count); } /// /// Initializes an instance of FixedString512Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. internal FormatError Initialize(Unicode.Rune rune, int count = 1) { this = default; return this.Append(rune, count); } /// /// Initializes an instance of FixedString512Bytes that is a copy of another string. /// /// The source buffer. /// The number of bytes to read from the source. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(byte* srcBytes, int srcLength) { bytes = default; utf8LengthInBytes = 0; unsafe { int len = 0; byte* dstBytes = GetUnsafePtr(); var error = UTF8ArrayUnsafeUtility.AppendUTF8Bytes(dstBytes, ref len, utf8MaxLengthInBytes, srcBytes, srcLength); if(error != FormatError.None) return error; this.Length = len; } return FormatError.None; } /// /// Initializes and returns an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. unsafe public FixedString512Bytes(NativeText.ReadOnly other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Initializes and returns an instance of FixedString512Bytes that is a copy of another string. /// /// The UnsafeText to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. unsafe public FixedString512Bytes(in UnsafeText other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString32Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public FixedString512Bytes(in FixedString32Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString32Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString512Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString512Bytes a, in FixedString32Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString512Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for inequality. /// A FixedString32Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString512Bytes a, in FixedString32Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString32Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString64Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public FixedString512Bytes(in FixedString64Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString64Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString512Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString512Bytes a, in FixedString64Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString512Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for inequality. /// A FixedString64Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString512Bytes a, in FixedString64Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString64Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString128Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public FixedString512Bytes(in FixedString128Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString128Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString512Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString512Bytes a, in FixedString128Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString512Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for inequality. /// A FixedString128Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString512Bytes a, in FixedString128Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString128Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString512Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public FixedString512Bytes(in FixedString512Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString512Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString512Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString512Bytes a, in FixedString512Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString512Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for inequality. /// A FixedString512Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString512Bytes a, in FixedString512Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString512Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString4096Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. public FixedString512Bytes(in FixedString4096Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString512Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString4096Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString512Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString512Bytes a, in FixedString4096Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString512Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for inequality. /// A FixedString4096Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString512Bytes a, in FixedString4096Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString4096Bytes other) { return this == other; } /// /// Returns a new FixedString4096Bytes that is a copy of another string. /// /// A FixedString512Bytes to copy. /// A new FixedString4096Bytes that is a copy of the other string. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public static implicit operator FixedString4096Bytes(in FixedString512Bytes fs) => new FixedString4096Bytes(in fs); /// /// Returns a new FixedString512Bytes that is a copy of another string. /// /// A string to copy. /// A new FixedString512Bytes that is a copy of another string. /// Thrown if the string to copy's length exceeds the capacity of FixedString512Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public static implicit operator FixedString512Bytes(string b) => new FixedString512Bytes(b); /// /// Returns a new managed string that is a copy of this string. /// /// A new managed string that is a copy of this string. [ExcludeFromBurstCompatTesting("Returns managed string")] public override String ToString() { return this.ConvertToString(); } /// /// Returns a hash code of this string. /// /// Only the character bytes are included in the hash: any bytes beyond are not part of the hash. /// The hash code of this string. public override int GetHashCode() { return this.ComputeHashCode(); } /// /// Returns true if this string and an object are equal. /// /// /// Returns false if the object is neither a System.String or a FixedString. /// /// Two strings are equal if they have equal length and all their characters match. /// An object to compare for equality. /// True if this string and the object are equal. [ExcludeFromBurstCompatTesting("Takes managed object")] public override bool Equals(object obj) { if(ReferenceEquals(null, obj)) return false; if(obj is String aString) return Equals(aString); if(obj is FixedString32Bytes aFixedString32Bytes) return Equals(aFixedString32Bytes); if(obj is FixedString64Bytes aFixedString64Bytes) return Equals(aFixedString64Bytes); if(obj is FixedString128Bytes aFixedString128Bytes) return Equals(aFixedString128Bytes); if(obj is FixedString512Bytes aFixedString512Bytes) return Equals(aFixedString512Bytes); if(obj is FixedString4096Bytes aFixedString4096Bytes) return Equals(aFixedString4096Bytes); return false; } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly void CheckIndexInRange(int index) { if (index < 0) throw new IndexOutOfRangeException($"Index {index} must be positive."); if (index >= utf8LengthInBytes) throw new IndexOutOfRangeException($"Index {index} is out of range in FixedString512Bytes of '{utf8LengthInBytes}' Length."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckLengthInRange(int length) { if (length < 0) throw new ArgumentOutOfRangeException($"Length {length} must be positive."); if (length > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Length {length} is out of range in FixedString512Bytes of '{utf8MaxLengthInBytes}' Capacity."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckCapacityInRange(int capacity) { if (capacity > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Capacity {capacity} must be lower than {utf8MaxLengthInBytes}."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckCopyError(CopyError error, String source) { if (error != CopyError.None) throw new ArgumentException($"FixedString512Bytes: {error} while copying \"{source}\""); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckFormatError(FormatError error) { if (error != FormatError.None) throw new ArgumentException("Source is too long to fit into fixed string of this size"); } } // A temporary copy of a struct is made before it is displayed in a C# debugger. // However, only the first element of data members with names is copied at this time. // Therefore, it's important that all data visible in the debugger, has a name // and includes no 'fixed' array. This is why we name every byte in the following struct. /// /// For internal use only. /// [Serializable] [StructLayout(LayoutKind.Explicit, Size=4094)] [GenerateTestsForBurstCompatibility] public struct FixedBytes4094 { /// /// For internal use only. /// [FieldOffset(0)] public FixedBytes16 offset0000; /// /// For internal use only. /// [FieldOffset(16)] public FixedBytes16 offset0016; /// /// For internal use only. /// [FieldOffset(32)] public FixedBytes16 offset0032; /// /// For internal use only. /// [FieldOffset(48)] public FixedBytes16 offset0048; /// /// For internal use only. /// [FieldOffset(64)] public FixedBytes16 offset0064; /// /// For internal use only. /// [FieldOffset(80)] public FixedBytes16 offset0080; /// /// For internal use only. /// [FieldOffset(96)] public FixedBytes16 offset0096; /// /// For internal use only. /// [FieldOffset(112)] public FixedBytes16 offset0112; /// /// For internal use only. /// [FieldOffset(128)] public FixedBytes16 offset0128; /// /// For internal use only. /// [FieldOffset(144)] public FixedBytes16 offset0144; /// /// For internal use only. /// [FieldOffset(160)] public FixedBytes16 offset0160; /// /// For internal use only. /// [FieldOffset(176)] public FixedBytes16 offset0176; /// /// For internal use only. /// [FieldOffset(192)] public FixedBytes16 offset0192; /// /// For internal use only. /// [FieldOffset(208)] public FixedBytes16 offset0208; /// /// For internal use only. /// [FieldOffset(224)] public FixedBytes16 offset0224; /// /// For internal use only. /// [FieldOffset(240)] public FixedBytes16 offset0240; /// /// For internal use only. /// [FieldOffset(256)] public FixedBytes16 offset0256; /// /// For internal use only. /// [FieldOffset(272)] public FixedBytes16 offset0272; /// /// For internal use only. /// [FieldOffset(288)] public FixedBytes16 offset0288; /// /// For internal use only. /// [FieldOffset(304)] public FixedBytes16 offset0304; /// /// For internal use only. /// [FieldOffset(320)] public FixedBytes16 offset0320; /// /// For internal use only. /// [FieldOffset(336)] public FixedBytes16 offset0336; /// /// For internal use only. /// [FieldOffset(352)] public FixedBytes16 offset0352; /// /// For internal use only. /// [FieldOffset(368)] public FixedBytes16 offset0368; /// /// For internal use only. /// [FieldOffset(384)] public FixedBytes16 offset0384; /// /// For internal use only. /// [FieldOffset(400)] public FixedBytes16 offset0400; /// /// For internal use only. /// [FieldOffset(416)] public FixedBytes16 offset0416; /// /// For internal use only. /// [FieldOffset(432)] public FixedBytes16 offset0432; /// /// For internal use only. /// [FieldOffset(448)] public FixedBytes16 offset0448; /// /// For internal use only. /// [FieldOffset(464)] public FixedBytes16 offset0464; /// /// For internal use only. /// [FieldOffset(480)] public FixedBytes16 offset0480; /// /// For internal use only. /// [FieldOffset(496)] public FixedBytes16 offset0496; /// /// For internal use only. /// [FieldOffset(512)] public FixedBytes16 offset0512; /// /// For internal use only. /// [FieldOffset(528)] public FixedBytes16 offset0528; /// /// For internal use only. /// [FieldOffset(544)] public FixedBytes16 offset0544; /// /// For internal use only. /// [FieldOffset(560)] public FixedBytes16 offset0560; /// /// For internal use only. /// [FieldOffset(576)] public FixedBytes16 offset0576; /// /// For internal use only. /// [FieldOffset(592)] public FixedBytes16 offset0592; /// /// For internal use only. /// [FieldOffset(608)] public FixedBytes16 offset0608; /// /// For internal use only. /// [FieldOffset(624)] public FixedBytes16 offset0624; /// /// For internal use only. /// [FieldOffset(640)] public FixedBytes16 offset0640; /// /// For internal use only. /// [FieldOffset(656)] public FixedBytes16 offset0656; /// /// For internal use only. /// [FieldOffset(672)] public FixedBytes16 offset0672; /// /// For internal use only. /// [FieldOffset(688)] public FixedBytes16 offset0688; /// /// For internal use only. /// [FieldOffset(704)] public FixedBytes16 offset0704; /// /// For internal use only. /// [FieldOffset(720)] public FixedBytes16 offset0720; /// /// For internal use only. /// [FieldOffset(736)] public FixedBytes16 offset0736; /// /// For internal use only. /// [FieldOffset(752)] public FixedBytes16 offset0752; /// /// For internal use only. /// [FieldOffset(768)] public FixedBytes16 offset0768; /// /// For internal use only. /// [FieldOffset(784)] public FixedBytes16 offset0784; /// /// For internal use only. /// [FieldOffset(800)] public FixedBytes16 offset0800; /// /// For internal use only. /// [FieldOffset(816)] public FixedBytes16 offset0816; /// /// For internal use only. /// [FieldOffset(832)] public FixedBytes16 offset0832; /// /// For internal use only. /// [FieldOffset(848)] public FixedBytes16 offset0848; /// /// For internal use only. /// [FieldOffset(864)] public FixedBytes16 offset0864; /// /// For internal use only. /// [FieldOffset(880)] public FixedBytes16 offset0880; /// /// For internal use only. /// [FieldOffset(896)] public FixedBytes16 offset0896; /// /// For internal use only. /// [FieldOffset(912)] public FixedBytes16 offset0912; /// /// For internal use only. /// [FieldOffset(928)] public FixedBytes16 offset0928; /// /// For internal use only. /// [FieldOffset(944)] public FixedBytes16 offset0944; /// /// For internal use only. /// [FieldOffset(960)] public FixedBytes16 offset0960; /// /// For internal use only. /// [FieldOffset(976)] public FixedBytes16 offset0976; /// /// For internal use only. /// [FieldOffset(992)] public FixedBytes16 offset0992; /// /// For internal use only. /// [FieldOffset(1008)] public FixedBytes16 offset1008; /// /// For internal use only. /// [FieldOffset(1024)] public FixedBytes16 offset1024; /// /// For internal use only. /// [FieldOffset(1040)] public FixedBytes16 offset1040; /// /// For internal use only. /// [FieldOffset(1056)] public FixedBytes16 offset1056; /// /// For internal use only. /// [FieldOffset(1072)] public FixedBytes16 offset1072; /// /// For internal use only. /// [FieldOffset(1088)] public FixedBytes16 offset1088; /// /// For internal use only. /// [FieldOffset(1104)] public FixedBytes16 offset1104; /// /// For internal use only. /// [FieldOffset(1120)] public FixedBytes16 offset1120; /// /// For internal use only. /// [FieldOffset(1136)] public FixedBytes16 offset1136; /// /// For internal use only. /// [FieldOffset(1152)] public FixedBytes16 offset1152; /// /// For internal use only. /// [FieldOffset(1168)] public FixedBytes16 offset1168; /// /// For internal use only. /// [FieldOffset(1184)] public FixedBytes16 offset1184; /// /// For internal use only. /// [FieldOffset(1200)] public FixedBytes16 offset1200; /// /// For internal use only. /// [FieldOffset(1216)] public FixedBytes16 offset1216; /// /// For internal use only. /// [FieldOffset(1232)] public FixedBytes16 offset1232; /// /// For internal use only. /// [FieldOffset(1248)] public FixedBytes16 offset1248; /// /// For internal use only. /// [FieldOffset(1264)] public FixedBytes16 offset1264; /// /// For internal use only. /// [FieldOffset(1280)] public FixedBytes16 offset1280; /// /// For internal use only. /// [FieldOffset(1296)] public FixedBytes16 offset1296; /// /// For internal use only. /// [FieldOffset(1312)] public FixedBytes16 offset1312; /// /// For internal use only. /// [FieldOffset(1328)] public FixedBytes16 offset1328; /// /// For internal use only. /// [FieldOffset(1344)] public FixedBytes16 offset1344; /// /// For internal use only. /// [FieldOffset(1360)] public FixedBytes16 offset1360; /// /// For internal use only. /// [FieldOffset(1376)] public FixedBytes16 offset1376; /// /// For internal use only. /// [FieldOffset(1392)] public FixedBytes16 offset1392; /// /// For internal use only. /// [FieldOffset(1408)] public FixedBytes16 offset1408; /// /// For internal use only. /// [FieldOffset(1424)] public FixedBytes16 offset1424; /// /// For internal use only. /// [FieldOffset(1440)] public FixedBytes16 offset1440; /// /// For internal use only. /// [FieldOffset(1456)] public FixedBytes16 offset1456; /// /// For internal use only. /// [FieldOffset(1472)] public FixedBytes16 offset1472; /// /// For internal use only. /// [FieldOffset(1488)] public FixedBytes16 offset1488; /// /// For internal use only. /// [FieldOffset(1504)] public FixedBytes16 offset1504; /// /// For internal use only. /// [FieldOffset(1520)] public FixedBytes16 offset1520; /// /// For internal use only. /// [FieldOffset(1536)] public FixedBytes16 offset1536; /// /// For internal use only. /// [FieldOffset(1552)] public FixedBytes16 offset1552; /// /// For internal use only. /// [FieldOffset(1568)] public FixedBytes16 offset1568; /// /// For internal use only. /// [FieldOffset(1584)] public FixedBytes16 offset1584; /// /// For internal use only. /// [FieldOffset(1600)] public FixedBytes16 offset1600; /// /// For internal use only. /// [FieldOffset(1616)] public FixedBytes16 offset1616; /// /// For internal use only. /// [FieldOffset(1632)] public FixedBytes16 offset1632; /// /// For internal use only. /// [FieldOffset(1648)] public FixedBytes16 offset1648; /// /// For internal use only. /// [FieldOffset(1664)] public FixedBytes16 offset1664; /// /// For internal use only. /// [FieldOffset(1680)] public FixedBytes16 offset1680; /// /// For internal use only. /// [FieldOffset(1696)] public FixedBytes16 offset1696; /// /// For internal use only. /// [FieldOffset(1712)] public FixedBytes16 offset1712; /// /// For internal use only. /// [FieldOffset(1728)] public FixedBytes16 offset1728; /// /// For internal use only. /// [FieldOffset(1744)] public FixedBytes16 offset1744; /// /// For internal use only. /// [FieldOffset(1760)] public FixedBytes16 offset1760; /// /// For internal use only. /// [FieldOffset(1776)] public FixedBytes16 offset1776; /// /// For internal use only. /// [FieldOffset(1792)] public FixedBytes16 offset1792; /// /// For internal use only. /// [FieldOffset(1808)] public FixedBytes16 offset1808; /// /// For internal use only. /// [FieldOffset(1824)] public FixedBytes16 offset1824; /// /// For internal use only. /// [FieldOffset(1840)] public FixedBytes16 offset1840; /// /// For internal use only. /// [FieldOffset(1856)] public FixedBytes16 offset1856; /// /// For internal use only. /// [FieldOffset(1872)] public FixedBytes16 offset1872; /// /// For internal use only. /// [FieldOffset(1888)] public FixedBytes16 offset1888; /// /// For internal use only. /// [FieldOffset(1904)] public FixedBytes16 offset1904; /// /// For internal use only. /// [FieldOffset(1920)] public FixedBytes16 offset1920; /// /// For internal use only. /// [FieldOffset(1936)] public FixedBytes16 offset1936; /// /// For internal use only. /// [FieldOffset(1952)] public FixedBytes16 offset1952; /// /// For internal use only. /// [FieldOffset(1968)] public FixedBytes16 offset1968; /// /// For internal use only. /// [FieldOffset(1984)] public FixedBytes16 offset1984; /// /// For internal use only. /// [FieldOffset(2000)] public FixedBytes16 offset2000; /// /// For internal use only. /// [FieldOffset(2016)] public FixedBytes16 offset2016; /// /// For internal use only. /// [FieldOffset(2032)] public FixedBytes16 offset2032; /// /// For internal use only. /// [FieldOffset(2048)] public FixedBytes16 offset2048; /// /// For internal use only. /// [FieldOffset(2064)] public FixedBytes16 offset2064; /// /// For internal use only. /// [FieldOffset(2080)] public FixedBytes16 offset2080; /// /// For internal use only. /// [FieldOffset(2096)] public FixedBytes16 offset2096; /// /// For internal use only. /// [FieldOffset(2112)] public FixedBytes16 offset2112; /// /// For internal use only. /// [FieldOffset(2128)] public FixedBytes16 offset2128; /// /// For internal use only. /// [FieldOffset(2144)] public FixedBytes16 offset2144; /// /// For internal use only. /// [FieldOffset(2160)] public FixedBytes16 offset2160; /// /// For internal use only. /// [FieldOffset(2176)] public FixedBytes16 offset2176; /// /// For internal use only. /// [FieldOffset(2192)] public FixedBytes16 offset2192; /// /// For internal use only. /// [FieldOffset(2208)] public FixedBytes16 offset2208; /// /// For internal use only. /// [FieldOffset(2224)] public FixedBytes16 offset2224; /// /// For internal use only. /// [FieldOffset(2240)] public FixedBytes16 offset2240; /// /// For internal use only. /// [FieldOffset(2256)] public FixedBytes16 offset2256; /// /// For internal use only. /// [FieldOffset(2272)] public FixedBytes16 offset2272; /// /// For internal use only. /// [FieldOffset(2288)] public FixedBytes16 offset2288; /// /// For internal use only. /// [FieldOffset(2304)] public FixedBytes16 offset2304; /// /// For internal use only. /// [FieldOffset(2320)] public FixedBytes16 offset2320; /// /// For internal use only. /// [FieldOffset(2336)] public FixedBytes16 offset2336; /// /// For internal use only. /// [FieldOffset(2352)] public FixedBytes16 offset2352; /// /// For internal use only. /// [FieldOffset(2368)] public FixedBytes16 offset2368; /// /// For internal use only. /// [FieldOffset(2384)] public FixedBytes16 offset2384; /// /// For internal use only. /// [FieldOffset(2400)] public FixedBytes16 offset2400; /// /// For internal use only. /// [FieldOffset(2416)] public FixedBytes16 offset2416; /// /// For internal use only. /// [FieldOffset(2432)] public FixedBytes16 offset2432; /// /// For internal use only. /// [FieldOffset(2448)] public FixedBytes16 offset2448; /// /// For internal use only. /// [FieldOffset(2464)] public FixedBytes16 offset2464; /// /// For internal use only. /// [FieldOffset(2480)] public FixedBytes16 offset2480; /// /// For internal use only. /// [FieldOffset(2496)] public FixedBytes16 offset2496; /// /// For internal use only. /// [FieldOffset(2512)] public FixedBytes16 offset2512; /// /// For internal use only. /// [FieldOffset(2528)] public FixedBytes16 offset2528; /// /// For internal use only. /// [FieldOffset(2544)] public FixedBytes16 offset2544; /// /// For internal use only. /// [FieldOffset(2560)] public FixedBytes16 offset2560; /// /// For internal use only. /// [FieldOffset(2576)] public FixedBytes16 offset2576; /// /// For internal use only. /// [FieldOffset(2592)] public FixedBytes16 offset2592; /// /// For internal use only. /// [FieldOffset(2608)] public FixedBytes16 offset2608; /// /// For internal use only. /// [FieldOffset(2624)] public FixedBytes16 offset2624; /// /// For internal use only. /// [FieldOffset(2640)] public FixedBytes16 offset2640; /// /// For internal use only. /// [FieldOffset(2656)] public FixedBytes16 offset2656; /// /// For internal use only. /// [FieldOffset(2672)] public FixedBytes16 offset2672; /// /// For internal use only. /// [FieldOffset(2688)] public FixedBytes16 offset2688; /// /// For internal use only. /// [FieldOffset(2704)] public FixedBytes16 offset2704; /// /// For internal use only. /// [FieldOffset(2720)] public FixedBytes16 offset2720; /// /// For internal use only. /// [FieldOffset(2736)] public FixedBytes16 offset2736; /// /// For internal use only. /// [FieldOffset(2752)] public FixedBytes16 offset2752; /// /// For internal use only. /// [FieldOffset(2768)] public FixedBytes16 offset2768; /// /// For internal use only. /// [FieldOffset(2784)] public FixedBytes16 offset2784; /// /// For internal use only. /// [FieldOffset(2800)] public FixedBytes16 offset2800; /// /// For internal use only. /// [FieldOffset(2816)] public FixedBytes16 offset2816; /// /// For internal use only. /// [FieldOffset(2832)] public FixedBytes16 offset2832; /// /// For internal use only. /// [FieldOffset(2848)] public FixedBytes16 offset2848; /// /// For internal use only. /// [FieldOffset(2864)] public FixedBytes16 offset2864; /// /// For internal use only. /// [FieldOffset(2880)] public FixedBytes16 offset2880; /// /// For internal use only. /// [FieldOffset(2896)] public FixedBytes16 offset2896; /// /// For internal use only. /// [FieldOffset(2912)] public FixedBytes16 offset2912; /// /// For internal use only. /// [FieldOffset(2928)] public FixedBytes16 offset2928; /// /// For internal use only. /// [FieldOffset(2944)] public FixedBytes16 offset2944; /// /// For internal use only. /// [FieldOffset(2960)] public FixedBytes16 offset2960; /// /// For internal use only. /// [FieldOffset(2976)] public FixedBytes16 offset2976; /// /// For internal use only. /// [FieldOffset(2992)] public FixedBytes16 offset2992; /// /// For internal use only. /// [FieldOffset(3008)] public FixedBytes16 offset3008; /// /// For internal use only. /// [FieldOffset(3024)] public FixedBytes16 offset3024; /// /// For internal use only. /// [FieldOffset(3040)] public FixedBytes16 offset3040; /// /// For internal use only. /// [FieldOffset(3056)] public FixedBytes16 offset3056; /// /// For internal use only. /// [FieldOffset(3072)] public FixedBytes16 offset3072; /// /// For internal use only. /// [FieldOffset(3088)] public FixedBytes16 offset3088; /// /// For internal use only. /// [FieldOffset(3104)] public FixedBytes16 offset3104; /// /// For internal use only. /// [FieldOffset(3120)] public FixedBytes16 offset3120; /// /// For internal use only. /// [FieldOffset(3136)] public FixedBytes16 offset3136; /// /// For internal use only. /// [FieldOffset(3152)] public FixedBytes16 offset3152; /// /// For internal use only. /// [FieldOffset(3168)] public FixedBytes16 offset3168; /// /// For internal use only. /// [FieldOffset(3184)] public FixedBytes16 offset3184; /// /// For internal use only. /// [FieldOffset(3200)] public FixedBytes16 offset3200; /// /// For internal use only. /// [FieldOffset(3216)] public FixedBytes16 offset3216; /// /// For internal use only. /// [FieldOffset(3232)] public FixedBytes16 offset3232; /// /// For internal use only. /// [FieldOffset(3248)] public FixedBytes16 offset3248; /// /// For internal use only. /// [FieldOffset(3264)] public FixedBytes16 offset3264; /// /// For internal use only. /// [FieldOffset(3280)] public FixedBytes16 offset3280; /// /// For internal use only. /// [FieldOffset(3296)] public FixedBytes16 offset3296; /// /// For internal use only. /// [FieldOffset(3312)] public FixedBytes16 offset3312; /// /// For internal use only. /// [FieldOffset(3328)] public FixedBytes16 offset3328; /// /// For internal use only. /// [FieldOffset(3344)] public FixedBytes16 offset3344; /// /// For internal use only. /// [FieldOffset(3360)] public FixedBytes16 offset3360; /// /// For internal use only. /// [FieldOffset(3376)] public FixedBytes16 offset3376; /// /// For internal use only. /// [FieldOffset(3392)] public FixedBytes16 offset3392; /// /// For internal use only. /// [FieldOffset(3408)] public FixedBytes16 offset3408; /// /// For internal use only. /// [FieldOffset(3424)] public FixedBytes16 offset3424; /// /// For internal use only. /// [FieldOffset(3440)] public FixedBytes16 offset3440; /// /// For internal use only. /// [FieldOffset(3456)] public FixedBytes16 offset3456; /// /// For internal use only. /// [FieldOffset(3472)] public FixedBytes16 offset3472; /// /// For internal use only. /// [FieldOffset(3488)] public FixedBytes16 offset3488; /// /// For internal use only. /// [FieldOffset(3504)] public FixedBytes16 offset3504; /// /// For internal use only. /// [FieldOffset(3520)] public FixedBytes16 offset3520; /// /// For internal use only. /// [FieldOffset(3536)] public FixedBytes16 offset3536; /// /// For internal use only. /// [FieldOffset(3552)] public FixedBytes16 offset3552; /// /// For internal use only. /// [FieldOffset(3568)] public FixedBytes16 offset3568; /// /// For internal use only. /// [FieldOffset(3584)] public FixedBytes16 offset3584; /// /// For internal use only. /// [FieldOffset(3600)] public FixedBytes16 offset3600; /// /// For internal use only. /// [FieldOffset(3616)] public FixedBytes16 offset3616; /// /// For internal use only. /// [FieldOffset(3632)] public FixedBytes16 offset3632; /// /// For internal use only. /// [FieldOffset(3648)] public FixedBytes16 offset3648; /// /// For internal use only. /// [FieldOffset(3664)] public FixedBytes16 offset3664; /// /// For internal use only. /// [FieldOffset(3680)] public FixedBytes16 offset3680; /// /// For internal use only. /// [FieldOffset(3696)] public FixedBytes16 offset3696; /// /// For internal use only. /// [FieldOffset(3712)] public FixedBytes16 offset3712; /// /// For internal use only. /// [FieldOffset(3728)] public FixedBytes16 offset3728; /// /// For internal use only. /// [FieldOffset(3744)] public FixedBytes16 offset3744; /// /// For internal use only. /// [FieldOffset(3760)] public FixedBytes16 offset3760; /// /// For internal use only. /// [FieldOffset(3776)] public FixedBytes16 offset3776; /// /// For internal use only. /// [FieldOffset(3792)] public FixedBytes16 offset3792; /// /// For internal use only. /// [FieldOffset(3808)] public FixedBytes16 offset3808; /// /// For internal use only. /// [FieldOffset(3824)] public FixedBytes16 offset3824; /// /// For internal use only. /// [FieldOffset(3840)] public FixedBytes16 offset3840; /// /// For internal use only. /// [FieldOffset(3856)] public FixedBytes16 offset3856; /// /// For internal use only. /// [FieldOffset(3872)] public FixedBytes16 offset3872; /// /// For internal use only. /// [FieldOffset(3888)] public FixedBytes16 offset3888; /// /// For internal use only. /// [FieldOffset(3904)] public FixedBytes16 offset3904; /// /// For internal use only. /// [FieldOffset(3920)] public FixedBytes16 offset3920; /// /// For internal use only. /// [FieldOffset(3936)] public FixedBytes16 offset3936; /// /// For internal use only. /// [FieldOffset(3952)] public FixedBytes16 offset3952; /// /// For internal use only. /// [FieldOffset(3968)] public FixedBytes16 offset3968; /// /// For internal use only. /// [FieldOffset(3984)] public FixedBytes16 offset3984; /// /// For internal use only. /// [FieldOffset(4000)] public FixedBytes16 offset4000; /// /// For internal use only. /// [FieldOffset(4016)] public FixedBytes16 offset4016; /// /// For internal use only. /// [FieldOffset(4032)] public FixedBytes16 offset4032; /// /// For internal use only. /// [FieldOffset(4048)] public FixedBytes16 offset4048; /// /// For internal use only. /// [FieldOffset(4064)] public FixedBytes16 offset4064; /// /// For internal use only. /// [FieldOffset(4080)] public byte byte4080; /// /// For internal use only. /// [FieldOffset(4081)] public byte byte4081; /// /// For internal use only. /// [FieldOffset(4082)] public byte byte4082; /// /// For internal use only. /// [FieldOffset(4083)] public byte byte4083; /// /// For internal use only. /// [FieldOffset(4084)] public byte byte4084; /// /// For internal use only. /// [FieldOffset(4085)] public byte byte4085; /// /// For internal use only. /// [FieldOffset(4086)] public byte byte4086; /// /// For internal use only. /// [FieldOffset(4087)] public byte byte4087; /// /// For internal use only. /// [FieldOffset(4088)] public byte byte4088; /// /// For internal use only. /// [FieldOffset(4089)] public byte byte4089; /// /// For internal use only. /// [FieldOffset(4090)] public byte byte4090; /// /// For internal use only. /// [FieldOffset(4091)] public byte byte4091; /// /// For internal use only. /// [FieldOffset(4092)] public byte byte4092; /// /// For internal use only. /// [FieldOffset(4093)] public byte byte4093; } /// /// An unmanaged UTF-8 string whose content is stored directly in the 4096-byte struct. /// /// /// The binary layout of this string is guaranteed, for now and all time, to be a length (a little-endian two byte integer) /// followed by the bytes of the characters (with no padding). A zero byte always immediately follows the last character. /// Effectively, the number of bytes for storing characters is 3 less than 4096 (two length bytes and one null byte). /// /// This layout is identical to a of bytes, thus allowing reinterpretation between FixedString4096Bytes and FixedList4096Bytes. /// /// By virtue of being an unmanaged, non-allocated struct with no pointers, this string is fully compatible with jobs and Burst compilation. /// Unlike managed string types, these strings can be put in any unmanaged ECS components, FixedList, or any other unmanaged structs. /// [Serializable] [StructLayout(LayoutKind.Sequential, Size=4096)] [GenerateTestsForBurstCompatibility] public partial struct FixedString4096Bytes : INativeList , IUTF8Bytes , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable , IComparable , IEquatable { internal const ushort utf8MaxLengthInBytes = 4093; [SerializeField] internal ushort utf8LengthInBytes; [SerializeField] internal FixedBytes4094 bytes; /// /// Returns the maximum number of UTF-8 bytes that can be stored in this string. /// /// /// The maximum number of UTF-8 bytes that can be stored in this string. /// public static int UTF8MaxLengthInBytes => utf8MaxLengthInBytes; /// /// For internal use only. Use instead. /// /// For internal use only. Use instead. [CreateProperty] [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] [ExcludeFromBurstCompatTesting("Returns managed string")] public string Value => ToString(); /// /// Returns a pointer to the character bytes. /// /// /// The pointer returned by this method points into the internals of the target FixedString object. It is the /// caller's responsibility to ensure that the pointer is not used after the FixedString object is destroyed or goes /// out of scope. /// /// A pointer to the character bytes. [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly unsafe byte* GetUnsafePtr() { fixed(void* b = &bytes) return (byte*)b; } /// /// The current length in bytes of this string's content. /// /// /// The length value does not include the null-terminator byte. /// /// The new length in bytes of the string's content. /// Thrown if the new length is out of bounds. /// /// The current length in bytes of this string's content. /// public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8LengthInBytes; } set { CheckLengthInRange(value); utf8LengthInBytes = (ushort)value; unsafe { GetUnsafePtr()[utf8LengthInBytes] = 0; } } } /// /// The number of bytes this string has for storing UTF-8 characters. /// /// The number of bytes this string has for storing UTF-8 characters. /// /// Does not include the null-terminator byte. /// /// A setter is included for conformity with , but is fixed at 4093. /// Setting the value to anything other than 4093 throws an exception. /// /// In UTF-8 encoding, each Unicode code point (character) requires 1 to 4 bytes, /// so the number of characters that can be stored may be less than the capacity. /// /// Thrown if attempting to set the capacity to anything other than 4093. public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { return utf8MaxLengthInBytes; } set { CheckCapacityInRange(value); } } /// /// Attempts to set the length in bytes. Does nothing if the new length is invalid. /// /// The desired length. /// Whether added or removed bytes should be cleared (zeroed). (Increasing the length adds bytes; decreasing the length removes bytes.) /// True if the new length is valid. public bool TryResize(int newLength, NativeArrayOptions clearOptions = NativeArrayOptions.ClearMemory) { if (newLength < 0 || newLength > utf8MaxLengthInBytes) return false; if (newLength == utf8LengthInBytes) return true; unsafe { if (clearOptions == NativeArrayOptions.ClearMemory) { if (newLength > utf8LengthInBytes) UnsafeUtility.MemClear(GetUnsafePtr() + utf8LengthInBytes, newLength - utf8LengthInBytes); else UnsafeUtility.MemClear(GetUnsafePtr() + newLength, utf8LengthInBytes - newLength); } utf8LengthInBytes = (ushort)newLength; // always null terminate GetUnsafePtr()[utf8LengthInBytes] = 0; } return true; } /// /// Returns true if this string is empty (has no characters). /// /// True if this string is empty (has no characters). public readonly bool IsEmpty { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => utf8LengthInBytes == 0; } /// /// Returns the byte (not character) at an index. /// /// A byte index. /// The byte at the index. /// Thrown if the index is out of bounds. public byte this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get { unsafe { CheckIndexInRange(index); return GetUnsafePtr()[index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { unsafe { CheckIndexInRange(index); GetUnsafePtr()[index] = value; } } } /// /// Returns the reference to a byte (not character) at an index. /// /// A byte index. /// A reference to the byte at the index. /// Thrown if the index is out of bounds. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref byte ElementAt(int index) { unsafe { CheckIndexInRange(index); return ref GetUnsafePtr()[index]; } } /// /// Sets the length to 0. /// public void Clear() { Length = 0; } /// /// Appends a byte. /// /// /// A zero byte will always follow the newly appended byte. /// /// No validation is performed: it is your responsibility for the bytes of the string to form valid UTF-8 when you're done appending bytes. /// /// A byte to append. public void Add(in byte value) { this[Length++] = value; } /// /// An enumerator over the characters (not bytes) of a FixedString4096Bytes. /// /// /// In an enumerator's initial state, is not valid to read. /// The first call advances the enumerator's index to the first character. /// public struct Enumerator : IEnumerator { FixedString4096Bytes target; int offset; Unicode.Rune current; /// /// Initializes and returns an instance of FixedString4096Bytes.Enumerator. /// /// A FixeString4096 for which to create an enumerator. public Enumerator(FixedString4096Bytes other) { target = other; offset = 0; current = default; } /// /// Does nothing. /// public void Dispose() { } /// /// Advances the enumerator to the next character. /// /// True if is valid to read after the call. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { if (offset >= target.Length) return false; unsafe { Unicode.Utf8ToUcs(out current, target.GetUnsafePtr(), ref offset, target.Length); } return true; } /// /// Resets the enumerator to its initial state. /// public void Reset() { offset = 0; current = default; } /// /// The current character. /// /// /// In an enumerator's initial state, is not valid to read. /// /// The current character. public Unicode.Rune Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => current; } object IEnumerator.Current => Current; } /// /// Returns an enumerator for iterating over the characters of this string. /// /// An enumerator for iterating over the characters of the FixedString4096Bytes. public Enumerator GetEnumerator() { return new Enumerator(this); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A `System.String` to compare with. /// An integer denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other string.
/// +1 denotes that this string should be sorted to follow the other string.
///
[ExcludeFromBurstCompatTesting("Takes managed string")] public int CompareTo(String other) { return ToString().CompareTo(other); } /// /// Returns true if this string and another have the same length and all the same characters. /// /// A string to compare for equality. /// True if this string and the other have the same length and all the same characters. [ExcludeFromBurstCompatTesting("Takes managed string")] public bool Equals(String other) { unsafe { int alen = utf8LengthInBytes; int blen = other.Length; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(bytes); fixed(char* bptr = other) { return UTF8ArrayUnsafeUtility.StrCmp(aptr, alen, bptr, blen) == 0; } } } /// /// Returns a reference to a FixedList4096Bytes<byte> representation of this string. /// /// /// The referenced FixedListByte4096 is the very same bytes as the original FixedString4096Bytes, /// so it is only valid as long as the original FixedString4096Bytes is valid. /// /// A ref to a FixedListByte4096 representation of the FixedString4096Bytes. public unsafe ref FixedList4096Bytes AsFixedList() { return ref UnsafeUtility.AsRef>(UnsafeUtility.AddressOf(ref this)); } /// /// Initializes and returns an instance of FixedString4096Bytes with the characters copied from a string. /// /// The source string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public FixedString4096Bytes(String source) { this = default; var error = Initialize(source); CheckCopyError(error, source); } /// /// Initializes an instance of FixedString4096Bytes with the characters copied from a string. /// /// The source string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, only the portion that fits is copied in and CopyError.Truncation is returned. [ExcludeFromBurstCompatTesting("Takes managed string")] internal CopyError Initialize(String source) { return this.CopyFromTruncated(source); } /// /// Initializes and returns an instance of FixedString4096Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. public FixedString4096Bytes(Unicode.Rune rune, int count = 1) { this = default; Initialize(rune, count); } /// /// Initializes an instance of FixedString4096Bytes with a single character repeatedly appended some number of times. /// /// The Unicode.Rune to repeat. /// The number of times to repeat the character. Default is 1. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. internal FormatError Initialize(Unicode.Rune rune, int count = 1) { this = default; return this.Append(rune, count); } /// /// Initializes an instance of FixedString4096Bytes that is a copy of another string. /// /// The source buffer. /// The number of bytes to read from the source. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(byte* srcBytes, int srcLength) { bytes = default; utf8LengthInBytes = 0; unsafe { int len = 0; byte* dstBytes = GetUnsafePtr(); var error = UTF8ArrayUnsafeUtility.AppendUTF8Bytes(dstBytes, ref len, utf8MaxLengthInBytes, srcBytes, srcLength); if(error != FormatError.None) return error; this.Length = len; } return FormatError.None; } /// /// Initializes and returns an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. unsafe public FixedString4096Bytes(NativeText.ReadOnly other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Initializes and returns an instance of FixedString4096Bytes that is a copy of another string. /// /// The UnsafeText to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. unsafe public FixedString4096Bytes(in UnsafeText other) { this = default; var error = Initialize(other.GetUnsafePtr(), other.Length); CheckFormatError(error); } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString32Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public FixedString4096Bytes(in FixedString32Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString32Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString4096Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString4096Bytes a, in FixedString32Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString4096Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for inequality. /// A FixedString32Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString4096Bytes a, in FixedString32Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString32Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString32Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString64Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public FixedString4096Bytes(in FixedString64Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString64Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString4096Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString4096Bytes a, in FixedString64Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString4096Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for inequality. /// A FixedString64Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString4096Bytes a, in FixedString64Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString64Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString64Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString128Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public FixedString4096Bytes(in FixedString128Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString128Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString4096Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString4096Bytes a, in FixedString128Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString4096Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for inequality. /// A FixedString128Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString4096Bytes a, in FixedString128Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString128Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString128Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString512Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public FixedString4096Bytes(in FixedString512Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString512Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString4096Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString4096Bytes a, in FixedString512Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString4096Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for inequality. /// A FixedString512Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString4096Bytes a, in FixedString512Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString512Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString512Bytes other) { return this == other; } /// /// Returns the lexicographical sort order of this string relative to another. /// /// A string to compare with. /// A number denoting the lexicographical sort order of this string relative to the other: /// /// 0 denotes that both strings have the same sort position.
/// -1 denotes that this string should be sorted to precede the other.
/// +1 denotes that this string should be sorted to follow the other.
///
public int CompareTo(FixedString4096Bytes other) { return FixedStringMethods.CompareTo(ref this, other); } /// /// Initializes and returns an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. public FixedString4096Bytes(in FixedString4096Bytes other) { this = default; var error = Initialize(other); CheckFormatError(error); } /// /// Initializes an instance of FixedString4096Bytes that is a copy of another string. /// /// The string to copy. /// If the length of the source string exceeds this fixed string's UTF8 capacity, the entire write operation will fail, and FormatError.Overflow is returned. unsafe internal FormatError Initialize(in FixedString4096Bytes other) { return Initialize((byte*) UnsafeUtilityExtensions.AddressOf(other.bytes), other.utf8LengthInBytes); } /// /// Returns true if a FixedString4096Bytes and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public static bool operator ==(in FixedString4096Bytes a, in FixedString4096Bytes b) { // this must not call any methods on 'a' or 'b' unsafe { int alen = a.utf8LengthInBytes; int blen = b.utf8LengthInBytes; byte* aptr = (byte*) UnsafeUtilityExtensions.AddressOf(a.bytes); byte* bptr = (byte*) UnsafeUtilityExtensions.AddressOf(b.bytes); return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes(aptr, alen, bptr, blen); } } /// /// Returns true if a FixedString4096Bytes and another string are unequal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for inequality. /// A FixedString4096Bytes to compare for inequality. /// True if the two strings are unequal. public static bool operator !=(in FixedString4096Bytes a, in FixedString4096Bytes b) { return !(a == b); } /// /// Returns true if this string and another string are equal. /// /// Two strings are equal if they have equal length and all their characters match. /// A FixedString4096Bytes to compare for equality. /// True if the two strings are equal. public bool Equals(FixedString4096Bytes other) { return this == other; } /// /// Returns a new FixedString4096Bytes that is a copy of another string. /// /// A string to copy. /// A new FixedString4096Bytes that is a copy of another string. /// Thrown if the string to copy's length exceeds the capacity of FixedString4096Bytes. [ExcludeFromBurstCompatTesting("Takes managed string")] public static implicit operator FixedString4096Bytes(string b) => new FixedString4096Bytes(b); /// /// Returns a new managed string that is a copy of this string. /// /// A new managed string that is a copy of this string. [ExcludeFromBurstCompatTesting("Returns managed string")] public override String ToString() { return this.ConvertToString(); } /// /// Returns a hash code of this string. /// /// Only the character bytes are included in the hash: any bytes beyond are not part of the hash. /// The hash code of this string. public override int GetHashCode() { return this.ComputeHashCode(); } /// /// Returns true if this string and an object are equal. /// /// /// Returns false if the object is neither a System.String or a FixedString. /// /// Two strings are equal if they have equal length and all their characters match. /// An object to compare for equality. /// True if this string and the object are equal. [ExcludeFromBurstCompatTesting("Takes managed object")] public override bool Equals(object obj) { if(ReferenceEquals(null, obj)) return false; if(obj is String aString) return Equals(aString); if(obj is FixedString32Bytes aFixedString32Bytes) return Equals(aFixedString32Bytes); if(obj is FixedString64Bytes aFixedString64Bytes) return Equals(aFixedString64Bytes); if(obj is FixedString128Bytes aFixedString128Bytes) return Equals(aFixedString128Bytes); if(obj is FixedString512Bytes aFixedString512Bytes) return Equals(aFixedString512Bytes); if(obj is FixedString4096Bytes aFixedString4096Bytes) return Equals(aFixedString4096Bytes); return false; } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly void CheckIndexInRange(int index) { if (index < 0) throw new IndexOutOfRangeException($"Index {index} must be positive."); if (index >= utf8LengthInBytes) throw new IndexOutOfRangeException($"Index {index} is out of range in FixedString4096Bytes of '{utf8LengthInBytes}' Length."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckLengthInRange(int length) { if (length < 0) throw new ArgumentOutOfRangeException($"Length {length} must be positive."); if (length > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Length {length} is out of range in FixedString4096Bytes of '{utf8MaxLengthInBytes}' Capacity."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] void CheckCapacityInRange(int capacity) { if (capacity > utf8MaxLengthInBytes) throw new ArgumentOutOfRangeException($"Capacity {capacity} must be lower than {utf8MaxLengthInBytes}."); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckCopyError(CopyError error, String source) { if (error != CopyError.None) throw new ArgumentException($"FixedString4096Bytes: {error} while copying \"{source}\""); } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")] static void CheckFormatError(FormatError error) { if (error != FormatError.None) throw new ArgumentException("Source is too long to fit into fixed string of this size"); } } }