A game about forced loneliness, made by TACStudios
1using System; 2using NUnit.Framework; 3using Unity.Collections.NotBurstCompatible; 4using Unity.Collections.LowLevel.Unsafe; 5using Unity.Jobs; 6using UnityEngine.TestTools; 7using UnityEngine; 8 9namespace Unity.Collections.Tests 10{ 11 internal class DataStreamTests 12 { 13 internal class ReadAndWrite 14 { 15 [TestCase(ushort.MaxValue)] 16 [TestCase(ushort.MinValue)] 17 public void UShort(ushort expected) 18 { 19 bool Write(ref DataStreamWriter writer) => writer.WriteUShort(expected); 20 CheckReadWrite(sizeof(ushort), reader => reader.ReadUShort(), Write, expected); 21 } 22 23 [TestCase((uint) 0b101010)] 24 [TestCase((uint) 0b111111)] 25 public void RawBits(uint expected) 26 { 27 bool Write(ref DataStreamWriter writer) => writer.WriteRawBits(expected, 6); 28 CheckReadWrite(6, reader => reader.ReadRawBits(6), Write, expected); 29 } 30 31 [Test] 32 public void RawBits_OutOfCapacity() 33 { 34 const uint expected = 0b101011001; 35 var writer = new DataStreamWriter(1, Allocator.Temp); 36 Assert.False(writer.WriteRawBits(expected, 9)); 37 Assert.True(writer.HasFailedWrites); 38 } 39 40 [TestCase(uint.MaxValue)] 41 [TestCase(uint.MinValue)] 42 public void UInt(uint expected) 43 { 44 bool Write(ref DataStreamWriter writer) => writer.WriteUInt(expected); 45 CheckReadWrite(sizeof(uint), reader => reader.ReadUInt(), Write, expected); 46 } 47 48 [TestCase(float.MaxValue)] 49 [TestCase(float.MinValue)] 50 public void Float(float expected) 51 { 52 bool Write(ref DataStreamWriter writer) => writer.WriteFloat(expected); 53 CheckReadWrite(sizeof(float), reader => reader.ReadFloat(), Write, expected); 54 } 55 56 [TestCase(short.MaxValue)] 57 [TestCase(short.MinValue)] 58 public void Short(short expected) 59 { 60 bool Write(ref DataStreamWriter writer) => writer.WriteShort(expected); 61 CheckReadWrite(sizeof(short), reader => reader.ReadShort(), Write, expected); 62 } 63 64 [Test] 65 public void FixedString32() 66 { 67 var expected = new FixedString32Bytes("This is a string"); 68 bool Write(ref DataStreamWriter writer) => writer.WriteFixedString32(expected); 69 CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString32(), Write, expected); 70 } 71 72 [Test] 73 public void FixedString64() 74 { 75 var expected = new FixedString64Bytes("This is a string"); 76 bool Write(ref DataStreamWriter writer) => writer.WriteFixedString64(expected); 77 CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString64(), Write, expected); 78 } 79 80 [Test] 81 public void FixedString128() 82 { 83 var expected = new FixedString128Bytes("This is a string"); 84 bool Write(ref DataStreamWriter writer) => writer.WriteFixedString128(expected); 85 CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString128(), Write, expected); 86 } 87 88 [Test] 89 public void FixedString512() 90 { 91 var expected = new FixedString512Bytes("This is a string"); 92 bool Write(ref DataStreamWriter writer) => writer.WriteFixedString512(expected); 93 CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString512(), Write, expected); 94 } 95 96 [Test] 97 public void FixedString4096() 98 { 99 var expected = new FixedString4096Bytes("This is a string"); 100 bool Write(ref DataStreamWriter writer) => writer.WriteFixedString4096(expected); 101 CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString4096(), Write, 102 expected); 103 } 104 105 [Test] 106 public void LongLooped() 107 { 108 const long baseVal = -99; 109 const long expected = -1979; 110 bool Write(ref DataStreamWriter writer, long value) => writer.WriteLong(value); 111 long Read(ref DataStreamReader reader) => reader.ReadLong(); 112 CheckReadWriteLooped(sizeof(long), baseVal, expected, Write, Read, (l, u) => l + u); 113 } 114 } 115 116 internal class ReadAndWriteNetworkOrder 117 { 118 [TestCase(int.MaxValue)] 119 [TestCase(int.MinValue)] 120 public void Int(int expected) 121 { 122 bool Write(ref DataStreamWriter writer) => writer.WriteIntNetworkByteOrder(expected); 123 CheckReadWrite(sizeof(int), reader => reader.ReadIntNetworkByteOrder(), Write, expected); 124 } 125 126 [TestCase(uint.MaxValue)] 127 [TestCase(uint.MinValue)] 128 public void UInt(uint expected) 129 { 130 bool Write(ref DataStreamWriter writer) => writer.WriteUIntNetworkByteOrder(expected); 131 CheckReadWrite(sizeof(uint), reader => reader.ReadUIntNetworkByteOrder(), Write, expected); 132 } 133 134 [TestCase(short.MaxValue)] 135 [TestCase(short.MinValue)] 136 public void Short(short expected) 137 { 138 bool Write(ref DataStreamWriter writer) => writer.WriteShortNetworkByteOrder(expected); 139 CheckReadWrite(sizeof(short), reader => reader.ReadShortNetworkByteOrder(), Write, expected); 140 } 141 142 [TestCase(ushort.MaxValue)] 143 [TestCase(ushort.MinValue)] 144 public void UShort(ushort expected) 145 { 146 bool Write(ref DataStreamWriter writer) => writer.WriteUShortNetworkByteOrder(expected); 147 CheckReadWrite(sizeof(ushort), reader => reader.ReadUShortNetworkByteOrder(), Write, expected); 148 } 149 150 [Test] 151 public void ReadIncorrect() 152 { 153 var dataStream = new DataStreamWriter(4, Allocator.Temp); 154 dataStream.WriteIntNetworkByteOrder(1979); 155 dataStream.Flush(); 156 var reader = new DataStreamReader(dataStream.AsNativeArray()); 157 Assert.AreNotEqual(1979, reader.ReadInt()); 158 } 159 } 160 161 internal class ReadWritePacked 162 { 163 [Test] 164 public void UInt() 165 { 166 const uint expected = 1979; 167 const uint baseVal = 2000; 168 bool Write(ref DataStreamWriter writer) => writer.WriteUInt(expected); 169 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, uint value) => writer.WritePackedUInt(value, model); 170 uint Read(ref DataStreamReader reader) => reader.ReadUInt(); 171 uint ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedUInt(model); 172 CheckReadWritePackedLooped(sizeof(uint), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u); 173 } 174 175 [Test] 176 public void IntExistingData() 177 { 178 unsafe 179 { 180 var n = 300 * 4; 181 var data = stackalloc byte[n]; 182 var compressionModel = StreamCompressionModel.Default; 183 var dataStream = new DataStreamWriter(data, n); 184 const int base_val = -10; 185 const int count = 20; 186 for (int i = 0; i < count; ++i) 187 dataStream.WritePackedInt(base_val + i, compressionModel); 188 189 dataStream.WriteInt((int)1979); 190 dataStream.Flush(); 191 192 var na = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>(data, n, Allocator.Invalid); 193#if ENABLE_UNITY_COLLECTIONS_CHECKS 194 NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref na, AtomicSafetyHandle.GetTempMemoryHandle()); 195#endif 196 var reader = new DataStreamReader(na); 197 for (int i = 0; i < count; ++i) 198 { 199 var val = reader.ReadPackedInt(compressionModel); 200 Assert.AreEqual(base_val + i, val); 201 } 202 203 Assert.AreEqual(1979, reader.ReadInt()); 204 } 205 } 206 207 [Test] 208 public void Int() 209 { 210 const int expected = -1979; 211 const int baseVal = -10; 212 bool Write(ref DataStreamWriter writer) => writer.WriteInt(expected); 213 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, int value) => writer.WritePackedInt(value, model); 214 int Read(ref DataStreamReader reader) => reader.ReadInt(); 215 int ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedInt(model); 216 CheckReadWritePackedLooped(sizeof(int), baseVal, expected, Write, WritePacked, Read, ReadPacked, (i, u) => (int)(i + u)); 217 } 218 219 [Test] 220 public void Long() 221 { 222 const long expected = -1979; 223 const long baseVal = -99; 224 bool Write(ref DataStreamWriter writer) => writer.WriteLong(expected); 225 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, long value) => writer.WritePackedLong(value, model); 226 long Read(ref DataStreamReader reader) => reader.ReadLong(); 227 long ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedLong(model); 228 229 CheckReadWritePackedLooped(sizeof(long), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u); 230 } 231 232 [Test] 233 public void ULong() 234 { 235 const ulong expected = 1979; 236 const ulong baseVal = 2000; 237 bool Write(ref DataStreamWriter writer) => writer.WriteULong(expected); 238 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, ulong value) => writer.WritePackedULong(value, model); 239 ulong Read(ref DataStreamReader reader) => reader.ReadULong(); 240 ulong ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedULong(model); 241 CheckReadWritePackedLooped(sizeof(ulong), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u); 242 } 243 244 [Test] 245 public void Float() 246 { 247 const float expected = 1979.1f; 248 const float baseVal = 2000.1f; 249 bool Write(ref DataStreamWriter writer) => writer.WriteFloat(expected); 250 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, float value) => writer.WritePackedFloat(value, model); 251 float Read(ref DataStreamReader reader) => reader.ReadFloat(); 252 float ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFloat(model); 253 CheckReadWritePackedLooped(sizeof(float), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u); 254 } 255 256 [Test] 257 public void Double() 258 { 259 const double expected = 1979.1989; 260 const double baseVal = 2000.2000; 261 bool Write(ref DataStreamWriter writer) => writer.WriteDouble(expected); 262 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, double value) => writer.WritePackedDouble(value, model); 263 double Read(ref DataStreamReader reader) => reader.ReadDouble(); 264 double ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedDouble(model); 265 CheckReadWritePackedLooped(sizeof(double), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u); 266 } 267 268 [Test] 269 public void WriteOutSideOfCapacity_Fails() 270 { 271 var model = StreamCompressionModel.Default; 272 var writer = new DataStreamWriter(sizeof(uint) / 2, Allocator.Temp); 273 Assert.False(writer.HasFailedWrites); 274 Assert.False(writer.WritePackedUInt(uint.MaxValue, model), "Writing a uint where there is no room should fail."); 275 Assert.That(writer.HasFailedWrites); 276 } 277 278 [Test] 279 [TestRequiresDotsDebugOrCollectionChecks] 280 public void ReadOutSideOfCapacity_Fails() 281 { 282 var model = StreamCompressionModel.Default; 283 var reader = new DataStreamReader(new NativeArray<byte>(0, Allocator.Temp)); 284 LogAssert.Expect(LogType.Error, "Trying to read 2 bits from a stream where only 0 are available"); 285 Assert.That(reader.ReadPackedUInt(model), Is.EqualTo(0)); 286 Assert.That(reader.HasFailedReads); 287 } 288 } 289 290 internal class ReadWritePackedDelta 291 { 292 [Test] 293 public void Int() 294 { 295 const int expected = int.MaxValue; 296 const int baseline = int.MinValue; 297 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedIntDelta(expected, baseline, model); 298 int ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedIntDelta(baseline, model); 299 CheckReadWritePacked(sizeof(int), ReadPacked, WritePacked, expected); 300 } 301 302 [Test] 303 public void Long() 304 { 305 const long expected = long.MaxValue; 306 const long baseline = long.MinValue; 307 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedLongDelta(expected, baseline, model); 308 long ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedLongDelta(baseline, model); 309 CheckReadWritePacked(sizeof(long), ReadPacked, WritePacked, expected); 310 } 311 312 [Test] 313 public void ULong() 314 { 315 const ulong expected = ulong.MaxValue; 316 const ulong baseline = ulong.MinValue; 317 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedULongDelta(expected, baseline, model); 318 ulong ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedULongDelta(baseline, model); 319 CheckReadWritePacked(sizeof(ulong), ReadPacked, WritePacked, expected); 320 } 321 322 [Test] 323 public void FixedString32() 324 { 325 var expected = new FixedString32Bytes("This is a string"); 326 var baseline = new FixedString32Bytes("This is another string"); 327 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString32Delta(expected, baseline, model); 328 FixedString32Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString32Delta(baseline, model); 329 CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected); 330 } 331 332 [Test] 333 public void FixedString32_LargerBaseline() 334 { 335 var expected = new FixedString32Bytes("This is another string"); 336 var baseline = new FixedString32Bytes("This is a string"); 337 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString32Delta(expected, baseline, model); 338 FixedString32Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString32Delta(baseline, model); 339 CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected); 340 } 341 342 [Test] 343 public void FixedString64() 344 { 345 var expected = new FixedString64Bytes("This is a string"); 346 var baseline = new FixedString64Bytes("This is another string"); 347 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString64Delta(expected, baseline, model); 348 FixedString64Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString64Delta(baseline, model); 349 CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected); 350 } 351 352 [Test] 353 public void FixedString128() 354 { 355 var expected = new FixedString128Bytes("This is a string"); 356 var baseline = new FixedString128Bytes("This is another string"); 357 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString128Delta(expected, baseline, model); 358 FixedString128Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString128Delta(baseline, model); 359 CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected); 360 } 361 362 [Test] 363 public void FixedString512() 364 { 365 var expected = new FixedString512Bytes("This is a string"); 366 var baseline = new FixedString512Bytes("This is another string"); 367 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString512Delta(expected, baseline, model); 368 FixedString512Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString512Delta(baseline, model); 369 CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected); 370 } 371 372 [Test] 373 public void FixedString4096() 374 { 375 var expected = new FixedString4096Bytes("This is a string"); 376 var baseline = new FixedString4096Bytes("This is another string"); 377 bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString4096Delta(expected, baseline, model); 378 FixedString4096Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString4096Delta(baseline, model); 379 CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected); 380 } 381 382 [Test] 383 public void Float_OutOfBoundsFails() 384 { 385 const float expected = float.MaxValue; 386 const float baseline = float.MinValue; 387 var model = StreamCompressionModel.Default; 388 var writer = new DataStreamWriter(sizeof(float) / 2, Allocator.Temp); 389 Assert.False(writer.HasFailedWrites); 390 Assert.False(writer.WritePackedFloatDelta(expected, baseline, model)); 391 Assert.That(writer.HasFailedWrites); 392 } 393 394 [Test] 395 public void Float_UnchangedData() 396 { 397 const float expected = float.MaxValue; 398 const float baseline = float.MaxValue; 399 var model = StreamCompressionModel.Default; 400 var writer = new DataStreamWriter(1, Allocator.Temp); 401 Assert.True(writer.WritePackedFloatDelta(expected, baseline, model)); 402 var reader = new DataStreamReader(writer.AsNativeArray()); 403 Assert.AreEqual(baseline, reader.ReadPackedFloatDelta(baseline, model)); 404 Assert.That(reader.GetBitsRead(), Is.EqualTo(1)); 405 } 406 407 [Test] 408 public void Float_ChangedData() 409 { 410 const float expected = float.MaxValue; 411 const float baseline = float.MinValue; 412 var model = StreamCompressionModel.Default; 413 var writer = new DataStreamWriter(sizeof(float) + 1, Allocator.Temp); 414 Assert.True(writer.WritePackedFloatDelta(expected, baseline, model)); 415 var reader = new DataStreamReader(writer.AsNativeArray()); 416 Assert.AreEqual(1, reader.ReadRawBits(1)); 417 var uf = new UIntFloat 418 { 419 intValue = reader.ReadRawBits(32) 420 }; 421 Assert.AreEqual(expected, uf.floatValue); 422 } 423 424 [Test] 425 [TestRequiresDotsDebugOrCollectionChecks] 426 public void UInt_OutOfCapacity() 427 { 428 var model = StreamCompressionModel.Default; 429 var writer = new DataStreamWriter(0, Allocator.Temp); 430 var reader = new DataStreamReader(writer.AsNativeArray()); 431 LogAssert.Expect(LogType.Error, "Trying to read 2 bits from a stream where only 0 are available"); 432 Assert.That(reader.ReadPackedUInt(model), Is.EqualTo(0)); 433 Assert.That(reader.HasFailedReads); 434 } 435 436 437 // We test with a variable amount of writes to ensure we overflow the internal ulong bitBuffer. 438 [Test] 439 public void Flush_Works([Values(1, 7, 24, 65)]int numWrites) 440 { 441 const int baseline = 100; 442 var model = StreamCompressionModel.Default; 443 var writer = new DataStreamWriter(512, Allocator.Temp); 444 445 // Writer: 446 for(int i = 0; i < numWrites; i++) 447 writer.WritePackedUIntDelta((uint) (100 + i), baseline, model); 448 449 // Flush, and write another sentinel value in. 450 writer.Flush(); 451 writer.WritePackedUIntDelta(45, baseline, model); 452 writer.Flush(); 453 Assert.IsFalse(writer.HasFailedWrites, "Sanity: writer.HasFailedWrites"); 454 455 // Reader: 456 var reader = new DataStreamReader(writer.AsNativeArray()); 457 for(int i = 0; i < numWrites; i++) 458 { 459 var read = reader.ReadPackedUIntDelta(baseline, model); 460 Assert.AreEqual((uint)(100 + i), read, "100 + i"); 461 } 462 463 // When we flush the reader, we expect to now be aligned. 464 reader.Flush(); 465 var read45 = reader.ReadPackedUIntDelta(baseline, model); 466 Assert.AreEqual(45, read45, "45"); 467 reader.Flush(); 468 Assert.IsFalse(reader.HasFailedReads, "reader.HasFailedReads"); 469 Assert.AreEqual(writer.LengthInBits, reader.GetBitsRead(), "writer.LengthInBits vs reader.GetBitsRead()"); 470 LogAssert.NoUnexpectedReceived(); 471 } 472 473 [Test] 474 public void NotMirroringFlushCall_Fails() 475 { 476 const int baseline = 100; 477 var model = StreamCompressionModel.Default; 478 var writer = new DataStreamWriter(512, Allocator.Temp); 479 480 // Writer: 481 writer.WritePackedUIntDelta(100, baseline, model); 482 Assert.AreNotEqual(0, writer.LengthInBits % 8, "Sanity: Not byte aligned!"); 483 writer.Flush(); 484 writer.WritePackedUIntDelta(45, baseline, model); 485 writer.Flush(); 486 Assert.IsFalse(writer.HasFailedWrites, "Sanity: writer.HasFailedWrites"); 487 488 // Reader: 489 var reader = new DataStreamReader(writer.AsNativeArray()); 490 var read = reader.ReadPackedUIntDelta(baseline, model); 491 Assert.AreEqual(100u, read, "100u"); 492 493 // SKIPPED: reader.Flush(); 494 // THUS: Read pointer alignment should be wrong. 495 LogAssert.ignoreFailingMessages = true; // Defensive: Technically we're reading too FEW bits, 496 // so we shouldn't get error logs here. 497 Assert.AreNotEqual(45, reader.ReadPackedIntDelta(baseline, model), "!45"); 498 Assert.AreNotEqual(writer.LengthInBits, reader.GetBitsRead(), "writer.LengthInBits vs reader.GetBitsRead()"); 499 } 500 501 [Test] 502 public void CanMixPackedAndNonPacked() 503 { 504 const int baseline = 200; 505 var model = StreamCompressionModel.Default; 506 var writer = new DataStreamWriter(12, Allocator.Temp); 507 508 writer.WritePackedIntDelta(201, baseline, model); 509 Assert.AreNotEqual(0, writer.LengthInBits % 8, "Sanity: This test is invalid if we accidentally byte-align."); 510 writer.WriteInt(202); 511 writer.WritePackedInt(203, model); 512 writer.WriteInt(204); 513 514 Assert.IsFalse(writer.HasFailedWrites, "Sanity: writer.HasFailedWrites"); 515 516 var reader = new DataStreamReader(writer.AsNativeArray()); 517 Assert.AreEqual(201, reader.ReadPackedIntDelta(baseline, model)); 518 Assert.AreEqual(202, reader.ReadInt()); 519 Assert.AreEqual(203, reader.ReadPackedInt(model)); 520 Assert.AreEqual(204, reader.ReadInt()); 521 Assert.IsFalse(reader.HasFailedReads, "reader.HasFailedReads"); 522 } 523 } 524 525 [Test] 526 public void IsCreated_ReturnsTrueAfterConstructor() 527 { 528 var dataStream = new DataStreamWriter(4, Allocator.Temp); 529 Assert.True(dataStream.IsCreated, "Buffer must be created after calling constructor."); 530 } 531 532 [Test] 533 public void LengthInBits_MatchesWrittenCount() 534 { 535 var dataStream = new DataStreamWriter(4, Allocator.Temp); 536 dataStream.WriteByte(0); 537 Assert.That(dataStream.LengthInBits, Is.EqualTo(1 * 8)); 538 dataStream.WriteByte(1); 539 dataStream.WriteByte(1); 540 Assert.That(dataStream.LengthInBits, Is.EqualTo(3 * 8)); 541 } 542 543 [Test] 544 public void CreateStreamWithPartOfSourceByteArray() 545 { 546 byte[] byteArray = 547 { 548 (byte)'s', (byte)'o', (byte)'m', (byte)'e', 549 (byte)' ', (byte)'d', (byte)'a', (byte)'t', (byte)'a' 550 }; 551 552 DataStreamWriter dataStream; 553 dataStream = new DataStreamWriter(4, Allocator.Temp); 554 dataStream.WriteBytes(new NativeArray<byte>(byteArray, Allocator.Temp).GetSubArray(0, 4)); 555 Assert.AreEqual(dataStream.Length, 4); 556 var reader = new DataStreamReader(dataStream.AsNativeArray()); 557 for (int i = 0; i < dataStream.Length; ++i) 558 { 559 Assert.AreEqual(byteArray[i], reader.ReadByte()); 560 } 561 562#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG 563 LogAssert.Expect(LogType.Error, "Trying to read 1 bytes from a stream where only 0 are available"); 564 Assert.AreEqual(0, reader.ReadByte()); 565#endif 566 } 567 568 [Test] 569 public void CreateStreamWithSourceByteArray() 570 { 571 byte[] byteArray = new byte[100]; 572 byteArray[0] = (byte)'a'; 573 byteArray[1] = (byte)'b'; 574 byteArray[2] = (byte)'c'; 575 576 DataStreamWriter dataStream1, dataStream2; 577 dataStream1 = new DataStreamWriter(byteArray.Length, Allocator.Temp); 578 dataStream2 = new DataStreamWriter(byteArray.Length, Allocator.Temp); 579 dataStream1.WriteBytes(new NativeArray<byte>(byteArray, Allocator.Temp)); 580 dataStream2.WriteBytes(byteArray); 581 582 var arr1 = dataStream1.AsNativeArray(); 583 var arr2 = dataStream2.AsNativeArray(); 584 var reader1 = new DataStreamReader(arr1); 585 var reader2 = new DataStreamReader(arr2); 586 for (var i = 0; i < byteArray.Length; ++i) 587 { 588 Assert.AreEqual(byteArray[i], reader1.ReadByte()); 589 Assert.AreEqual(byteArray[i], reader2.ReadByte()); 590 } 591 } 592 593 [Test] 594 public void ReadIntoExistingNativeByteArray() 595 { 596 var byteArray = new NativeArray<byte>(100, Allocator.Temp); 597 598 DataStreamWriter dataStream; 599 dataStream = new DataStreamWriter(3, Allocator.Temp); 600 { 601 dataStream.WriteByte((byte)'a'); 602 dataStream.WriteByte((byte)'b'); 603 dataStream.WriteByte((byte)'c'); 604 var reader = new DataStreamReader(dataStream.AsNativeArray()); 605 reader.ReadBytes(byteArray.GetSubArray(0, dataStream.Length)); 606 reader = new DataStreamReader(dataStream.AsNativeArray()); 607 for (int i = 0; i < reader.Length; ++i) 608 { 609 Assert.AreEqual(byteArray[i], reader.ReadByte()); 610 } 611 } 612 } 613 614 [Test] 615 public void ReadIntoExistingByteArray() 616 { 617 var byteArray = new byte[3]; 618 619 DataStreamWriter dataStream; 620 dataStream = new DataStreamWriter(3, Allocator.Temp); 621 { 622 dataStream.WriteByte((byte)'a'); 623 dataStream.WriteByte((byte)'b'); 624 dataStream.WriteByte((byte)'c'); 625 var reader = new DataStreamReader(dataStream.AsNativeArray()); 626 reader.ReadBytes(byteArray); 627 reader = new DataStreamReader(dataStream.AsNativeArray()); 628 for (int i = 0; i < reader.Length; ++i) 629 { 630 Assert.AreEqual(byteArray[i], reader.ReadByte()); 631 } 632 } 633 } 634 635 [Test] 636 public void ReadingDataFromStreamWithSliceOffset() 637 { 638 var dataStream = new DataStreamWriter(100, Allocator.Temp); 639 dataStream.WriteByte((byte)'a'); 640 dataStream.WriteByte((byte)'b'); 641 dataStream.WriteByte((byte)'c'); 642 dataStream.WriteByte((byte)'d'); 643 dataStream.WriteByte((byte)'e'); 644 dataStream.WriteByte((byte)'f'); 645 var reader = new DataStreamReader(dataStream.AsNativeArray().GetSubArray(3, 3)); 646 Assert.AreEqual('d', reader.ReadByte()); 647 Assert.AreEqual('e', reader.ReadByte()); 648 Assert.AreEqual('f', reader.ReadByte()); 649 } 650 651 [Test] 652 public void GetStreamReaderUnsafePtr() 653 { 654 var a = new NativeArray<byte>(1, Allocator.Temp); 655 a[0] = (byte)42; 656 var reader = new DataStreamReader(a); 657 658 unsafe 659 { 660 var ptr = (byte*)reader.GetUnsafeReadOnlyPtr(); 661 Assert.AreEqual((byte)42, *ptr); 662 } 663 } 664 665 [Test] 666 public void WriteOutOfBounds() 667 { 668 var dataStream = new DataStreamWriter(9, Allocator.Temp); 669 Assert.IsTrue(dataStream.WriteInt(42)); 670 Assert.AreEqual(4, dataStream.Length); 671 Assert.IsTrue(dataStream.WriteInt(42)); 672 Assert.AreEqual(8, dataStream.Length); 673 Assert.IsFalse(dataStream.HasFailedWrites); 674 Assert.IsFalse(dataStream.WriteInt(42)); 675 Assert.AreEqual(8, dataStream.Length); 676 Assert.IsTrue(dataStream.HasFailedWrites); 677 678 Assert.IsFalse(dataStream.WriteShort(42)); 679 Assert.AreEqual(8, dataStream.Length); 680 Assert.IsTrue(dataStream.HasFailedWrites); 681 682 Assert.IsTrue(dataStream.WriteByte(42)); 683 Assert.AreEqual(9, dataStream.Length); 684 Assert.IsTrue(dataStream.HasFailedWrites); 685 686 Assert.IsFalse(dataStream.WriteByte(42)); 687 Assert.AreEqual(9, dataStream.Length); 688 Assert.IsTrue(dataStream.HasFailedWrites); 689 } 690 691 [Test] 692 public void ReadWritePackedUIntWithDeferred() 693 { 694 var compressionModel = StreamCompressionModel.Default; 695 var dataStream = new DataStreamWriter(300 * 4, Allocator.Temp); 696 uint base_val = 2000; 697 uint count = 277; 698 var def = dataStream; 699 dataStream.WriteInt((int)0); 700 for (uint i = 0; i < count; ++i) 701 dataStream.WritePackedUInt(base_val + i, compressionModel); 702 703 dataStream.Flush(); 704 def.WriteInt(1979); 705 def = dataStream; 706 dataStream.WriteInt((int)0); 707 def.WriteInt(1979); 708 dataStream.Flush(); 709 var reader = new DataStreamReader(dataStream.AsNativeArray()); 710 Assert.AreEqual(1979, reader.ReadInt()); 711 for (uint i = 0; i < count; ++i) 712 { 713 var val = reader.ReadPackedUInt(compressionModel); 714 Assert.AreEqual(base_val + i, val); 715 } 716 717 Assert.AreEqual(1979, reader.ReadInt()); 718 } 719 720 [Test] 721 public void PassDataStreamReaderToJob() 722 { 723 using (var returnValue = new NativeArray<int>(1, Allocator.TempJob)) 724 { 725 var writer = new DataStreamWriter(sizeof(int), Allocator.Temp); 726 writer.WriteInt(42); 727 728 var reader = new DataStreamReader(writer.AsNativeArray()); 729 730 new ReaderTestJob 731 { 732 Reader = reader, 733 ReturnValue = returnValue 734 }.Run(); 735 736 Assert.AreEqual(42, returnValue[0]); 737 } 738 } 739 740 private struct ReaderTestJob : IJob 741 { 742 public DataStreamReader Reader; 743 public NativeArray<int> ReturnValue; 744 745 public void Execute() 746 { 747 ReturnValue[0] = Reader.ReadInt(); 748 } 749 } 750 751 delegate T Read<out T>(ref DataStreamReader reader); 752 delegate T ReadPacked<out T>(ref DataStreamReader reader, StreamCompressionModel model); 753 delegate bool Write(ref DataStreamWriter writer); 754 delegate T Sum<T>(T x, uint y); 755 delegate bool WriteWithValue<in T>(ref DataStreamWriter writer, T value); 756 delegate bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model); 757 delegate bool WritePackedWithValue<in T>(ref DataStreamWriter writer, StreamCompressionModel model, T value); 758 759 const int FixedStringHeader = 2; 760 761 static void CheckReadWritePackedLooped<T>(int size, T baseVal, T expected, 762 Write write, WritePackedWithValue<T> writePackedWithValue, 763 Read<T> read, ReadPacked<T> readPacked, Sum<T> sum) 764 { 765 var compressionModel = StreamCompressionModel.Default; 766 var dataStream = new DataStreamWriter(300 * size, Allocator.Temp); 767 const int count = 277; 768 for (uint i = 0; i < count; ++i) 769 { 770 T res = sum(baseVal, i); 771 writePackedWithValue(ref dataStream, compressionModel, res); 772 } 773 774 write(ref dataStream); 775 dataStream.Flush(); 776 var reader = new DataStreamReader(dataStream.AsNativeArray()); 777 for (uint i = 0; i < count; ++i) 778 { 779 var val = readPacked(ref reader, compressionModel); 780 Assert.AreEqual(sum(baseVal, i), val); 781 } 782 783 Assert.AreEqual(expected, read(ref reader)); 784 } 785 786 static void CheckReadWritePacked<T>(int size, ReadPacked<T> read, WritePacked write, T value) 787 { 788 var model = StreamCompressionModel.Default; 789 var writer = new DataStreamWriter(size, Allocator.Temp); 790 write(ref writer, model); 791 writer.Flush(); 792 var reader = new DataStreamReader(writer.AsNativeArray()); 793 Assert.That(read(ref reader, model), Is.EqualTo(value)); 794 } 795 796 static void CheckReadWrite<T>(int size, Func<DataStreamReader, T> read, Write write, T value) 797 { 798 var writer = new DataStreamWriter(size, Allocator.Temp); 799 write(ref writer); 800 writer.Flush(); 801 Assert.That(read(new DataStreamReader(writer.AsNativeArray())), Is.EqualTo(value)); 802 } 803 804 static void CheckReadWriteLooped<T>(int size, T baseVal, T expected, WriteWithValue<T> write, Read<T> read, Sum<T> sum) 805 { 806 var writer = new DataStreamWriter(300 * size, Allocator.Temp); 807 const int count = 277; 808 for (uint i = 0; i < count; ++i) 809 { 810 write(ref writer, sum(baseVal, i)); 811 } 812 813 write(ref writer, expected); 814 writer.Flush(); 815 var reader = new DataStreamReader(writer.AsNativeArray()); 816 for (uint i = 0; i < count; ++i) 817 { 818 var val = read(ref reader); 819 Assert.AreEqual(sum(baseVal, i), val); 820 } 821 822 Assert.AreEqual(expected, read(ref reader)); 823 } 824 825 [Test] 826 public void MiNiCheck() 827 { 828 var model = StreamCompressionModel.Default; 829 Assert.That(model.ToString(), Is.EqualTo("Unity.Collections.StreamCompressionModel")); 830 } 831 } 832}