1 /* 2 * Copyright 2024 Google LLC. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkRustPngFFI_DEFINED 9 #define SkRustPngFFI_DEFINED 10 11 #include <stddef.h> 12 #include <stdint.h> 13 14 // TODO(https://crbug.com/356698922): Use a real `#include` if possible. 15 namespace rust { 16 inline namespace cxxbridge1 { 17 template <typename T> class Slice; 18 } // namespace cxxbridge1 19 } // namespace rust 20 21 namespace rust_png { 22 23 // Implementing the abstract C++ class below gives a rough equivalent of 24 // `dyn std::io::Read` from Rust. 25 class ReadTrait { 26 public: 27 // The `virtual` method below is a rough equivalent of the 28 // `std::io::Read::read` method in Rust. See 29 // https://doc.rust-lang.org/nightly/std/io/trait.Read.html#tymethod.read 30 // for guidance on the desired implementation and behavior of this method. 31 // 32 // Note that (unlike in Rust) this method is infallible. This aspect of the 33 // design is used tentatively and based on the following considerations: 34 // * `SkStream::read` is also infallible 35 // * `SkStream::read` communicates no-more-input by reporting that 0 bytes 36 // have been read (just like Rust's `Read` trait), and this condition 37 // corresponds to the only IO error covered by `SkCodec::Result`: 38 // `kIncompleteInput`. 39 // * FFI based on the `cxx` crate doesn't currently support Rust's 40 // `std::result::Result`, `std::option::Option`, nor C++'s 41 // `std::optional` or `std::expected`. 42 virtual size_t read(rust::Slice<uint8_t> buffer) = 0; 43 44 // `drop` is not part of the `std::io::Read` trait, but we expose the 45 // destructor through public API to make it possible to pass 46 // `std::unique_ptr<ReadTrait>` over the FFI boundary. 47 virtual ~ReadTrait() = default; 48 49 // This type is non-copyable and non-movable. 50 ReadTrait(const ReadTrait&) = delete; 51 ReadTrait(ReadTrait&&) = delete; 52 ReadTrait& operator=(const ReadTrait&) = delete; 53 ReadTrait& operator=(ReadTrait&&) = delete; 54 55 protected: 56 ReadTrait() = default; 57 }; 58 59 // Implementing the abstract C++ class below gives a rough equivalent of 60 // `dyn std::io::Write` from Rust. 61 class WriteTrait { 62 public: 63 // The `virtual` method below is a rough equivalent of the 64 // `std::io::Write::write` method in Rust. See 65 // https://doc.rust-lang.org/nightly/std/io/trait.Write.html#tymethod.write 66 // for guidance on the desired implementation and behavior of this method. 67 // 68 // Implementation should return `true` if the whole buffer has been 69 // successfully written (and return `false` to indicate an error). 70 // This mimics how `SkStreamW::write` communicates errors. 71 virtual bool write(rust::Slice<const uint8_t> buffer) = 0; 72 73 // The `virtual` method below is a rough equivalent of the 74 // `std::io::Write::flush` method in Rust. See 75 // https://doc.rust-lang.org/nightly/std/io/trait.Write.html#tymethod.flush 76 // for guidance on the desired implementation and behavior of this method. 77 // 78 // Note that (unlike in Rust) this method is infallible. This aspect of the 79 // design mimics `SkStreamW::flush`. 80 virtual void flush() = 0; 81 82 // `drop` is not part of the `std::io::Read` trait, but we expose the 83 // destructor through public API to make it possible to pass 84 // `std::unique_ptr<WriteTrait>` over the FFI boundary. 85 virtual ~WriteTrait() = default; 86 87 // This type is non-copyable and non-movable. 88 WriteTrait(const WriteTrait&) = delete; 89 WriteTrait(WriteTrait&&) = delete; 90 WriteTrait& operator=(const WriteTrait&) = delete; 91 WriteTrait& operator=(WriteTrait&&) = delete; 92 93 protected: 94 WriteTrait() = default; 95 }; 96 97 } // namespace rust_png 98 99 #endif // SkRustPngFFI_DEFINED 100