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 }