1 module skia.SKStream; 2 3 import skia.Definitions; 4 import skia.SkiaApi; 5 import skia.Exceptions; 6 import skia.SKObject; 7 import skia.SKData; 8 import skia.SKStream; 9 10 /** 11 * 12 */ 13 class SKStream : SKObject 14 { 15 this(void* handle, bool owns) 16 { 17 super(handle, owns); 18 } 19 20 bool IsAtEnd() 21 { 22 return SkiaApi.sk_stream_is_at_end(cast(sk_stream_t*)Handle); 23 } 24 25 byte ReadSByte() 26 { 27 byte buffer; 28 if (ReadSByte(buffer)) 29 return buffer; 30 return byte.init; 31 } 32 33 short ReadInt16() 34 { 35 short buffer; 36 if (ReadInt16(buffer)) 37 return buffer; 38 return short.init; 39 } 40 41 int ReadInt32() 42 { 43 int buffer; 44 if (ReadInt32(buffer)) 45 return buffer; 46 return int.init; 47 } 48 49 ubyte ReadByte() 50 { 51 ubyte buffer; 52 if (ReadByte(buffer)) 53 return buffer; 54 return ubyte.init; 55 } 56 57 ushort ReadUInt16() 58 { 59 ushort buffer; 60 if (ReadUInt16(buffer)) 61 return buffer; 62 return ushort.init; 63 } 64 65 uint ReadUInt32() 66 { 67 uint buffer; 68 if (ReadUInt32(buffer)) 69 return buffer; 70 return uint.init; 71 } 72 73 bool ReadBool() 74 { 75 bool buffer; 76 if (ReadBool(buffer)) 77 return buffer; 78 return bool.init; 79 } 80 81 bool ReadSByte(ref byte buffer) 82 { 83 byte* b = &buffer; 84 return SkiaApi.sk_stream_read_s8(cast(sk_stream_t*)Handle, b); 85 } 86 87 bool ReadInt16(ref short buffer) 88 { 89 short* b = &buffer; 90 return SkiaApi.sk_stream_read_s16(cast(sk_stream_t*)Handle, b); 91 } 92 93 bool ReadInt32(ref int buffer) 94 { 95 int* b = &buffer; 96 return SkiaApi.sk_stream_read_s32(cast(sk_stream_t*)Handle, b); 97 } 98 99 bool ReadByte(ref ubyte buffer) 100 { 101 ubyte* b = &buffer; 102 return SkiaApi.sk_stream_read_u8(cast(sk_stream_t*)Handle, b); 103 } 104 105 bool ReadUInt16(ref ushort buffer) 106 { 107 ushort* b = &buffer; 108 return SkiaApi.sk_stream_read_u16(cast(sk_stream_t*)Handle, b); 109 } 110 111 bool ReadUInt32(ref uint buffer) 112 { 113 uint* b = &buffer; 114 return SkiaApi.sk_stream_read_u32(cast(sk_stream_t*)Handle, b); 115 } 116 117 bool ReadBool(ref bool buffer) 118 { 119 bool b; 120 auto result = SkiaApi.sk_stream_read_bool(cast(sk_stream_t*)Handle, &b); 121 buffer = b > 0; 122 return result; 123 } 124 125 int Read(byte[] buffer, int size) 126 { 127 byte* b = buffer.ptr; 128 return Read(cast(void*) b, size); 129 } 130 131 int Read(void* buffer, int size) 132 { 133 return cast(int) SkiaApi.sk_stream_read(cast(sk_stream_t*)Handle, cast(void*) buffer, cast(size_t) size); 134 } 135 136 int Peek(void* buffer, int size) 137 { 138 return cast(int) SkiaApi.sk_stream_peek(cast(sk_stream_t*)Handle, cast(void*) buffer, cast(size_t) size); 139 } 140 141 int Skip(int size) 142 { 143 return cast(int) SkiaApi.sk_stream_skip(cast(sk_stream_t*)Handle, cast(size_t) size); 144 } 145 146 bool Rewind() 147 { 148 return SkiaApi.sk_stream_rewind(cast(sk_stream_t*)Handle); 149 } 150 151 bool Seek(int position) 152 { 153 return SkiaApi.sk_stream_seek(cast(sk_stream_t*)Handle, cast(size_t) position); 154 } 155 156 bool Move(long offset) 157 { 158 return Move(cast(int) offset); 159 } 160 161 bool Move(int offset) 162 { 163 return SkiaApi.sk_stream_move(cast(sk_stream_t*)Handle, offset); 164 } 165 166 void* GetMemoryBase() 167 { 168 return cast(void*) SkiaApi.sk_stream_get_memory_base(cast(sk_stream_t*)Handle); 169 } 170 171 SKStream Fork() 172 { 173 return GetObject(SkiaApi.sk_stream_fork(cast(sk_stream_t*)Handle)); 174 } 175 176 SKStream Duplicate() 177 { 178 return GetObject(SkiaApi.sk_stream_duplicate(cast(sk_stream_t*)Handle)); 179 } 180 181 bool HasPosition() 182 { 183 184 return SkiaApi.sk_stream_has_position(cast(sk_stream_t*)Handle); 185 186 } 187 188 int Position() 189 { 190 return cast(int) SkiaApi.sk_stream_get_position(cast(sk_stream_t*)Handle); 191 } 192 193 void Position(int value) 194 { 195 Seek(value); 196 } 197 198 bool HasLength() 199 { 200 return SkiaApi.sk_stream_has_length(cast(sk_stream_t*)Handle); 201 } 202 203 int Length() 204 { 205 return cast(int) SkiaApi.sk_stream_get_length(cast(sk_stream_t*)Handle); 206 } 207 208 static SKStream GetObject(void* handle) 209 { 210 return GetOrAddObject!SKStream(handle, (h, o) { 211 return new SKStreamImplementation(h, o); 212 }); 213 } 214 215 } 216 217 class SKStreamImplementation : SKStream 218 { 219 this(void* handle, bool owns) 220 { 221 super(handle, owns); 222 } 223 224 protected override void Dispose(bool disposing) 225 { 226 return super.Dispose(disposing); 227 } 228 229 protected override void DisposeNative() 230 { 231 return SkiaApi.sk_stream_destroy(cast(sk_stream_t*)Handle); 232 } 233 234 } 235 236 class SKStreamRewindable : SKStream 237 { 238 this(void* handle, bool owns) 239 { 240 super(handle, owns); 241 } 242 } 243 244 class SKStreamSeekable : SKStreamRewindable 245 { 246 this(void* handle, bool owns) 247 { 248 super(handle, owns); 249 } 250 } 251 252 class SKStreamAsset : SKStreamSeekable 253 { 254 this(void* handle, bool owns) 255 { 256 super(handle, owns); 257 } 258 259 // static new SKStreamAsset GetObject(void* handle) 260 // { 261 // // dfmt off 262 // return GetOrAddObject!SKStreamAsset(handle, (h, o) { return new SKStreamAssetImplementation (h, o); }); 263 // // dfmt on 264 // } 265 266 } 267 268 class SKStreamAssetImplementation : SKStreamAsset 269 { 270 this(void* handle, bool owns) 271 { 272 super(handle, owns); 273 } 274 275 protected override void Dispose(bool disposing) 276 { 277 return super.Dispose(disposing); 278 } 279 280 protected override void DisposeNative() 281 { 282 return SkiaApi.sk_stream_asset_destroy(cast(sk_stream_asset_t*)Handle); 283 } 284 } 285 286 class SKStreamMemory : SKStreamAsset 287 { 288 this(void* handle, bool owns) 289 { 290 super(handle, owns); 291 } 292 } 293 294 class SKFileStream : SKStreamAsset 295 { 296 this(void* handle, bool owns) 297 { 298 super(handle, owns); 299 } 300 301 this(string path) 302 { 303 super(CreateNew(path), true); 304 if (Handle is null) 305 { 306 throw new InvalidOperationException("Unable to create a new SKFileStream instance."); 307 } 308 } 309 310 private static void* CreateNew(string path) 311 { 312 // auto bytes = StringUtilities.GetEncodedText (path, SKTextEncoding.Utf8, true); 313 // byte* p = cast(byte*) path.ptr; 314 // return SkiaApi.sk_filestream_new(p); 315 return SkiaApi.sk_filestream_new(path); 316 } 317 318 protected override void Dispose(bool disposing) 319 { 320 return super.Dispose(disposing); 321 } 322 323 override void Dispose() 324 { 325 return super.Dispose(); 326 } 327 328 protected override void DisposeNative() 329 { 330 return SkiaApi.sk_filestream_destroy(cast(sk_stream_filestream_t*)Handle); 331 } 332 333 bool IsValid() 334 { 335 return SkiaApi.sk_filestream_is_valid(cast(sk_stream_filestream_t*)Handle); 336 } 337 338 static bool IsPathSupported(string path) 339 { 340 return true; 341 } 342 343 static SKStreamAsset OpenStream(string path) 344 { 345 SKFileStream stream = new SKFileStream(path); 346 if (!stream.IsValid) 347 { 348 stream.Dispose(); 349 stream = null; 350 } 351 return stream; 352 } 353 } 354 355 class SKMemoryStream : SKStreamMemory 356 { 357 this(void* handle, bool owns) 358 { 359 super(handle, owns); 360 } 361 362 this() 363 { 364 this(SkiaApi.sk_memorystream_new(), true); 365 if (Handle is null) 366 { 367 throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); 368 } 369 } 370 371 this(ulong length) 372 { 373 this(SkiaApi.sk_memorystream_new_with_length(cast(void*) length), true); 374 if (Handle is null) 375 { 376 throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); 377 } 378 } 379 380 this(void* data, void* length, bool copyData = false) 381 { 382 this(SkiaApi.sk_memorystream_new_with_data(cast(void*) data, cast(int)length, copyData), true); 383 if (Handle is null) 384 { 385 throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); 386 } 387 } 388 389 this(SKData data) 390 { 391 this(SkiaApi.sk_memorystream_new_with_skdata(cast(sk_data_t*)data.Handle), true); 392 if (Handle is null) 393 { 394 throw new InvalidOperationException("Unable to create a new SKMemoryStream instance."); 395 } 396 } 397 398 this(byte[] data) 399 { 400 this(); 401 SetMemory(data); 402 } 403 404 protected override void Dispose(bool disposing) 405 { 406 return super.Dispose(disposing); 407 } 408 409 protected override void DisposeNative() 410 { 411 return SkiaApi.sk_memorystream_destroy(cast(sk_stream_memorystream_t*)Handle); 412 } 413 414 void SetMemory(void* data, void* length, bool copyData = false) 415 { 416 SkiaApi.sk_memorystream_set_memory(cast(sk_stream_memorystream_t*)Handle, cast(void*) data, cast(int)length, copyData); 417 } 418 419 void SetMemory(byte[] data, void* length, bool copyData = false) 420 { 421 byte* d = data.ptr; 422 SkiaApi.sk_memorystream_set_memory(cast(sk_stream_memorystream_t*)Handle, d, cast(int)length, copyData); 423 } 424 425 void SetMemory(byte[] data) 426 { 427 SetMemory(data, cast(void*) data.length, true); 428 } 429 } 430 431 class SKWStream : SKObject 432 { 433 this(void* handle, bool owns) 434 { 435 super(handle, owns); 436 } 437 438 int BytesWritten() 439 { 440 441 return cast(int) SkiaApi.sk_wstream_bytes_written(cast(sk_wstream_t*)Handle); 442 443 } 444 445 bool Write(byte[] buffer, int size) 446 { 447 byte* b = buffer.ptr; 448 return SkiaApi.sk_wstream_write(cast(sk_wstream_t*)Handle, cast(void*) b, cast(size_t) size); 449 } 450 451 bool NewLine() 452 { 453 return SkiaApi.sk_wstream_newline(cast(sk_wstream_t*)Handle); 454 } 455 456 void Flush() 457 { 458 SkiaApi.sk_wstream_flush(cast(sk_wstream_t*)Handle); 459 } 460 461 bool Write8(ubyte value) 462 { 463 return SkiaApi.sk_wstream_write_8(cast(sk_wstream_t*)Handle, value); 464 } 465 466 bool Write16(ushort value) 467 { 468 return SkiaApi.sk_wstream_write_16(cast(sk_wstream_t*)Handle, value); 469 } 470 471 bool Write32(uint value) 472 { 473 return SkiaApi.sk_wstream_write_32(cast(sk_wstream_t*)Handle, value); 474 } 475 476 bool WriteText(string value) 477 { 478 return SkiaApi.sk_wstream_write_text(cast(sk_wstream_t*)Handle, value); 479 } 480 481 bool WriteDecimalAsTest(int value) 482 { 483 return SkiaApi.sk_wstream_write_dec_as_text(cast(sk_wstream_t*)Handle, value); 484 } 485 486 bool WriteBigDecimalAsText(long value, int digits) 487 { 488 return SkiaApi.sk_wstream_write_bigdec_as_text(cast(sk_wstream_t*)Handle, value, digits); 489 } 490 491 bool WriteHexAsText(uint value, int digits) 492 { 493 return SkiaApi.sk_wstream_write_hex_as_text(cast(sk_wstream_t*)Handle, value, digits); 494 } 495 496 bool WriteScalarAsText(float value) 497 { 498 return SkiaApi.sk_wstream_write_scalar_as_text(cast(sk_wstream_t*)Handle, value); 499 } 500 501 bool WriteBool(bool value) 502 { 503 return SkiaApi.sk_wstream_write_bool(cast(sk_wstream_t*)Handle, value); 504 } 505 506 bool WriteScalar(float value) 507 { 508 return SkiaApi.sk_wstream_write_scalar(cast(sk_wstream_t*)Handle, value); 509 } 510 511 bool WritePackedUInt32(uint value) 512 { 513 return SkiaApi.sk_wstream_write_packed_uint(cast(sk_wstream_t*)Handle, cast(size_t) value); 514 } 515 516 bool WriteStream(SKStream input, int length) 517 { 518 if (input is null) 519 { 520 throw new ArgumentNullException("input"); 521 } 522 523 return SkiaApi.sk_wstream_write_stream(cast(sk_wstream_t*)Handle, cast(sk_stream_t*)input.Handle, cast(size_t) length); 524 } 525 526 static int GetSizeOfPackedUInt32(uint value) 527 { 528 return SkiaApi.sk_wstream_get_size_of_packed_uint(cast(size_t) value); 529 } 530 } 531 532 class SKFileWStream : SKWStream 533 { 534 this(void* handle, bool owns) 535 { 536 super(handle, owns); 537 } 538 539 this(string path) 540 { 541 super(CreateNew(path), true); 542 if (Handle is null) 543 { 544 throw new InvalidOperationException("Unable to create a new SKFileWStream instance."); 545 } 546 } 547 548 private static void* CreateNew(string path) 549 { 550 // auto bytes = StringUtilities.GetEncodedText (path, SKTextEncoding.Utf8, true); 551 // byte* p = cast(byte*) bytes.ptr; 552 // return SkiaApi.sk_filewstream_new(p); 553 return SkiaApi.sk_filewstream_new(path); 554 } 555 556 protected override void Dispose(bool disposing) 557 { 558 return super.Dispose(disposing); 559 } 560 561 override void Dispose() 562 { 563 return super.Dispose(); 564 } 565 protected override void DisposeNative() 566 { 567 SkiaApi.sk_filewstream_destroy(cast(sk_wstream_filestream_t*)Handle); 568 } 569 570 bool IsValid() 571 { 572 return SkiaApi.sk_filewstream_is_valid(cast(sk_wstream_filestream_t*)Handle); 573 } 574 575 static bool IsPathSupported(string path) 576 { 577 return true; 578 } 579 580 static SKWStream OpenStream(string path) 581 { 582 SKFileWStream stream = new SKFileWStream(path); 583 if (!stream.IsValid) 584 { 585 stream.Dispose(); 586 stream = null; 587 } 588 return stream; 589 } 590 } 591 592 class SKDynamicMemoryWStream : SKWStream 593 { 594 this(void* handle, bool owns) 595 { 596 super(handle, owns); 597 } 598 599 this() 600 { 601 super(SkiaApi.sk_dynamicmemorywstream_new(), true); 602 if (Handle is null) 603 { 604 throw new InvalidOperationException( 605 "Unable to create a new SKDynamicMemoryWStream instance."); 606 } 607 } 608 609 SKData CopyToData() 610 { 611 auto data = SKData.Create(BytesWritten); 612 CopyTo(data.Data); 613 return data; 614 } 615 616 // SKStreamAsset DetachAsStream() 617 // { 618 // return SKStreamAssetImplementation.GetObject( 619 // SkiaApi.sk_dynamicmemorywstream_detach_as_stream(cast(sk_wstream_dynamicmemorystream_t*)Handle)); 620 // } 621 622 SKData DetachAsData() 623 { 624 return SKData.GetObject(SkiaApi.sk_dynamicmemorywstream_detach_as_data(cast(sk_wstream_dynamicmemorystream_t*)Handle)); 625 } 626 627 void CopyTo(void* data) 628 { 629 SkiaApi.sk_dynamicmemorywstream_copy_to(cast(sk_wstream_dynamicmemorystream_t*)Handle, cast(void*) data); 630 } 631 632 void CopyTo(byte[] data) 633 { 634 auto size = BytesWritten; 635 if (data.length < size) 636 throw new Exception( 637 "Not enough space to copy. Expected at least {size}, but received {data.Length}."); 638 639 void* d = data.ptr; 640 SkiaApi.sk_dynamicmemorywstream_copy_to(cast(sk_wstream_dynamicmemorystream_t*)Handle, d); 641 } 642 643 bool CopyTo(SKWStream dst) 644 { 645 if (dst is null) 646 throw new ArgumentNullException(dst.stringof); 647 return SkiaApi.sk_dynamicmemorywstream_write_to_stream(cast(sk_wstream_dynamicmemorystream_t*)Handle, cast(sk_wstream_t*)dst.Handle); 648 } 649 650 // bool CopyTo(Stream dst) 651 // { 652 // if (dst is null) 653 // throw new ArgumentNullException(dst.stringof); 654 655 // auto wrapped = new SKManagedWStream(dst); 656 // scope (exit) 657 // { 658 // wrapped.Dispose(); 659 // } 660 661 // return CopyTo(wrapped); 662 // } 663 664 protected override void Dispose(bool disposing) 665 { 666 return super.Dispose(disposing); 667 } 668 669 override void Dispose() 670 { 671 return super.Dispose(); 672 } 673 674 protected override void DisposeNative() 675 { 676 SkiaApi.sk_dynamicmemorywstream_destroy(cast(sk_wstream_dynamicmemorystream_t*)Handle); 677 } 678 }