diff --git a/content/blog/Rust-Usage-of-Cow/index.md b/content/blog/Rust-Usage-of-Cow/index.md new file mode 100644 index 0000000..6dde9b8 --- /dev/null +++ b/content/blog/Rust-Usage-of-Cow/index.md @@ -0,0 +1,96 @@ +--- +title: "Rust: Usage of Cow(Clone on Write)" +date: 2025-01-17 14:03:43 +tags: ['Rust'] +--- + +## Rust: Usage of Cow(Clone on Write) + +Today, After reading following blog +post(https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/), +I finally understood the need for Cow in Rust. Below is my code sample with +relevant comments. + +```rust +use std::borrow::Cow; + +#[derive(Clone, Debug)] +struct Book { + name: String, + price: u32, +} + +fn update_book_price<'a>(book: &'a Book, price: u32) -> Cow<'a, Book> { + // If the price matches, there's no need to create a new book. + if book.price == price { + return Cow::Borrowed(book); + } + + // If the price does not match, create a new book (updating the title to + // make it easy to distinguish the objects). + Cow::Owned(Book { + name: format!("{}-updated", book.name.clone()), + price, + }) +} + +fn main() { + let book = Book { + name: "Rust programming".to_string(), + price: 100, + }; + + // CASE 1: Since there is no change in price, we get a `Cow` wrapped + // borrowed version of the existing book. + let updated_book: Cow<'_, Book> = update_book_price(&book, 100); + // The returned `Cow` object is always immutable. The following line will + // not work even though we can access the object fields via the `Deref` + // trait: + // updated_book.price = 200; + println!("{:?}", updated_book); // Book { name: "Rust programming", price: 100 } + + // If we ever need to own the above object (e.g., for modifying it), we can + // call `into_owned()` on `Cow` to get a cloned version of the book. + // This cloned object will be mutable. + let mut updated_book: Book = updated_book.into_owned(); + updated_book.price = 200; + println!("{:?}", updated_book); // Book { name: "Rust programming", price: 200 } + + // ======================================== + + // CASE 2: Since the price has changed, we get a `Cow` wrapped owned version + // of the book. This owned version is the object we created in the + // `update_book_price()` method. + let updated_book: Cow<'_, Book> = update_book_price(&book, 300); + // Again, the returned object is immutable, so the following line will not + // work: + // updated_book.price = 400; + println!("{:?}", updated_book); // Book { name: "Rust programming-updated", price: 300 } + + // If we ever need to own this object (e.g., for modifying it), we can call + // `into_owned()` on `Cow` to get the owned object. Importantly, in this + // case, `Cow` simply returns the already owned object instead of cloning + // it. The returned object will be mutable. + let mut updated_book: Book = updated_book.into_owned(); + updated_book.price = 400; + println!("{:?}", updated_book); // Book { name: "Rust programming-updated", price: 400 } + + // Takeaway 1: `Cow` allows us to defer cloning a borrowed object until it + // is required for modification (ownership). When ownership is needed, `Cow` + // provides the following behavior via `into_owned()`: + // 1. `Cow` either calls `clone()` on the borrowed object. + // 2. Or, `Cow` directly returns the underlying owned object. + + // Takeaway 2: With the help of `Cow` (Clone-On-Write), we can design + // methods optimized to return the borrowed object wrapped inside `Cow`. + // This approach helps delay the cloning process. Specifically, the + // `update_book_price()` method returns either a borrowed `Cow` or an owned + // `Cow`, catering to both cases. However, this flexibility is not always + // necessary. Since every type `T` that `Cow` wraps requires + // `#[derive(Clone)]`, `Cow` can decide when to clone the borrowed object + // and when to return the underlying owned object directly, depending on the + // need when `into_owned()` is called. + + // Reference: https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/ +} +``` \ No newline at end of file diff --git a/docs/404.html b/docs/404.html index ba637ee..c2926ac 100644 --- a/docs/404.html +++ b/docs/404.html @@ -1,6 +1,6 @@ - + 404 Page not found | Vineel Kovvuri diff --git a/docs/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/index.html b/docs/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/index.html index 52fe759..e6c14ed 100644 --- a/docs/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/index.html +++ b/docs/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/index.html @@ -1,6 +1,6 @@ - + A Newbie's Introduction To Compilation Process And Reverse Engineering | Vineel Kovvuri diff --git a/docs/blog/c-case-studies/f/index.html b/docs/blog/c-case-studies/f/index.html index e41c224..3400ed8 100644 --- a/docs/blog/c-case-studies/f/index.html +++ b/docs/blog/c-case-studies/f/index.html @@ -1,6 +1,6 @@ - + Libspng - C Language Case Study | Vineel Kovvuri diff --git a/docs/blog/compiler-internals/index.html b/docs/blog/compiler-internals/index.html index e629121..33eabe2 100644 --- a/docs/blog/compiler-internals/index.html +++ b/docs/blog/compiler-internals/index.html @@ -1,6 +1,6 @@ - + Compiler Internals | Vineel Kovvuri diff --git a/docs/blog/how-do-breakpoints-work-in-debuggers/index.html b/docs/blog/how-do-breakpoints-work-in-debuggers/index.html index aaf52e0..e5edf84 100644 --- a/docs/blog/how-do-breakpoints-work-in-debuggers/index.html +++ b/docs/blog/how-do-breakpoints-work-in-debuggers/index.html @@ -1,6 +1,6 @@ - + How Do Breakpoints Work In Debuggers? | Vineel Kovvuri diff --git a/docs/blog/index.html b/docs/blog/index.html index fa6986e..e0bd958 100644 --- a/docs/blog/index.html +++ b/docs/blog/index.html @@ -1,6 +1,6 @@ - + Blogs | Vineel Kovvuri @@ -35,6 +35,11 @@

Blog

+
  • + 2025/01/17 + Rust: Usage of Cow(Clone on Write) - blog +
  • +
  • 2025/01/14 Rust: From and Into trait - Part 2 - blog diff --git a/docs/blog/index.xml b/docs/blog/index.xml index 0b3c756..64567bc 100644 --- a/docs/blog/index.xml +++ b/docs/blog/index.xml @@ -2,115 +2,122 @@ Blogs on Vineel Kovvuri - /blog/ + //localhost:9999/blog/ Recent content in Blogs on Vineel Kovvuri Hugo en-us - Tue, 14 Jan 2025 23:33:54 +0000 - + Fri, 17 Jan 2025 14:03:43 +0000 + + + Rust: Usage of Cow(Clone on Write) + //localhost:9999/blog/rust-usage-of-cow/ + Fri, 17 Jan 2025 14:03:43 +0000 + //localhost:9999/blog/rust-usage-of-cow/ + <h2 id="rust-usage-of-cowclone-on-write">Rust: Usage of Cow(Clone on Write)</h2> <p>Today, After reading following blog post(<a href="https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/)">https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/)</a>, I finally understood the need for Cow in Rust. Below is my code sample with relevant comments.</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">use</span><span style="color:#bbb"> </span>std::borrow::Cow;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Clone, Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#038">String</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price: <span style="color:#888;font-weight:bold">u32</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">update_book_price</span>&lt;<span style="color:#369">&#39;a</span>&gt;(book: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">Book</span>,<span style="color:#bbb"> </span>price: <span style="color:#888;font-weight:bold">u32</span>)<span style="color:#bbb"> </span>-&gt; <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#369">&#39;a</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If the price matches, there&#39;s no need to create a new book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">if</span><span style="color:#bbb"> </span>book.price<span style="color:#bbb"> </span>==<span style="color:#bbb"> </span>price<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">return</span><span style="color:#bbb"> </span>Cow::Borrowed(book);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If the price does not match, create a new book (updating the title to </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// make it easy to distinguish the objects). </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>Cow::Owned(Book<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#b06;font-weight:bold">format</span>!(<span style="color:#d20;background-color:#fff0f0">&#34;{}-updated&#34;</span>,<span style="color:#bbb"> </span>book.name.clone()),<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>})<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>book<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>Book<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#d20;background-color:#fff0f0">&#34;Rust programming&#34;</span>.to_string(),<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price: <span style="color:#00d;font-weight:bold">100</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// CASE 1: Since there is no change in price, we get a `Cow` wrapped </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// borrowed version of the existing book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#038">&#39;_</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>update_book_price(&amp;book,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">100</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// The returned `Cow` object is always immutable. The following line will </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// not work even though we can access the object fields via the `Deref` </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// trait: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// updated_book.price = 200; </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming&#34;, price: 100 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If we ever need to own the above object (e.g., for modifying it), we can </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// call `into_owned()` on `Cow` to get a cloned version of the book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// This cloned object will be mutable. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>updated_book.into_owned();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>updated_book.price<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">200</span>;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming&#34;, price: 200 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// ======================================== </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// CASE 2: Since the price has changed, we get a `Cow` wrapped owned version </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// of the book. This owned version is the object we created in the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `update_book_price()` method. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#038">&#39;_</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>update_book_price(&amp;book,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">300</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Again, the returned object is immutable, so the following line will not </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// work: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// updated_book.price = 400; </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming-updated&#34;, price: 300 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If we ever need to own this object (e.g., for modifying it), we can call </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `into_owned()` on `Cow` to get the owned object. Importantly, in this </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// case, `Cow` simply returns the already owned object instead of cloning </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// it. The returned object will be mutable. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>updated_book.into_owned();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>updated_book.price<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">400</span>;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming-updated&#34;, price: 400 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 1: `Cow` allows us to defer cloning a borrowed object until it </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// is required for modification (ownership). When ownership is needed, `Cow` </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// provides the following behavior via `into_owned()`: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// 1. `Cow` either calls `clone()` on the borrowed object. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// 2. Or, `Cow` directly returns the underlying owned object. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 2: With the help of `Cow` (Clone-On-Write), we can design </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// methods optimized to return the borrowed object wrapped inside `Cow`. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// This approach helps delay the cloning process. Specifically, the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `update_book_price()` method returns either a borrowed `Cow` or an owned </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `Cow`, catering to both cases. However, this flexibility is not always </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// necessary. Since every type `T` that `Cow` wraps requires </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `#[derive(Clone)]`, `Cow` can decide when to clone the borrowed object </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// and when to return the underlying owned object directly, depending on the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// need when `into_owned()` is called. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Reference: https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/ </span></span></span><span style="display:flex;"><span><span style="color:#888"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div> + Rust: From and Into trait - Part 2 - /blog/rust-from-vs-into-traits-part-2/ + //localhost:9999/blog/rust-from-vs-into-traits-part-2/ Tue, 14 Jan 2025 23:33:54 +0000 - /blog/rust-from-vs-into-traits-part-2/ + //localhost:9999/blog/rust-from-vs-into-traits-part-2/ <h2 id="rust-from-and-into-trait-usage">Rust: From and Into trait usage</h2> <p>Knowing how Rust&rsquo;s <code>From</code> and <code>Into</code> traits work is one part of the story, but being able to use them efficiently is another. In this code sample, we will explore how to define functions or methods that accept parameters which can be converted from and into the expected types.</p> <p>In this code, we have two functions, <code>increment()</code> and <code>increment2()</code>, and we will see how they work with the <code>From</code> trait implemented for the <code>Number</code> type.</p> Rust: Aligned vs Unaligned Memory Access - /blog/rust-aligned-vs-unaligned-memory-access/ + //localhost:9999/blog/rust-aligned-vs-unaligned-memory-access/ Tue, 14 Jan 2025 19:05:52 +0000 - /blog/rust-aligned-vs-unaligned-memory-access/ + //localhost:9999/blog/rust-aligned-vs-unaligned-memory-access/ <h2 id="rust-rust-aligned-vs-unaligned-memory-access">Rust: Rust Aligned vs Unaligned Memory Access</h2> <p>Unlike C, Rust enforces some rules when trying to access memory. Mainly it requires consideration to alignment of the data that we are trying to read. Below code will illustrate the details.</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data: [<span style="color:#888;font-weight:bold">u8</span>;<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">10</span>]<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>[<span style="color:#00d;font-weight:bold">0x11</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x22</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x33</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x44</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x55</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x66</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x77</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x88</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x99</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0xAA</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Alignment Tidbit: Alignment depends on the data type we are using. u8 has </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// an alignment of 1, so u8 values can be accessed at any address. In </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// contrast, u16 has an alignment of 2, so they can only be accessed at </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// addresses aligned by 2. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Case 1: unaligned u16 access from raw pointer. This will panic </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>)<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>;<span style="color:#bbb"> </span><span style="color:#888">// interpreting the underlying address as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>x<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>*ptr;<span style="color:#bbb"> </span><span style="color:#888">// This dereference will panic: misaligned pointer dereference: address must be a multiple of 0x2 but is 0x7ffdec94efcd </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;x: </span><span style="color:#33b;background-color:#fff0f0">{x}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Slices: Accessing elements through a slice will have the same alignment </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// as its underlying data. So this prevent unaligned access. Also we cannot </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpret a u8 array as a u16 slice unlike raw pointer access </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// Case 2: aligned u8 access from slice </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>slice<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;data[<span style="color:#00d;font-weight:bold">1</span>..<span style="color:#00d;font-weight:bold">2</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>value<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>slice[<span style="color:#00d;font-weight:bold">0</span>];<span style="color:#bbb"> </span><span style="color:#888">// This works </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;slice: </span><span style="color:#33b;background-color:#fff0f0">{value}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Case 3: unaligned u16 access from a slice using unsafe. This will panic </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr: *<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u8</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>unaligned_data_ptr: *<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u8</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// slice::from_raw_parts will panic as unaligned *const u8 is being </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpreted as *const u16 . </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>unaligned_slice<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>core::slice::from_raw_parts(data_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">usize</span>)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>value<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>slice[<span style="color:#00d;font-weight:bold">0</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;unaligned_slice: </span><span style="color:#33b;background-color:#fff0f0">{value}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 1: The takeaway here is that when interpreting *const u8 as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// or u32, we cannot simply cast *const u8 as *const u16 and dereference </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// that location and except u16. Instead, we can only access the *const u8 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// as two u8 values and then use bit math to combine those bytes to form a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// u16. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 2: When creating an array of u8(with odd number of elements), </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// the address at which the array starts in memory need not be a power of 2. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// Because u8&#39;s have an alignment of 1. If that is the case, and trying to </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpret data + 1 address location as u16 will not trigger a panic. Be </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// aware of that! </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data: [<span style="color:#888;font-weight:bold">u8</span>;<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">5</span>]<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>[<span style="color:#00d;font-weight:bold">0x11</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x22</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x33</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x44</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x55</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>)<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>;<span style="color:#bbb"> </span><span style="color:#888">// interpreting the underlying address as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>x<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>*ptr;<span style="color:#bbb"> </span><span style="color:#888">// This dereference will NOT trigger a panic! </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{x}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div> Rust: Sharing a Single Object Across Multiple Owners - /blog/rust-sharing-objects/ + //localhost:9999/blog/rust-sharing-objects/ Tue, 07 Jan 2025 00:17:07 -0700 - /blog/rust-sharing-objects/ + //localhost:9999/blog/rust-sharing-objects/ <h2 id="rust-sharing-a-single-object-across-multiple-owners">Rust: Sharing a Single Object Across Multiple Owners</h2> <p>Today, I found an interesting way to share a single object(C) among multiple owners(A and B)</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">use</span><span style="color:#bbb"> </span>std::ffi::c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">A</span>&lt;<span style="color:#369">&#39;a</span>&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>C,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">B</span>&lt;<span style="color:#369">&#39;a</span>&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>C,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#888">// Common object C shared between object A and object B </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">C</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>val: <span style="color:#888;font-weight:bold">u32</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// - Using stack objects </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;Object c shared b/w multiple stack based objects&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>C<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>val: <span style="color:#00d;font-weight:bold">100</span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>A<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>*(a_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>*(b_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>a_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>b_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">4000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from b </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// - Using heap objects </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;Object c shared b/w multiple heap based objects&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>C<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>val: <span style="color:#00d;font-weight:bold">100</span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>A<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#038">Box</span>::into_raw(<span style="color:#038">Box</span>::new(a))<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#038">Box</span>::into_raw(<span style="color:#038">Box</span>::new(b))<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>a_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span><span style="color:#038">Box</span>::&lt;A&gt;::from_raw(a_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>b_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span><span style="color:#038">Box</span>::&lt;B&gt;::from_raw(b_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>a_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>b_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">4000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from b </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div><p>Got curious and asked ChatGPT below question:</p> Rust: From vs Into traits - /blog/rust-from-vs-into-traits/ + //localhost:9999/blog/rust-from-vs-into-traits/ Mon, 06 Jan 2025 06:17:07 -0700 - /blog/rust-from-vs-into-traits/ + //localhost:9999/blog/rust-from-vs-into-traits/ <h2 id="why-does-implementing-fromt-on-u-enable-calling-tinto-to-get-u">Why does implementing <code>From&lt;T&gt;</code> on <code>U</code> enable calling <code>T.into()</code> to get <code>U</code>?</h2> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">impl</span><span style="color:#bbb"> </span><span style="color:#038">From</span>&lt;A&gt;<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">for</span><span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">from</span>(a: <span style="color:#b06;font-weight:bold">A</span>)<span style="color:#bbb"> </span>-&gt; <span style="color:#b06;font-weight:bold">B</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Convert A to B </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div><p>By implementing the <code>from()</code> static method on <code>B</code>, you can convert an instance of <code>A</code> to <code>B</code>:</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>a: <span style="color:#b06;font-weight:bold">A</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>...;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>b: <span style="color:#b06;font-weight:bold">B</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B::from(a);<span style="color:#bbb"> </span><span style="color:#888">// This works </span></span></span></code></pre></div><p>However, in practice, we often avoid using this directly, as it isn&rsquo;t considered idiomatic Rust. Instead, we do the following:</p> Compiler Internals - /blog/compiler-internals/ + //localhost:9999/blog/compiler-internals/ Fri, 01 Nov 2019 18:33:07 -0700 - /blog/compiler-internals/ + //localhost:9999/blog/compiler-internals/ <h2 id="basics">Basics</h2> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#888">//a.c </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">myadd</span>() { </span></span><span style="display:flex;"><span> <span style="color:#888;font-weight:bold">int</span> sum = <span style="color:#00d;font-weight:bold">10</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">for</span> (<span style="color:#888;font-weight:bold">int</span> i = <span style="color:#00d;font-weight:bold">0</span>; i &lt; <span style="color:#00d;font-weight:bold">100</span>; i++) </span></span><span style="display:flex;"><span> sum += i; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> sum; </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">myadd2</span>() { </span></span><span style="display:flex;"><span> <span style="color:#888;font-weight:bold">int</span> sum = <span style="color:#00d;font-weight:bold">10</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">for</span> (<span style="color:#888;font-weight:bold">int</span> i = <span style="color:#00d;font-weight:bold">0</span>; i &lt; <span style="color:#00d;font-weight:bold">100</span>; i++) </span></span><span style="display:flex;"><span> sum += i*i; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> sum; </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> <span style="color:#06b;font-weight:bold">myadd</span>(); </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>&gt;cl /c a.c </span></span><span style="display:flex;"><span>&gt;link /dump /symbols a.obj </span></span><span style="display:flex;"><span><span style="color:#00d;font-weight:bold">008</span> <span style="color:#00d;font-weight:bold">00000000</span> SECT3 notype () External | myadd </span></span><span style="display:flex;"><span><span style="color:#00d;font-weight:bold">009</span> <span style="color:#00d;font-weight:bold">00000050</span> SECT3 notype () External | myadd2 </span></span><span style="display:flex;"><span>00A 000000A0 SECT3 notype () External | main </span></span></code></pre></div><p>The <strong>link /dump</strong> command dumps the symbols that are part of the obj file. The compiler cannot optimize myadd2 because technically these unused functions can be accessed by functions in other libs.</p> UART - From AVR to Linux to Logic Analyzer - /blog/uart-from-avr-to-linux-to-logic-analyzer/ + //localhost:9999/blog/uart-from-avr-to-linux-to-logic-analyzer/ Fri, 20 Sep 2019 18:33:07 -0700 - /blog/uart-from-avr-to-linux-to-logic-analyzer/ + //localhost:9999/blog/uart-from-avr-to-linux-to-logic-analyzer/ <h1 id="uart---from-avr-to-linux-to-logic-analyzer">UART - From AVR to Linux to Logic Analyzer</h1> <h1 id="introduction">Introduction</h1> <p>In this article, let&rsquo;s see how a program running on Atmega328PU microcontroller can communicate to external world using UART. In order to run through this exercise we need below equipment.</p> <ol> <li><a href="https://www.aliexpress.com/item/32973635527.html?spm=a2g0s.9042311.0.0.27424c4dOZJfJV">Atmega328PU Microcontroller</a></li> <li>Breadboard</li> <li><a href="https://www.aliexpress.com/item/32651814443.html?spm=a2g0s.9042311.0.0.27424c4dOZJfJV">AVR/USBASP programmer</a></li> <li><a href="https://www.amazon.com/gp/product/B00QT7LQ88/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&amp;psc=1">USB to TTL Adapater</a></li> <li><a href="https://www.aliexpress.com/item/33062091072.html?spm=a2g0s.9042311.0.0.27424c4dHus6xH">Logic Analyzer</a></li> <li><a href="https://www.aliexpress.com/item/33024255264.html?spm=a2g0s.9042311.0.0.65aa4c4dDiDkXx">Digital Oscilloscope</a></li> </ol> <h1 id="atmega328pu-pinout">Atmega328PU pinout</h1> <p>It is an 8-bit microcontroller(uC) with following pinout. All its digital pins are grouped in to 4 banks(PA/PB/PC/PD). <img src="Atmega328PUPinout.png" alt=""></p> What Does It Take To Write An Emulator In Java? - /blog/what-does-it-take-to-write-an-emulator-in-java/ + //localhost:9999/blog/what-does-it-take-to-write-an-emulator-in-java/ Wed, 10 Apr 2019 18:33:07 -0700 - /blog/what-does-it-take-to-write-an-emulator-in-java/ + //localhost:9999/blog/what-does-it-take-to-write-an-emulator-in-java/ <h1 id="introduction">Introduction</h1> <p>I am proud, This weekend I did some productive work. I was able to code Chip 8 emulator in Java over a night. I have always been fascinated by them and finally I was able to get the damn thing to work! For those of you who are not familiar with software emulator, It is a software which can emulate the functionality of other hardware or software components. Notable examples are video game emulators(<a href="https://en.wikipedia.org/wiki/DOSBox">Dosbox</a> ,<a href="https://en.wikipedia.org/wiki/List_of_video_game_emulators">NES Emulator</a>), general purpose software emulators(<a href="https://en.wikipedia.org/wiki/QEMU">QEmu</a>)</p> Setting User Mode Break Points From Kd Aka .process /i Vs .process /r /p - /blog/usermode-breakpoints-from-kd/ + //localhost:9999/blog/usermode-breakpoints-from-kd/ Sun, 10 Mar 2019 18:33:07 -0700 - /blog/usermode-breakpoints-from-kd/ + //localhost:9999/blog/usermode-breakpoints-from-kd/ <h1 id="introduction">Introduction</h1> <p>When performing KD(Kernel Debugging) in Windows with Windbg if you have to set a break point in a user mode process we should always use <strong>.process /i address; g; .reload /user</strong>. Lot of good content is written on the <a href="https://www.osronline.com/article.cfm%5Earticle=576.htm">internet</a> on this command, but nothing seemed to explain why this command should be used instead of the familiar <strong>.process /r /p address</strong>. I would like to shed some light on this. Before reading any further I would strongly encourage you to read about it from above link. In this article I assume some basic knowledge on how kernel debugging is done with Windbg. Also, I would like to start with the following question.</p> Signed/Unsigned Integer Arithmetic In C - /blog/signed-unsigned-integer-arithmetic-in-c/ + //localhost:9999/blog/signed-unsigned-integer-arithmetic-in-c/ Sun, 10 Feb 2019 18:33:07 -0700 - /blog/signed-unsigned-integer-arithmetic-in-c/ + //localhost:9999/blog/signed-unsigned-integer-arithmetic-in-c/ <h1 id="introduction">Introduction</h1> <p>This article is about understanding how integer conversions happen in C language. The C standard defines the integer conversion rules agnostic to any specific machine architecture. This also makes things more complicated for programmers to understand.</p> <p>First of all, Why do we need integer conversions at all? The answer is simple, we need to have single type for any given expression. Let&rsquo;s say we have an expression <em><expr1><op><expr2></em> when expr1 and expr2 are of different types, we want the resulting expression from this to have one single type.</p> Pdb Files: The Glue Between The Binary File And Source Code - /blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ + //localhost:9999/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ Thu, 10 Jan 2019 18:33:07 -0700 - /blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ + //localhost:9999/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ <h1 id="introduction">Introduction</h1> <p>Have you ever wondered how a debugger magically gets you to the correct pdb and correct sources when debugging an application? This article talks exactly that in the context of Windbg.</p> <p>As you might be aware of, PDB files(also called as symbol files) is the glue between your application binary and the source code. There are two key Environment variables which configures Windbg about where to look for symbols and sources. They are _NT_SYMBOL_PATH and _NT_SOURCE_PATH. The _NT_SYMBOL_PATH points to the directory containing your PDBs(also called as symbol files) or to a symbol server. _NT_SOURCE_PATH points to the directory of your sources or to a source server which indexes the soruce files. One important point to remember here is one or more source files make up one or more binary files. But each binary will have a single PDB unless the source code is modified. This is important because Windbg has to perform lot of book keeping to map binary symbols with their source locations.</p> PCI Express Basics 101 - /blog/pci-express-basics-101/ + //localhost:9999/blog/pci-express-basics-101/ Mon, 10 Dec 2018 18:33:07 -0700 - /blog/pci-express-basics-101/ + //localhost:9999/blog/pci-express-basics-101/ <h1 id="introduction">Introduction</h1> <p>PCI Express: It is a standard which comes in multiple generations and multiple lane configurations. PCI-E is in its 5th generation, but mostly the current shipping generation is 3rd generation also called as Gen 3. Mainly each generation improves upon the previous generation regarding the speed per lane supported by the protocol.</p> <p>Below is the table for each generation and lane speed For single-lane and 16-lane links, in each direction:</p> Lib Files 101 - /blog/lib-files-101/ + //localhost:9999/blog/lib-files-101/ Sat, 10 Nov 2018 18:33:07 -0700 - /blog/lib-files-101/ + //localhost:9999/blog/lib-files-101/ <h1 id="introduction">Introduction</h1> <p>During the compilation one of the crucial step after assembling is creating the Object files. The collection of these object files is called a lib file. We can create these .lib files through following visual studio project types</p> <ol> <li>Static Library</li> <li>Dynamic Linked Library</li> </ol> <p>The format of these .lib files is specified in &lsquo;Archive (Library) File Format.&rsquo; section of <a href="https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#archive-library-file-formatspecification">PE Format</a>. As per the spec, .lib is an archive of individual .obj files with some metadata. Multiple tools can be used to extract lib files. Visual Studio installation contains Lib.exe tool. Since .lib and .obj files follow Unix COFF format Unix binutil&rsquo;s &lsquo;ar&rsquo; tool can be used to extract it.</p> How Do Breakpoints Work In Debuggers? - /blog/how-do-breakpoints-work-in-debuggers/ + //localhost:9999/blog/how-do-breakpoints-work-in-debuggers/ Wed, 10 Oct 2018 18:33:07 -0700 - /blog/how-do-breakpoints-work-in-debuggers/ + //localhost:9999/blog/how-do-breakpoints-work-in-debuggers/ <h1 id="introduction">Introduction</h1> <p>It&rsquo;s been a while, I have got a chance to blog about low-level stuff. In this article, I am going to explain how breakpoints work in debuggers. I am assuming the reader is already familiar with what a breakpoint is? and how to set it in your debugger of choice. The goal of this post is to explain the interplay between Debugger, Debuggee, Operating System and the CPU.</p> <h1 id="breakpoints-theory">Breakpoints Theory</h1> <p>To get there, we have to ask ourselves What does it mean by debugging a program/process?. To keep it simple, It&rsquo;s the controlled execution of a program by other program. The devil is in the word controlled. Whenever you open a debugger and launch a program or attach to a running process, the OS and the CPU guarantees that any event (like dll loading or interrupts or exceptions etc) happening on behalf of debuggee process are notified to debugger process for it to take necessary action. The important thing to understand here is, it&rsquo;s the execution of debuggee which is causing the debugger to take actions on behalf of it, not the other way around. So there should be something in the debuggee&rsquo;s code that should cause CPU to do the heavy lifting. This is where CPU&rsquo;s breakpoint instruction comes in. Every x86/amd64 CPU provides a special instruction called breakpoint instruction Int 3 whose mnemonic is 0xCC. When a piece of code executes this instruction, the CPU triggers a breakpoint interrupt and notifies it to OS and asks it what needs to be done next. Now this event from OS gets propagated to debugger by pausing all the threads in the debuggee. Now it&rsquo;s up to debugger to handle it according to its will.</p> A Newbie's Introduction To Compilation Process And Reverse Engineering - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ Fri, 10 Aug 2018 18:33:07 -0700 - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ <h1 id="introduction">Introduction</h1> <p>Compilers are surely the complex programs of all times. Even today, writing a compiler with minimum set of tools is considered to be challenging. This tutorial scratches the surface of different compiler phases involved in translating a given source code to executable and also shows how this information is useful in context of reverse engineering.</p> <p><a href="https://en.wikipedia.org/wiki/GNU_Compiler_Collection">GNU compiler collection</a> provides an excellent set of tools for dissecting the compilation process and to understand the working of bits and bytes in the final executable. For this tutorial I am using the following tools and considers C language to illustrate the examples.</p> Libspng - C Language Case Study - /blog/c-case-studies/f/ + //localhost:9999/blog/c-case-studies/f/ Tue, 10 Jul 2018 18:33:07 -0700 - /blog/c-case-studies/f/ + //localhost:9999/blog/c-case-studies/f/ <h1 id="build-system">Build System</h1> <p>It uses meson build system to build the library</p> <h1 id="data-structures">Data Structures</h1> <p>It is not using any fancy data structures instead it relies on plain array of objects and uses the traditional realloc function to expand them.</p> <h1 id="miscellaneous">Miscellaneous</h1> <p>All variables are declared as when needed. This deviates from Linux source code. In Linux kernel, declarations are done only in the beginning of a new scope (either at the start of the function or start of a scope)</p> diff --git a/docs/blog/lib-files-101/index.html b/docs/blog/lib-files-101/index.html index b4ec617..c80d64b 100644 --- a/docs/blog/lib-files-101/index.html +++ b/docs/blog/lib-files-101/index.html @@ -1,6 +1,6 @@ - + Lib Files 101 | Vineel Kovvuri diff --git a/docs/blog/pci-express-basics-101/index.html b/docs/blog/pci-express-basics-101/index.html index 2249090..40844b0 100644 --- a/docs/blog/pci-express-basics-101/index.html +++ b/docs/blog/pci-express-basics-101/index.html @@ -1,6 +1,6 @@ - + PCI Express Basics 101 | Vineel Kovvuri diff --git a/docs/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/index.html b/docs/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/index.html index 6ded3a0..a0ca9dc 100644 --- a/docs/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/index.html +++ b/docs/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/index.html @@ -1,6 +1,6 @@ - + Pdb Files: The Glue Between The Binary File And Source Code | Vineel Kovvuri diff --git a/docs/blog/rust-aligned-vs-unaligned-memory-access/index.html b/docs/blog/rust-aligned-vs-unaligned-memory-access/index.html index d36c41e..defaa5e 100644 --- a/docs/blog/rust-aligned-vs-unaligned-memory-access/index.html +++ b/docs/blog/rust-aligned-vs-unaligned-memory-access/index.html @@ -1,6 +1,6 @@ - + Rust: Aligned vs Unaligned Memory Access | Vineel Kovvuri diff --git a/docs/blog/rust-from-vs-into-traits-part-2/index.html b/docs/blog/rust-from-vs-into-traits-part-2/index.html index d627695..e810175 100644 --- a/docs/blog/rust-from-vs-into-traits-part-2/index.html +++ b/docs/blog/rust-from-vs-into-traits-part-2/index.html @@ -1,6 +1,6 @@ - + Rust: From and Into trait - Part 2 | Vineel Kovvuri diff --git a/docs/blog/rust-from-vs-into-traits/index.html b/docs/blog/rust-from-vs-into-traits/index.html index b031350..fec8bf0 100644 --- a/docs/blog/rust-from-vs-into-traits/index.html +++ b/docs/blog/rust-from-vs-into-traits/index.html @@ -1,6 +1,6 @@ - + Rust: From vs Into traits | Vineel Kovvuri diff --git a/docs/blog/rust-sharing-objects/index.html b/docs/blog/rust-sharing-objects/index.html index 34eef91..6e9ef52 100644 --- a/docs/blog/rust-sharing-objects/index.html +++ b/docs/blog/rust-sharing-objects/index.html @@ -1,6 +1,6 @@ - + Rust: Sharing a Single Object Across Multiple Owners | Vineel Kovvuri diff --git a/docs/blog/rust-usage-of-cow/index.html b/docs/blog/rust-usage-of-cow/index.html new file mode 100644 index 0000000..2543333 --- /dev/null +++ b/docs/blog/rust-usage-of-cow/index.html @@ -0,0 +1,142 @@ + + + + + + Rust: Usage of Cow(Clone on Write) | Vineel Kovvuri + + + + + + + + + + + +
    +

    Rust: Usage of Cow(Clone on Write)

    +

    Today, After reading following blog +post(https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/), +I finally understood the need for Cow in Rust. Below is my code sample with +relevant comments.

    +
    use std::borrow::Cow;
    +
    +#[derive(Clone, Debug)]
    +struct Book {
    +    name: String,
    +    price: u32,
    +}
    +
    +fn update_book_price<'a>(book: &'a Book, price: u32) -> Cow<'a, Book> {
    +    // If the price matches, there's no need to create a new book.
    +    if book.price == price {
    +        return Cow::Borrowed(book);
    +    }
    +
    +    // If the price does not match, create a new book (updating the title to
    +    // make it easy to distinguish the objects).
    +    Cow::Owned(Book {
    +        name: format!("{}-updated", book.name.clone()),
    +        price,
    +    })
    +}
    +
    +fn main() {
    +    let book = Book {
    +        name: "Rust programming".to_string(),
    +        price: 100,
    +    };
    +
    +    // CASE 1: Since there is no change in price, we get a `Cow` wrapped
    +    // borrowed version of the existing book.
    +    let updated_book: Cow<'_, Book> = update_book_price(&book, 100);
    +    // The returned `Cow` object is always immutable. The following line will
    +    // not work even though we can access the object fields via the `Deref`
    +    // trait:
    +    // updated_book.price = 200;
    +    println!("{:?}", updated_book); // Book { name: "Rust programming", price: 100 }
    +
    +    // If we ever need to own the above object (e.g., for modifying it), we can
    +    // call `into_owned()` on `Cow` to get a cloned version of the book.
    +    // This cloned object will be mutable.
    +    let mut updated_book: Book = updated_book.into_owned();
    +    updated_book.price = 200;
    +    println!("{:?}", updated_book); // Book { name: "Rust programming", price: 200 }
    +
    +    // ========================================
    +
    +    // CASE 2: Since the price has changed, we get a `Cow` wrapped owned version
    +    // of the book. This owned version is the object we created in the
    +    // `update_book_price()` method.
    +    let updated_book: Cow<'_, Book> = update_book_price(&book, 300);
    +    // Again, the returned object is immutable, so the following line will not
    +    // work:
    +    // updated_book.price = 400;
    +    println!("{:?}", updated_book); // Book { name: "Rust programming-updated", price: 300 }
    +
    +    // If we ever need to own this object (e.g., for modifying it), we can call
    +    // `into_owned()` on `Cow` to get the owned object. Importantly, in this
    +    // case, `Cow` simply returns the already owned object instead of cloning
    +    // it. The returned object will be mutable.
    +    let mut updated_book: Book = updated_book.into_owned();
    +    updated_book.price = 400;
    +    println!("{:?}", updated_book); // Book { name: "Rust programming-updated", price: 400 }
    +
    +    // Takeaway 1: `Cow` allows us to defer cloning a borrowed object until it
    +    // is required for modification (ownership). When ownership is needed, `Cow`
    +    // provides the following behavior via `into_owned()`:
    +    // 1. `Cow` either calls `clone()` on the borrowed object.
    +    // 2. Or, `Cow` directly returns the underlying owned object.
    +
    +    // Takeaway 2: With the help of `Cow` (Clone-On-Write), we can design
    +    // methods optimized to return the borrowed object wrapped inside `Cow`.
    +    // This approach helps delay the cloning process. Specifically, the
    +    // `update_book_price()` method returns either a borrowed `Cow` or an owned
    +    // `Cow`, catering to both cases. However, this flexibility is not always
    +    // necessary. Since every type `T` that `Cow` wraps requires
    +    // `#[derive(Clone)]`, `Cow` can decide when to clone the borrowed object
    +    // and when to return the underlying owned object directly, depending on the
    +    // need when `into_owned()` is called.
    +
    +    // Reference: https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/
    +}
    +
    +
    + +
    + + + + + + + + + + +
    + © Vineel Kumar Reddy Kovvuri 2017 – 2025 ❤️ Hugo Xmin + +
    + + + diff --git a/docs/blog/signed-unsigned-integer-arithmetic-in-c/index.html b/docs/blog/signed-unsigned-integer-arithmetic-in-c/index.html index b45c8fe..919a7cc 100644 --- a/docs/blog/signed-unsigned-integer-arithmetic-in-c/index.html +++ b/docs/blog/signed-unsigned-integer-arithmetic-in-c/index.html @@ -1,6 +1,6 @@ - + Signed/Unsigned Integer Arithmetic In C | Vineel Kovvuri diff --git a/docs/blog/uart-from-avr-to-linux-to-logic-analyzer/index.html b/docs/blog/uart-from-avr-to-linux-to-logic-analyzer/index.html index 97f96c5..74bbb47 100644 --- a/docs/blog/uart-from-avr-to-linux-to-logic-analyzer/index.html +++ b/docs/blog/uart-from-avr-to-linux-to-logic-analyzer/index.html @@ -1,6 +1,6 @@ - + UART - From AVR to Linux to Logic Analyzer | Vineel Kovvuri diff --git a/docs/blog/usermode-breakpoints-from-kd/index.html b/docs/blog/usermode-breakpoints-from-kd/index.html index 1f5aad4..e6f0f69 100644 --- a/docs/blog/usermode-breakpoints-from-kd/index.html +++ b/docs/blog/usermode-breakpoints-from-kd/index.html @@ -1,6 +1,6 @@ - + Setting User Mode Break Points From Kd Aka .process /i Vs .process /r /p | Vineel Kovvuri diff --git a/docs/blog/what-does-it-take-to-write-an-emulator-in-java/index.html b/docs/blog/what-does-it-take-to-write-an-emulator-in-java/index.html index 900566a..3580d01 100644 --- a/docs/blog/what-does-it-take-to-write-an-emulator-in-java/index.html +++ b/docs/blog/what-does-it-take-to-write-an-emulator-in-java/index.html @@ -1,6 +1,6 @@ - + What Does It Take To Write An Emulator In Java? | Vineel Kovvuri diff --git a/docs/categories/index.html b/docs/categories/index.html index 5a89715..09a727c 100644 --- a/docs/categories/index.html +++ b/docs/categories/index.html @@ -1,6 +1,6 @@ - + Categories | Vineel Kovvuri diff --git a/docs/categories/index.xml b/docs/categories/index.xml index 6b3fb1a..35a0d05 100644 --- a/docs/categories/index.xml +++ b/docs/categories/index.xml @@ -2,10 +2,10 @@ Categories on Vineel Kovvuri - /categories/ + //localhost:9999/categories/ Recent content in Categories on Vineel Kovvuri Hugo en-us - + diff --git a/docs/courses/c/index.html b/docs/courses/c/index.html index 3243620..c521200 100644 --- a/docs/courses/c/index.html +++ b/docs/courses/c/index.html @@ -1,6 +1,6 @@ - + C Language Course Structure | Vineel Kovvuri diff --git a/docs/courses/index.html b/docs/courses/index.html index dc153cb..0bfa95b 100644 --- a/docs/courses/index.html +++ b/docs/courses/index.html @@ -1,6 +1,6 @@ - + Courses | Vineel Kovvuri diff --git a/docs/courses/index.xml b/docs/courses/index.xml index f7a7a7f..8716a09 100644 --- a/docs/courses/index.xml +++ b/docs/courses/index.xml @@ -2,37 +2,37 @@ Courses on Vineel Kovvuri - /courses/ + //localhost:9999/courses/ Recent content in Courses on Vineel Kovvuri Hugo en-us - + C Language Course Structure - /courses/c/ + //localhost:9999/courses/c/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/c/ + //localhost:9999/courses/c/ <h1 id="c">C</h1> <ul> <li>Some Fundamentals</li> <li>Compiling And Running Your First Program</li> <li>Variables, Data Types, And Arithmetic Expressions</li> <li>Program Looping</li> <li>Making Decisions</li> <li>Working With Arrays</li> <li>Working With Functions</li> <li>Working With Structures</li> <li>Character Strings</li> <li>Pointers</li> <li>Operations On Bits</li> <li>The Preprocessor</li> <li>Extending Data Types With The Enumerated Data Type, Type Definitions, And Data Type Conversions</li> <li>Working With Larger Programs</li> <li>Input And Output Operations In C</li> <li>Miscellaneous And Advanced Features</li> <li>Debugging Programs</li> <li>Object-Oriented Programming</li> <li>The Standard C Library</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/CBook/">C Programming Notes for Professionals</a></li> </ul> Java Course Structure - /courses/java/ + //localhost:9999/courses/java/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/java/ + //localhost:9999/courses/java/ <h1 id="java">Java</h1> <h2 id="the-java-language">The Java Language</h2> <ul> <li>The History and Evolution of Java</li> <li>An Overview of Java</li> <li>Data Types, Variables, and Arrays</li> <li>Operators</li> <li>Control Statements</li> <li>Introducing Classes</li> <li>A Closer Look at Methods and Classes</li> <li>Inheritance</li> <li>Packages and Interfaces</li> <li>Exception Handling</li> <li>Multithreaded Programming</li> <li>Enumerations, Autoboxing, and Annotations</li> <li>I/O, Try-with-Resources, and Other Topics</li> <li>Generics</li> <li>Lambda Expressions</li> <li>Modules</li> <li>Switch Expressions, Records, and Other Recently Added Features</li> </ul> <h2 id="the-java-library">The Java Library</h2> <ul> <li>String Handling</li> <li>Exploring java.lang</li> <li>java.util Part 1: The Collections Framework</li> <li>java.util Part 2: More Utility Classes</li> <li>Input/Output: Exploring java.io</li> <li>Exploring NIO</li> <li>Networking</li> <li>Event Handling</li> <li>Images</li> <li>The Concurrency Utilities</li> <li>The Stream API</li> <li>Regular Expressions and Other Packages</li> </ul> <h2 id="introducing-gui-programming-with-swing">Introducing GUI Programming With Swing</h2> <ul> <li>Introducing Swing</li> <li>Exploring Swing</li> <li>Introducing Swing Menus</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/JavaBook/">Java Notes for Professionals</a></li> </ul> Linux Course Structure - /courses/linux/ + //localhost:9999/courses/linux/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/linux/ + //localhost:9999/courses/linux/ <h1 id="linux">Linux</h1> <h2 id="learning-the-shell">Learning The Shell</h2> <ul> <li>What Is The Shell</li> <li>Navigation</li> <li>Exploring The System</li> <li>Manipulating Files And Directories</li> <li>Working With Commands</li> <li>Redirection</li> <li>Seeing The World As The Shell Sees It</li> <li>Advanced Keyboard Tricks</li> <li>Permissions</li> <li>Processes</li> </ul> <h2 id="configuration-and-the-environment">Configuration And The Environment</h2> <ul> <li>The Environment</li> <li>A Gentle Introduction To Vi</li> <li>Customizing The Prompt</li> </ul> <h2 id="common-tasks-and-essential-tools">Common Tasks And Essential Tools</h2> <ul> <li>Package Management</li> <li>Storage Media</li> <li>Networking</li> <li>Searching For Files</li> <li>Archiving And Backup</li> <li>Regular Expressions</li> <li>Text Processing</li> <li>Formatting Output</li> <li>Printing</li> <li>Compiling Programs</li> </ul> <h2 id="writing-shell-scripts">Writing Shell Scripts</h2> <ul> <li>Writing Your First Script</li> <li>Starting A Project</li> <li>Top Down Design</li> <li>Flow Control Branching With If</li> <li>Reading Keyboard Input</li> <li>Flow Control Looping With While Until</li> <li>Troubleshooting</li> <li>Flow Control Branching With Case</li> <li>Positional Parameters</li> <li>Flow Control Looping With For</li> <li>Strings And Numbers</li> <li>Arrays</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/LinuxBook/">Linux Commands Notes for Professionals</a></li> </ul> Python Course Structure - /courses/python/ + //localhost:9999/courses/python/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/python/ + //localhost:9999/courses/python/ <h1 id="python">Python</h1> <h2 id="getting-started">Getting Started</h2> <ul> <li>A Python Q&amp;A Session</li> <li>How Python Runs Programs</li> <li>How You Run Programs</li> </ul> <h2 id="types-and-operations">Types And Operations</h2> <ul> <li>Introducing Python Object Types</li> <li>Numeric Types</li> <li>The Dynamic Typing Interlude</li> <li>String Fundamentals</li> <li>Lists And Dictionaries</li> <li>Tuples, Files, And Everything Else</li> </ul> <h2 id="statements-and-syntax">Statements And Syntax</h2> <ul> <li>Introducing Python Statements</li> <li>Assignments, Expressions, And Prints</li> <li>If Tests And Syntax Rules</li> <li>While And For Loops</li> <li>Iterations And Comprehensions</li> <li>The Documentation Interlude</li> </ul> <h2 id="functions-and-generators">Functions And Generators</h2> <ul> <li>Function Basics</li> <li>Scopes</li> <li>Arguments</li> <li>Advanced Function Topics</li> <li>Comprehensions And Generations</li> <li>The Benchmarking Interlude</li> </ul> <h2 id="modules-and-packages">Modules And Packages</h2> <ul> <li>Modules: The Big Picture</li> <li>Module Coding Basics</li> <li>Module Packages</li> <li>Advanced Module Topics</li> </ul> <h2 id="classes-and-oop">Classes And OOP</h2> <ul> <li>OOP: The Big Picture</li> <li>Class Coding Basics</li> <li>A More Realistic Example</li> <li>Class Coding Details</li> <li>Operator Overloading</li> <li>Designing With Classes</li> <li>Advanced Class Topics</li> </ul> <h2 id="exceptions-and-tools">Exceptions And Tools</h2> <ul> <li>Exception Basics</li> <li>Exception Coding Details</li> <li>Exception Objects</li> <li>Designing With Exceptions</li> </ul> <h2 id="advanced-topics">Advanced Topics</h2> <ul> <li>Unicode And Byte Strings</li> <li>Managed Attributes</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/PythonBook/">Python Notes for Professionals</a></li> </ul> diff --git a/docs/courses/java/index.html b/docs/courses/java/index.html index 2433606..71225c3 100644 --- a/docs/courses/java/index.html +++ b/docs/courses/java/index.html @@ -1,6 +1,6 @@ - + Java Course Structure | Vineel Kovvuri diff --git a/docs/courses/linux/index.html b/docs/courses/linux/index.html index a7ca691..8662f02 100644 --- a/docs/courses/linux/index.html +++ b/docs/courses/linux/index.html @@ -1,6 +1,6 @@ - + Linux Course Structure | Vineel Kovvuri diff --git a/docs/courses/python/index.html b/docs/courses/python/index.html index c2c0791..308ac88 100644 --- a/docs/courses/python/index.html +++ b/docs/courses/python/index.html @@ -1,6 +1,6 @@ - + Python Course Structure | Vineel Kovvuri diff --git a/docs/index.html b/docs/index.html index bd3592c..3a2cf03 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,7 +3,7 @@ - + Home | Vineel Kovvuri @@ -43,6 +43,13 @@

    Blog

    +
  • + 2025/01/17 + Rust: Usage of Cow(Clone on Write) +
  • + + +
  • 2025/01/14 Rust: From and Into trait - Part 2 @@ -105,13 +112,6 @@

    Blog

  • - -
  • - 2019/01/10 - Pdb Files: The Glue Between The Binary File And Source Code -
  • - -
  • more...
  • diff --git a/docs/index.xml b/docs/index.xml index ac25785..45af18f 100644 --- a/docs/index.xml +++ b/docs/index.xml @@ -2,172 +2,179 @@ Home on Vineel Kovvuri - / + //localhost:9999/ Recent content in Home on Vineel Kovvuri Hugo en-us - Tue, 14 Jan 2025 23:33:54 +0000 - + Fri, 17 Jan 2025 14:03:43 +0000 + + + Rust: Usage of Cow(Clone on Write) + //localhost:9999/blog/rust-usage-of-cow/ + Fri, 17 Jan 2025 14:03:43 +0000 + //localhost:9999/blog/rust-usage-of-cow/ + <h2 id="rust-usage-of-cowclone-on-write">Rust: Usage of Cow(Clone on Write)</h2> <p>Today, After reading following blog post(<a href="https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/)">https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/)</a>, I finally understood the need for Cow in Rust. Below is my code sample with relevant comments.</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">use</span><span style="color:#bbb"> </span>std::borrow::Cow;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Clone, Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#038">String</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price: <span style="color:#888;font-weight:bold">u32</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">update_book_price</span>&lt;<span style="color:#369">&#39;a</span>&gt;(book: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">Book</span>,<span style="color:#bbb"> </span>price: <span style="color:#888;font-weight:bold">u32</span>)<span style="color:#bbb"> </span>-&gt; <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#369">&#39;a</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If the price matches, there&#39;s no need to create a new book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">if</span><span style="color:#bbb"> </span>book.price<span style="color:#bbb"> </span>==<span style="color:#bbb"> </span>price<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">return</span><span style="color:#bbb"> </span>Cow::Borrowed(book);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If the price does not match, create a new book (updating the title to </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// make it easy to distinguish the objects). </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>Cow::Owned(Book<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#b06;font-weight:bold">format</span>!(<span style="color:#d20;background-color:#fff0f0">&#34;{}-updated&#34;</span>,<span style="color:#bbb"> </span>book.name.clone()),<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>})<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>book<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>Book<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#d20;background-color:#fff0f0">&#34;Rust programming&#34;</span>.to_string(),<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price: <span style="color:#00d;font-weight:bold">100</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// CASE 1: Since there is no change in price, we get a `Cow` wrapped </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// borrowed version of the existing book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#038">&#39;_</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>update_book_price(&amp;book,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">100</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// The returned `Cow` object is always immutable. The following line will </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// not work even though we can access the object fields via the `Deref` </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// trait: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// updated_book.price = 200; </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming&#34;, price: 100 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If we ever need to own the above object (e.g., for modifying it), we can </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// call `into_owned()` on `Cow` to get a cloned version of the book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// This cloned object will be mutable. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>updated_book.into_owned();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>updated_book.price<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">200</span>;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming&#34;, price: 200 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// ======================================== </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// CASE 2: Since the price has changed, we get a `Cow` wrapped owned version </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// of the book. This owned version is the object we created in the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `update_book_price()` method. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#038">&#39;_</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>update_book_price(&amp;book,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">300</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Again, the returned object is immutable, so the following line will not </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// work: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// updated_book.price = 400; </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming-updated&#34;, price: 300 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If we ever need to own this object (e.g., for modifying it), we can call </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `into_owned()` on `Cow` to get the owned object. Importantly, in this </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// case, `Cow` simply returns the already owned object instead of cloning </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// it. The returned object will be mutable. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>updated_book.into_owned();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>updated_book.price<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">400</span>;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming-updated&#34;, price: 400 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 1: `Cow` allows us to defer cloning a borrowed object until it </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// is required for modification (ownership). When ownership is needed, `Cow` </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// provides the following behavior via `into_owned()`: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// 1. `Cow` either calls `clone()` on the borrowed object. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// 2. Or, `Cow` directly returns the underlying owned object. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 2: With the help of `Cow` (Clone-On-Write), we can design </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// methods optimized to return the borrowed object wrapped inside `Cow`. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// This approach helps delay the cloning process. Specifically, the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `update_book_price()` method returns either a borrowed `Cow` or an owned </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `Cow`, catering to both cases. However, this flexibility is not always </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// necessary. Since every type `T` that `Cow` wraps requires </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `#[derive(Clone)]`, `Cow` can decide when to clone the borrowed object </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// and when to return the underlying owned object directly, depending on the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// need when `into_owned()` is called. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Reference: https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/ </span></span></span><span style="display:flex;"><span><span style="color:#888"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div> + Rust: From and Into trait - Part 2 - /blog/rust-from-vs-into-traits-part-2/ + //localhost:9999/blog/rust-from-vs-into-traits-part-2/ Tue, 14 Jan 2025 23:33:54 +0000 - /blog/rust-from-vs-into-traits-part-2/ + //localhost:9999/blog/rust-from-vs-into-traits-part-2/ <h2 id="rust-from-and-into-trait-usage">Rust: From and Into trait usage</h2> <p>Knowing how Rust&rsquo;s <code>From</code> and <code>Into</code> traits work is one part of the story, but being able to use them efficiently is another. In this code sample, we will explore how to define functions or methods that accept parameters which can be converted from and into the expected types.</p> <p>In this code, we have two functions, <code>increment()</code> and <code>increment2()</code>, and we will see how they work with the <code>From</code> trait implemented for the <code>Number</code> type.</p> Rust: Aligned vs Unaligned Memory Access - /blog/rust-aligned-vs-unaligned-memory-access/ + //localhost:9999/blog/rust-aligned-vs-unaligned-memory-access/ Tue, 14 Jan 2025 19:05:52 +0000 - /blog/rust-aligned-vs-unaligned-memory-access/ + //localhost:9999/blog/rust-aligned-vs-unaligned-memory-access/ <h2 id="rust-rust-aligned-vs-unaligned-memory-access">Rust: Rust Aligned vs Unaligned Memory Access</h2> <p>Unlike C, Rust enforces some rules when trying to access memory. Mainly it requires consideration to alignment of the data that we are trying to read. Below code will illustrate the details.</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data: [<span style="color:#888;font-weight:bold">u8</span>;<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">10</span>]<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>[<span style="color:#00d;font-weight:bold">0x11</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x22</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x33</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x44</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x55</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x66</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x77</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x88</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x99</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0xAA</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Alignment Tidbit: Alignment depends on the data type we are using. u8 has </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// an alignment of 1, so u8 values can be accessed at any address. In </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// contrast, u16 has an alignment of 2, so they can only be accessed at </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// addresses aligned by 2. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Case 1: unaligned u16 access from raw pointer. This will panic </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>)<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>;<span style="color:#bbb"> </span><span style="color:#888">// interpreting the underlying address as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>x<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>*ptr;<span style="color:#bbb"> </span><span style="color:#888">// This dereference will panic: misaligned pointer dereference: address must be a multiple of 0x2 but is 0x7ffdec94efcd </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;x: </span><span style="color:#33b;background-color:#fff0f0">{x}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Slices: Accessing elements through a slice will have the same alignment </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// as its underlying data. So this prevent unaligned access. Also we cannot </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpret a u8 array as a u16 slice unlike raw pointer access </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// Case 2: aligned u8 access from slice </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>slice<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;data[<span style="color:#00d;font-weight:bold">1</span>..<span style="color:#00d;font-weight:bold">2</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>value<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>slice[<span style="color:#00d;font-weight:bold">0</span>];<span style="color:#bbb"> </span><span style="color:#888">// This works </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;slice: </span><span style="color:#33b;background-color:#fff0f0">{value}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Case 3: unaligned u16 access from a slice using unsafe. This will panic </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr: *<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u8</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>unaligned_data_ptr: *<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u8</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// slice::from_raw_parts will panic as unaligned *const u8 is being </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpreted as *const u16 . </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>unaligned_slice<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>core::slice::from_raw_parts(data_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">usize</span>)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>value<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>slice[<span style="color:#00d;font-weight:bold">0</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;unaligned_slice: </span><span style="color:#33b;background-color:#fff0f0">{value}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 1: The takeaway here is that when interpreting *const u8 as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// or u32, we cannot simply cast *const u8 as *const u16 and dereference </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// that location and except u16. Instead, we can only access the *const u8 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// as two u8 values and then use bit math to combine those bytes to form a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// u16. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 2: When creating an array of u8(with odd number of elements), </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// the address at which the array starts in memory need not be a power of 2. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// Because u8&#39;s have an alignment of 1. If that is the case, and trying to </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpret data + 1 address location as u16 will not trigger a panic. Be </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// aware of that! </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data: [<span style="color:#888;font-weight:bold">u8</span>;<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">5</span>]<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>[<span style="color:#00d;font-weight:bold">0x11</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x22</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x33</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x44</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x55</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>)<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>;<span style="color:#bbb"> </span><span style="color:#888">// interpreting the underlying address as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>x<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>*ptr;<span style="color:#bbb"> </span><span style="color:#888">// This dereference will NOT trigger a panic! </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{x}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div> Rust: Sharing a Single Object Across Multiple Owners - /blog/rust-sharing-objects/ + //localhost:9999/blog/rust-sharing-objects/ Tue, 07 Jan 2025 00:17:07 -0700 - /blog/rust-sharing-objects/ + //localhost:9999/blog/rust-sharing-objects/ <h2 id="rust-sharing-a-single-object-across-multiple-owners">Rust: Sharing a Single Object Across Multiple Owners</h2> <p>Today, I found an interesting way to share a single object(C) among multiple owners(A and B)</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">use</span><span style="color:#bbb"> </span>std::ffi::c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">A</span>&lt;<span style="color:#369">&#39;a</span>&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>C,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">B</span>&lt;<span style="color:#369">&#39;a</span>&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>C,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#888">// Common object C shared between object A and object B </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">C</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>val: <span style="color:#888;font-weight:bold">u32</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// - Using stack objects </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;Object c shared b/w multiple stack based objects&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>C<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>val: <span style="color:#00d;font-weight:bold">100</span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>A<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>*(a_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>*(b_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>a_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>b_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">4000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from b </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// - Using heap objects </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;Object c shared b/w multiple heap based objects&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>C<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>val: <span style="color:#00d;font-weight:bold">100</span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>A<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#038">Box</span>::into_raw(<span style="color:#038">Box</span>::new(a))<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#038">Box</span>::into_raw(<span style="color:#038">Box</span>::new(b))<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>a_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span><span style="color:#038">Box</span>::&lt;A&gt;::from_raw(a_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>b_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span><span style="color:#038">Box</span>::&lt;B&gt;::from_raw(b_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>a_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>b_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">4000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from b </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div><p>Got curious and asked ChatGPT below question:</p> Rust: From vs Into traits - /blog/rust-from-vs-into-traits/ + //localhost:9999/blog/rust-from-vs-into-traits/ Mon, 06 Jan 2025 06:17:07 -0700 - /blog/rust-from-vs-into-traits/ + //localhost:9999/blog/rust-from-vs-into-traits/ <h2 id="why-does-implementing-fromt-on-u-enable-calling-tinto-to-get-u">Why does implementing <code>From&lt;T&gt;</code> on <code>U</code> enable calling <code>T.into()</code> to get <code>U</code>?</h2> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">impl</span><span style="color:#bbb"> </span><span style="color:#038">From</span>&lt;A&gt;<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">for</span><span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">from</span>(a: <span style="color:#b06;font-weight:bold">A</span>)<span style="color:#bbb"> </span>-&gt; <span style="color:#b06;font-weight:bold">B</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Convert A to B </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div><p>By implementing the <code>from()</code> static method on <code>B</code>, you can convert an instance of <code>A</code> to <code>B</code>:</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>a: <span style="color:#b06;font-weight:bold">A</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>...;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>b: <span style="color:#b06;font-weight:bold">B</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B::from(a);<span style="color:#bbb"> </span><span style="color:#888">// This works </span></span></span></code></pre></div><p>However, in practice, we often avoid using this directly, as it isn&rsquo;t considered idiomatic Rust. Instead, we do the following:</p> Compiler Internals - /blog/compiler-internals/ + //localhost:9999/blog/compiler-internals/ Fri, 01 Nov 2019 18:33:07 -0700 - /blog/compiler-internals/ + //localhost:9999/blog/compiler-internals/ <h2 id="basics">Basics</h2> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#888">//a.c </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">myadd</span>() { </span></span><span style="display:flex;"><span> <span style="color:#888;font-weight:bold">int</span> sum = <span style="color:#00d;font-weight:bold">10</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">for</span> (<span style="color:#888;font-weight:bold">int</span> i = <span style="color:#00d;font-weight:bold">0</span>; i &lt; <span style="color:#00d;font-weight:bold">100</span>; i++) </span></span><span style="display:flex;"><span> sum += i; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> sum; </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">myadd2</span>() { </span></span><span style="display:flex;"><span> <span style="color:#888;font-weight:bold">int</span> sum = <span style="color:#00d;font-weight:bold">10</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">for</span> (<span style="color:#888;font-weight:bold">int</span> i = <span style="color:#00d;font-weight:bold">0</span>; i &lt; <span style="color:#00d;font-weight:bold">100</span>; i++) </span></span><span style="display:flex;"><span> sum += i*i; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> sum; </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> <span style="color:#06b;font-weight:bold">myadd</span>(); </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>&gt;cl /c a.c </span></span><span style="display:flex;"><span>&gt;link /dump /symbols a.obj </span></span><span style="display:flex;"><span><span style="color:#00d;font-weight:bold">008</span> <span style="color:#00d;font-weight:bold">00000000</span> SECT3 notype () External | myadd </span></span><span style="display:flex;"><span><span style="color:#00d;font-weight:bold">009</span> <span style="color:#00d;font-weight:bold">00000050</span> SECT3 notype () External | myadd2 </span></span><span style="display:flex;"><span>00A 000000A0 SECT3 notype () External | main </span></span></code></pre></div><p>The <strong>link /dump</strong> command dumps the symbols that are part of the obj file. The compiler cannot optimize myadd2 because technically these unused functions can be accessed by functions in other libs.</p> UART - From AVR to Linux to Logic Analyzer - /blog/uart-from-avr-to-linux-to-logic-analyzer/ + //localhost:9999/blog/uart-from-avr-to-linux-to-logic-analyzer/ Fri, 20 Sep 2019 18:33:07 -0700 - /blog/uart-from-avr-to-linux-to-logic-analyzer/ + //localhost:9999/blog/uart-from-avr-to-linux-to-logic-analyzer/ <h1 id="uart---from-avr-to-linux-to-logic-analyzer">UART - From AVR to Linux to Logic Analyzer</h1> <h1 id="introduction">Introduction</h1> <p>In this article, let&rsquo;s see how a program running on Atmega328PU microcontroller can communicate to external world using UART. In order to run through this exercise we need below equipment.</p> <ol> <li><a href="https://www.aliexpress.com/item/32973635527.html?spm=a2g0s.9042311.0.0.27424c4dOZJfJV">Atmega328PU Microcontroller</a></li> <li>Breadboard</li> <li><a href="https://www.aliexpress.com/item/32651814443.html?spm=a2g0s.9042311.0.0.27424c4dOZJfJV">AVR/USBASP programmer</a></li> <li><a href="https://www.amazon.com/gp/product/B00QT7LQ88/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&amp;psc=1">USB to TTL Adapater</a></li> <li><a href="https://www.aliexpress.com/item/33062091072.html?spm=a2g0s.9042311.0.0.27424c4dHus6xH">Logic Analyzer</a></li> <li><a href="https://www.aliexpress.com/item/33024255264.html?spm=a2g0s.9042311.0.0.65aa4c4dDiDkXx">Digital Oscilloscope</a></li> </ol> <h1 id="atmega328pu-pinout">Atmega328PU pinout</h1> <p>It is an 8-bit microcontroller(uC) with following pinout. All its digital pins are grouped in to 4 banks(PA/PB/PC/PD). <img src="Atmega328PUPinout.png" alt=""></p> What Does It Take To Write An Emulator In Java? - /blog/what-does-it-take-to-write-an-emulator-in-java/ + //localhost:9999/blog/what-does-it-take-to-write-an-emulator-in-java/ Wed, 10 Apr 2019 18:33:07 -0700 - /blog/what-does-it-take-to-write-an-emulator-in-java/ + //localhost:9999/blog/what-does-it-take-to-write-an-emulator-in-java/ <h1 id="introduction">Introduction</h1> <p>I am proud, This weekend I did some productive work. I was able to code Chip 8 emulator in Java over a night. I have always been fascinated by them and finally I was able to get the damn thing to work! For those of you who are not familiar with software emulator, It is a software which can emulate the functionality of other hardware or software components. Notable examples are video game emulators(<a href="https://en.wikipedia.org/wiki/DOSBox">Dosbox</a> ,<a href="https://en.wikipedia.org/wiki/List_of_video_game_emulators">NES Emulator</a>), general purpose software emulators(<a href="https://en.wikipedia.org/wiki/QEMU">QEmu</a>)</p> Setting User Mode Break Points From Kd Aka .process /i Vs .process /r /p - /blog/usermode-breakpoints-from-kd/ + //localhost:9999/blog/usermode-breakpoints-from-kd/ Sun, 10 Mar 2019 18:33:07 -0700 - /blog/usermode-breakpoints-from-kd/ + //localhost:9999/blog/usermode-breakpoints-from-kd/ <h1 id="introduction">Introduction</h1> <p>When performing KD(Kernel Debugging) in Windows with Windbg if you have to set a break point in a user mode process we should always use <strong>.process /i address; g; .reload /user</strong>. Lot of good content is written on the <a href="https://www.osronline.com/article.cfm%5Earticle=576.htm">internet</a> on this command, but nothing seemed to explain why this command should be used instead of the familiar <strong>.process /r /p address</strong>. I would like to shed some light on this. Before reading any further I would strongly encourage you to read about it from above link. In this article I assume some basic knowledge on how kernel debugging is done with Windbg. Also, I would like to start with the following question.</p> Signed/Unsigned Integer Arithmetic In C - /blog/signed-unsigned-integer-arithmetic-in-c/ + //localhost:9999/blog/signed-unsigned-integer-arithmetic-in-c/ Sun, 10 Feb 2019 18:33:07 -0700 - /blog/signed-unsigned-integer-arithmetic-in-c/ + //localhost:9999/blog/signed-unsigned-integer-arithmetic-in-c/ <h1 id="introduction">Introduction</h1> <p>This article is about understanding how integer conversions happen in C language. The C standard defines the integer conversion rules agnostic to any specific machine architecture. This also makes things more complicated for programmers to understand.</p> <p>First of all, Why do we need integer conversions at all? The answer is simple, we need to have single type for any given expression. Let&rsquo;s say we have an expression <em><expr1><op><expr2></em> when expr1 and expr2 are of different types, we want the resulting expression from this to have one single type.</p> Pdb Files: The Glue Between The Binary File And Source Code - /blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ + //localhost:9999/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ Thu, 10 Jan 2019 18:33:07 -0700 - /blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ + //localhost:9999/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ <h1 id="introduction">Introduction</h1> <p>Have you ever wondered how a debugger magically gets you to the correct pdb and correct sources when debugging an application? This article talks exactly that in the context of Windbg.</p> <p>As you might be aware of, PDB files(also called as symbol files) is the glue between your application binary and the source code. There are two key Environment variables which configures Windbg about where to look for symbols and sources. They are _NT_SYMBOL_PATH and _NT_SOURCE_PATH. The _NT_SYMBOL_PATH points to the directory containing your PDBs(also called as symbol files) or to a symbol server. _NT_SOURCE_PATH points to the directory of your sources or to a source server which indexes the soruce files. One important point to remember here is one or more source files make up one or more binary files. But each binary will have a single PDB unless the source code is modified. This is important because Windbg has to perform lot of book keeping to map binary symbols with their source locations.</p> PCI Express Basics 101 - /blog/pci-express-basics-101/ + //localhost:9999/blog/pci-express-basics-101/ Mon, 10 Dec 2018 18:33:07 -0700 - /blog/pci-express-basics-101/ + //localhost:9999/blog/pci-express-basics-101/ <h1 id="introduction">Introduction</h1> <p>PCI Express: It is a standard which comes in multiple generations and multiple lane configurations. PCI-E is in its 5th generation, but mostly the current shipping generation is 3rd generation also called as Gen 3. Mainly each generation improves upon the previous generation regarding the speed per lane supported by the protocol.</p> <p>Below is the table for each generation and lane speed For single-lane and 16-lane links, in each direction:</p> Lib Files 101 - /blog/lib-files-101/ + //localhost:9999/blog/lib-files-101/ Sat, 10 Nov 2018 18:33:07 -0700 - /blog/lib-files-101/ + //localhost:9999/blog/lib-files-101/ <h1 id="introduction">Introduction</h1> <p>During the compilation one of the crucial step after assembling is creating the Object files. The collection of these object files is called a lib file. We can create these .lib files through following visual studio project types</p> <ol> <li>Static Library</li> <li>Dynamic Linked Library</li> </ol> <p>The format of these .lib files is specified in &lsquo;Archive (Library) File Format.&rsquo; section of <a href="https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#archive-library-file-formatspecification">PE Format</a>. As per the spec, .lib is an archive of individual .obj files with some metadata. Multiple tools can be used to extract lib files. Visual Studio installation contains Lib.exe tool. Since .lib and .obj files follow Unix COFF format Unix binutil&rsquo;s &lsquo;ar&rsquo; tool can be used to extract it.</p> How Do Breakpoints Work In Debuggers? - /blog/how-do-breakpoints-work-in-debuggers/ + //localhost:9999/blog/how-do-breakpoints-work-in-debuggers/ Wed, 10 Oct 2018 18:33:07 -0700 - /blog/how-do-breakpoints-work-in-debuggers/ + //localhost:9999/blog/how-do-breakpoints-work-in-debuggers/ <h1 id="introduction">Introduction</h1> <p>It&rsquo;s been a while, I have got a chance to blog about low-level stuff. In this article, I am going to explain how breakpoints work in debuggers. I am assuming the reader is already familiar with what a breakpoint is? and how to set it in your debugger of choice. The goal of this post is to explain the interplay between Debugger, Debuggee, Operating System and the CPU.</p> <h1 id="breakpoints-theory">Breakpoints Theory</h1> <p>To get there, we have to ask ourselves What does it mean by debugging a program/process?. To keep it simple, It&rsquo;s the controlled execution of a program by other program. The devil is in the word controlled. Whenever you open a debugger and launch a program or attach to a running process, the OS and the CPU guarantees that any event (like dll loading or interrupts or exceptions etc) happening on behalf of debuggee process are notified to debugger process for it to take necessary action. The important thing to understand here is, it&rsquo;s the execution of debuggee which is causing the debugger to take actions on behalf of it, not the other way around. So there should be something in the debuggee&rsquo;s code that should cause CPU to do the heavy lifting. This is where CPU&rsquo;s breakpoint instruction comes in. Every x86/amd64 CPU provides a special instruction called breakpoint instruction Int 3 whose mnemonic is 0xCC. When a piece of code executes this instruction, the CPU triggers a breakpoint interrupt and notifies it to OS and asks it what needs to be done next. Now this event from OS gets propagated to debugger by pausing all the threads in the debuggee. Now it&rsquo;s up to debugger to handle it according to its will.</p> A Newbie's Introduction To Compilation Process And Reverse Engineering - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ Fri, 10 Aug 2018 18:33:07 -0700 - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ <h1 id="introduction">Introduction</h1> <p>Compilers are surely the complex programs of all times. Even today, writing a compiler with minimum set of tools is considered to be challenging. This tutorial scratches the surface of different compiler phases involved in translating a given source code to executable and also shows how this information is useful in context of reverse engineering.</p> <p><a href="https://en.wikipedia.org/wiki/GNU_Compiler_Collection">GNU compiler collection</a> provides an excellent set of tools for dissecting the compilation process and to understand the working of bits and bytes in the final executable. For this tutorial I am using the following tools and considers C language to illustrate the examples.</p> Libspng - C Language Case Study - /blog/c-case-studies/f/ + //localhost:9999/blog/c-case-studies/f/ Tue, 10 Jul 2018 18:33:07 -0700 - /blog/c-case-studies/f/ + //localhost:9999/blog/c-case-studies/f/ <h1 id="build-system">Build System</h1> <p>It uses meson build system to build the library</p> <h1 id="data-structures">Data Structures</h1> <p>It is not using any fancy data structures instead it relies on plain array of objects and uses the traditional realloc function to expand them.</p> <h1 id="miscellaneous">Miscellaneous</h1> <p>All variables are declared as when needed. This deviates from Linux source code. In Linux kernel, declarations are done only in the beginning of a new scope (either at the start of the function or start of a scope)</p> C Language Course Structure - /courses/c/ + //localhost:9999/courses/c/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/c/ + //localhost:9999/courses/c/ <h1 id="c">C</h1> <ul> <li>Some Fundamentals</li> <li>Compiling And Running Your First Program</li> <li>Variables, Data Types, And Arithmetic Expressions</li> <li>Program Looping</li> <li>Making Decisions</li> <li>Working With Arrays</li> <li>Working With Functions</li> <li>Working With Structures</li> <li>Character Strings</li> <li>Pointers</li> <li>Operations On Bits</li> <li>The Preprocessor</li> <li>Extending Data Types With The Enumerated Data Type, Type Definitions, And Data Type Conversions</li> <li>Working With Larger Programs</li> <li>Input And Output Operations In C</li> <li>Miscellaneous And Advanced Features</li> <li>Debugging Programs</li> <li>Object-Oriented Programming</li> <li>The Standard C Library</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/CBook/">C Programming Notes for Professionals</a></li> </ul> Git Presentation - Part 1 - /presentations/git-part-1/ + //localhost:9999/presentations/git-part-1/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/git-part-1/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d3d1b1ff"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d3d1b1ff"> <div class="pdf-loading" id="pdf-loading-d3d1b1ff"></div> </div> <div id="overlayText"> <a href="./Git-Part-1.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d3d1b1ff"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d3d1b1ff"> <button id="pdf-prev-d3d1b1ff">Previous</button> <button id="pdf-next-d3d1b1ff">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d3d1b1ff"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d3d1b1ff"></span> </span> <a class="pdf-source" id="pdf-source-d3d1b1ff" href="./Git-Part-1.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d3d1b1ff" href="./Git-Part-1.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-1.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d3d1b1ff'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d3d1b1ff"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d3d1b1ff'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d3d1b1ff').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d3d1b1ff').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d3d1b1ff').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d3d1b1ff').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/awc9PQ4_Zvc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> + //localhost:9999/presentations/git-part-1/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d3d1b1ff"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d3d1b1ff"> <div class="pdf-loading" id="pdf-loading-d3d1b1ff"></div> </div> <div id="overlayText"> <a href="./Git-Part-1.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d3d1b1ff"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d3d1b1ff"> <button id="pdf-prev-d3d1b1ff">Previous</button> <button id="pdf-next-d3d1b1ff">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d3d1b1ff"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d3d1b1ff"></span> </span> <a class="pdf-source" id="pdf-source-d3d1b1ff" href="./Git-Part-1.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d3d1b1ff" href="./Git-Part-1.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-1.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d3d1b1ff'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d3d1b1ff"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d3d1b1ff'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d3d1b1ff').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d3d1b1ff').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d3d1b1ff').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d3d1b1ff').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/awc9PQ4_Zvc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> Git Presentation - Part 2 - /presentations/git-part-2/ + //localhost:9999/presentations/git-part-2/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/git-part-2/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-0528fdfc"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-0528fdfc"> <div class="pdf-loading" id="pdf-loading-0528fdfc"></div> </div> <div id="overlayText"> <a href="./Git-Part-2.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-0528fdfc"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-0528fdfc"> <button id="pdf-prev-0528fdfc">Previous</button> <button id="pdf-next-0528fdfc">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-0528fdfc"></span> / <span class="pdf-pagecount" id="pdf-pagecount-0528fdfc"></span> </span> <a class="pdf-source" id="pdf-source-0528fdfc" href="./Git-Part-2.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-0528fdfc" href="./Git-Part-2.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-2.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-0528fdfc'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-0528fdfc"), loadingWrapper = document.getElementById('pdf-loadingWrapper-0528fdfc'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-0528fdfc').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-0528fdfc').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-0528fdfc').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-0528fdfc').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> + //localhost:9999/presentations/git-part-2/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-0528fdfc"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-0528fdfc"> <div class="pdf-loading" id="pdf-loading-0528fdfc"></div> </div> <div id="overlayText"> <a href="./Git-Part-2.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-0528fdfc"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-0528fdfc"> <button id="pdf-prev-0528fdfc">Previous</button> <button id="pdf-next-0528fdfc">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-0528fdfc"></span> / <span class="pdf-pagecount" id="pdf-pagecount-0528fdfc"></span> </span> <a class="pdf-source" id="pdf-source-0528fdfc" href="./Git-Part-2.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-0528fdfc" href="./Git-Part-2.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-2.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-0528fdfc'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-0528fdfc"), loadingWrapper = document.getElementById('pdf-loadingWrapper-0528fdfc'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-0528fdfc').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-0528fdfc').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-0528fdfc').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-0528fdfc').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> Git Presentation - Part 3 - /presentations/git-part-3/ + //localhost:9999/presentations/git-part-3/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/git-part-3/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-1e15d788"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-1e15d788"> <div class="pdf-loading" id="pdf-loading-1e15d788"></div> </div> <div id="overlayText"> <a href="./Git-Part-3.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-1e15d788"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-1e15d788"> <button id="pdf-prev-1e15d788">Previous</button> <button id="pdf-next-1e15d788">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-1e15d788"></span> / <span class="pdf-pagecount" id="pdf-pagecount-1e15d788"></span> </span> <a class="pdf-source" id="pdf-source-1e15d788" href="./Git-Part-3.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-1e15d788" href="./Git-Part-3.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-3.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-1e15d788'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-1e15d788"), loadingWrapper = document.getElementById('pdf-loadingWrapper-1e15d788'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-1e15d788').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-1e15d788').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-1e15d788').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-1e15d788').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> + //localhost:9999/presentations/git-part-3/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-1e15d788"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-1e15d788"> <div class="pdf-loading" id="pdf-loading-1e15d788"></div> </div> <div id="overlayText"> <a href="./Git-Part-3.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-1e15d788"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-1e15d788"> <button id="pdf-prev-1e15d788">Previous</button> <button id="pdf-next-1e15d788">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-1e15d788"></span> / <span class="pdf-pagecount" id="pdf-pagecount-1e15d788"></span> </span> <a class="pdf-source" id="pdf-source-1e15d788" href="./Git-Part-3.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-1e15d788" href="./Git-Part-3.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-3.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-1e15d788'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-1e15d788"), loadingWrapper = document.getElementById('pdf-loadingWrapper-1e15d788'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-1e15d788').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-1e15d788').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-1e15d788').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-1e15d788').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> Java Course Structure - /courses/java/ + //localhost:9999/courses/java/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/java/ + //localhost:9999/courses/java/ <h1 id="java">Java</h1> <h2 id="the-java-language">The Java Language</h2> <ul> <li>The History and Evolution of Java</li> <li>An Overview of Java</li> <li>Data Types, Variables, and Arrays</li> <li>Operators</li> <li>Control Statements</li> <li>Introducing Classes</li> <li>A Closer Look at Methods and Classes</li> <li>Inheritance</li> <li>Packages and Interfaces</li> <li>Exception Handling</li> <li>Multithreaded Programming</li> <li>Enumerations, Autoboxing, and Annotations</li> <li>I/O, Try-with-Resources, and Other Topics</li> <li>Generics</li> <li>Lambda Expressions</li> <li>Modules</li> <li>Switch Expressions, Records, and Other Recently Added Features</li> </ul> <h2 id="the-java-library">The Java Library</h2> <ul> <li>String Handling</li> <li>Exploring java.lang</li> <li>java.util Part 1: The Collections Framework</li> <li>java.util Part 2: More Utility Classes</li> <li>Input/Output: Exploring java.io</li> <li>Exploring NIO</li> <li>Networking</li> <li>Event Handling</li> <li>Images</li> <li>The Concurrency Utilities</li> <li>The Stream API</li> <li>Regular Expressions and Other Packages</li> </ul> <h2 id="introducing-gui-programming-with-swing">Introducing GUI Programming With Swing</h2> <ul> <li>Introducing Swing</li> <li>Exploring Swing</li> <li>Introducing Swing Menus</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/JavaBook/">Java Notes for Professionals</a></li> </ul> Linux Course Structure - /courses/linux/ + //localhost:9999/courses/linux/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/linux/ + //localhost:9999/courses/linux/ <h1 id="linux">Linux</h1> <h2 id="learning-the-shell">Learning The Shell</h2> <ul> <li>What Is The Shell</li> <li>Navigation</li> <li>Exploring The System</li> <li>Manipulating Files And Directories</li> <li>Working With Commands</li> <li>Redirection</li> <li>Seeing The World As The Shell Sees It</li> <li>Advanced Keyboard Tricks</li> <li>Permissions</li> <li>Processes</li> </ul> <h2 id="configuration-and-the-environment">Configuration And The Environment</h2> <ul> <li>The Environment</li> <li>A Gentle Introduction To Vi</li> <li>Customizing The Prompt</li> </ul> <h2 id="common-tasks-and-essential-tools">Common Tasks And Essential Tools</h2> <ul> <li>Package Management</li> <li>Storage Media</li> <li>Networking</li> <li>Searching For Files</li> <li>Archiving And Backup</li> <li>Regular Expressions</li> <li>Text Processing</li> <li>Formatting Output</li> <li>Printing</li> <li>Compiling Programs</li> </ul> <h2 id="writing-shell-scripts">Writing Shell Scripts</h2> <ul> <li>Writing Your First Script</li> <li>Starting A Project</li> <li>Top Down Design</li> <li>Flow Control Branching With If</li> <li>Reading Keyboard Input</li> <li>Flow Control Looping With While Until</li> <li>Troubleshooting</li> <li>Flow Control Branching With Case</li> <li>Positional Parameters</li> <li>Flow Control Looping With For</li> <li>Strings And Numbers</li> <li>Arrays</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/LinuxBook/">Linux Commands Notes for Professionals</a></li> </ul> Python Course Structure - /courses/python/ + //localhost:9999/courses/python/ Mon, 01 Jan 0001 00:00:00 +0000 - /courses/python/ + //localhost:9999/courses/python/ <h1 id="python">Python</h1> <h2 id="getting-started">Getting Started</h2> <ul> <li>A Python Q&amp;A Session</li> <li>How Python Runs Programs</li> <li>How You Run Programs</li> </ul> <h2 id="types-and-operations">Types And Operations</h2> <ul> <li>Introducing Python Object Types</li> <li>Numeric Types</li> <li>The Dynamic Typing Interlude</li> <li>String Fundamentals</li> <li>Lists And Dictionaries</li> <li>Tuples, Files, And Everything Else</li> </ul> <h2 id="statements-and-syntax">Statements And Syntax</h2> <ul> <li>Introducing Python Statements</li> <li>Assignments, Expressions, And Prints</li> <li>If Tests And Syntax Rules</li> <li>While And For Loops</li> <li>Iterations And Comprehensions</li> <li>The Documentation Interlude</li> </ul> <h2 id="functions-and-generators">Functions And Generators</h2> <ul> <li>Function Basics</li> <li>Scopes</li> <li>Arguments</li> <li>Advanced Function Topics</li> <li>Comprehensions And Generations</li> <li>The Benchmarking Interlude</li> </ul> <h2 id="modules-and-packages">Modules And Packages</h2> <ul> <li>Modules: The Big Picture</li> <li>Module Coding Basics</li> <li>Module Packages</li> <li>Advanced Module Topics</li> </ul> <h2 id="classes-and-oop">Classes And OOP</h2> <ul> <li>OOP: The Big Picture</li> <li>Class Coding Basics</li> <li>A More Realistic Example</li> <li>Class Coding Details</li> <li>Operator Overloading</li> <li>Designing With Classes</li> <li>Advanced Class Topics</li> </ul> <h2 id="exceptions-and-tools">Exceptions And Tools</h2> <ul> <li>Exception Basics</li> <li>Exception Coding Details</li> <li>Exception Objects</li> <li>Designing With Exceptions</li> </ul> <h2 id="advanced-topics">Advanced Topics</h2> <ul> <li>Unicode And Byte Strings</li> <li>Managed Attributes</li> </ul> <h1 id="resources">Resources</h1> <ul> <li><a href="https://goalkicker.com/PythonBook/">Python Notes for Professionals</a></li> </ul> Visual Studio Code - /presentations/vscode/ + //localhost:9999/presentations/vscode/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/vscode/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d58c8836"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d58c8836"> <div class="pdf-loading" id="pdf-loading-d58c8836"></div> </div> <div id="overlayText"> <a href="./VSCode.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d58c8836"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d58c8836"> <button id="pdf-prev-d58c8836">Previous</button> <button id="pdf-next-d58c8836">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d58c8836"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d58c8836"></span> </span> <a class="pdf-source" id="pdf-source-d58c8836" href="./VSCode.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d58c8836" href="./VSCode.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/VSCode.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d58c8836'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d58c8836"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d58c8836'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d58c8836').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d58c8836').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d58c8836').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d58c8836').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/NZ5YXnLB8MI?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> + //localhost:9999/presentations/vscode/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d58c8836"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d58c8836"> <div class="pdf-loading" id="pdf-loading-d58c8836"></div> </div> <div id="overlayText"> <a href="./VSCode.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d58c8836"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d58c8836"> <button id="pdf-prev-d58c8836">Previous</button> <button id="pdf-next-d58c8836">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d58c8836"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d58c8836"></span> </span> <a class="pdf-source" id="pdf-source-d58c8836" href="./VSCode.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d58c8836" href="./VSCode.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/VSCode.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d58c8836'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d58c8836"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d58c8836'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d58c8836').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d58c8836').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d58c8836').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d58c8836').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/NZ5YXnLB8MI?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> diff --git a/docs/presentations/git-part-1/index.html b/docs/presentations/git-part-1/index.html index f27b99e..bda5b12 100644 --- a/docs/presentations/git-part-1/index.html +++ b/docs/presentations/git-part-1/index.html @@ -1,6 +1,6 @@ - + Git Presentation - Part 1 | Vineel Kovvuri @@ -157,7 +157,7 @@

    Git Presentation - Part 1

    if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') - pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; + pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, diff --git a/docs/presentations/git-part-2/index.html b/docs/presentations/git-part-2/index.html index 74111a6..828f783 100644 --- a/docs/presentations/git-part-2/index.html +++ b/docs/presentations/git-part-2/index.html @@ -1,6 +1,6 @@ - + Git Presentation - Part 2 | Vineel Kovvuri @@ -157,7 +157,7 @@

    Git Presentation - Part 2

    if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') - pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; + pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, diff --git a/docs/presentations/git-part-3/index.html b/docs/presentations/git-part-3/index.html index 33bd9f5..756937f 100644 --- a/docs/presentations/git-part-3/index.html +++ b/docs/presentations/git-part-3/index.html @@ -1,6 +1,6 @@ - + Git Presentation - Part 3 | Vineel Kovvuri @@ -157,7 +157,7 @@

    Git Presentation - Part 3

    if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') - pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; + pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, diff --git a/docs/presentations/index.html b/docs/presentations/index.html index ce7d5a2..ee75009 100644 --- a/docs/presentations/index.html +++ b/docs/presentations/index.html @@ -1,6 +1,6 @@ - + Presentations | Vineel Kovvuri diff --git a/docs/presentations/index.xml b/docs/presentations/index.xml index b56f451..2eec6ca 100644 --- a/docs/presentations/index.xml +++ b/docs/presentations/index.xml @@ -2,38 +2,38 @@ Presentations on Vineel Kovvuri - /presentations/ + //localhost:9999/presentations/ Recent content in Presentations on Vineel Kovvuri Hugo en-us - + Git Presentation - Part 1 - /presentations/git-part-1/ + //localhost:9999/presentations/git-part-1/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/git-part-1/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d3d1b1ff"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d3d1b1ff"> <div class="pdf-loading" id="pdf-loading-d3d1b1ff"></div> </div> <div id="overlayText"> <a href="./Git-Part-1.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d3d1b1ff"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d3d1b1ff"> <button id="pdf-prev-d3d1b1ff">Previous</button> <button id="pdf-next-d3d1b1ff">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d3d1b1ff"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d3d1b1ff"></span> </span> <a class="pdf-source" id="pdf-source-d3d1b1ff" href="./Git-Part-1.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d3d1b1ff" href="./Git-Part-1.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-1.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d3d1b1ff'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d3d1b1ff"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d3d1b1ff'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d3d1b1ff').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d3d1b1ff').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d3d1b1ff').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d3d1b1ff').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/awc9PQ4_Zvc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> + //localhost:9999/presentations/git-part-1/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d3d1b1ff"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d3d1b1ff"> <div class="pdf-loading" id="pdf-loading-d3d1b1ff"></div> </div> <div id="overlayText"> <a href="./Git-Part-1.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d3d1b1ff"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d3d1b1ff"> <button id="pdf-prev-d3d1b1ff">Previous</button> <button id="pdf-next-d3d1b1ff">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d3d1b1ff"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d3d1b1ff"></span> </span> <a class="pdf-source" id="pdf-source-d3d1b1ff" href="./Git-Part-1.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d3d1b1ff" href="./Git-Part-1.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-1.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d3d1b1ff'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d3d1b1ff"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d3d1b1ff'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d3d1b1ff').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d3d1b1ff').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d3d1b1ff').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d3d1b1ff').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/awc9PQ4_Zvc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> Git Presentation - Part 2 - /presentations/git-part-2/ + //localhost:9999/presentations/git-part-2/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/git-part-2/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-0528fdfc"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-0528fdfc"> <div class="pdf-loading" id="pdf-loading-0528fdfc"></div> </div> <div id="overlayText"> <a href="./Git-Part-2.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-0528fdfc"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-0528fdfc"> <button id="pdf-prev-0528fdfc">Previous</button> <button id="pdf-next-0528fdfc">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-0528fdfc"></span> / <span class="pdf-pagecount" id="pdf-pagecount-0528fdfc"></span> </span> <a class="pdf-source" id="pdf-source-0528fdfc" href="./Git-Part-2.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-0528fdfc" href="./Git-Part-2.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-2.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-0528fdfc'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-0528fdfc"), loadingWrapper = document.getElementById('pdf-loadingWrapper-0528fdfc'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-0528fdfc').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-0528fdfc').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-0528fdfc').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-0528fdfc').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> + //localhost:9999/presentations/git-part-2/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-0528fdfc"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-0528fdfc"> <div class="pdf-loading" id="pdf-loading-0528fdfc"></div> </div> <div id="overlayText"> <a href="./Git-Part-2.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-0528fdfc"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-0528fdfc"> <button id="pdf-prev-0528fdfc">Previous</button> <button id="pdf-next-0528fdfc">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-0528fdfc"></span> / <span class="pdf-pagecount" id="pdf-pagecount-0528fdfc"></span> </span> <a class="pdf-source" id="pdf-source-0528fdfc" href="./Git-Part-2.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-0528fdfc" href="./Git-Part-2.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-2.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-0528fdfc'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-0528fdfc"), loadingWrapper = document.getElementById('pdf-loadingWrapper-0528fdfc'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-0528fdfc').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-0528fdfc').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-0528fdfc').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-0528fdfc').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> Git Presentation - Part 3 - /presentations/git-part-3/ + //localhost:9999/presentations/git-part-3/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/git-part-3/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-1e15d788"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-1e15d788"> <div class="pdf-loading" id="pdf-loading-1e15d788"></div> </div> <div id="overlayText"> <a href="./Git-Part-3.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-1e15d788"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-1e15d788"> <button id="pdf-prev-1e15d788">Previous</button> <button id="pdf-next-1e15d788">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-1e15d788"></span> / <span class="pdf-pagecount" id="pdf-pagecount-1e15d788"></span> </span> <a class="pdf-source" id="pdf-source-1e15d788" href="./Git-Part-3.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-1e15d788" href="./Git-Part-3.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-3.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-1e15d788'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-1e15d788"), loadingWrapper = document.getElementById('pdf-loadingWrapper-1e15d788'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-1e15d788').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-1e15d788').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-1e15d788').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-1e15d788').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> + //localhost:9999/presentations/git-part-3/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-1e15d788"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-1e15d788"> <div class="pdf-loading" id="pdf-loading-1e15d788"></div> </div> <div id="overlayText"> <a href="./Git-Part-3.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-1e15d788"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-1e15d788"> <button id="pdf-prev-1e15d788">Previous</button> <button id="pdf-next-1e15d788">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-1e15d788"></span> / <span class="pdf-pagecount" id="pdf-pagecount-1e15d788"></span> </span> <a class="pdf-source" id="pdf-source-1e15d788" href="./Git-Part-3.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-1e15d788" href="./Git-Part-3.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/Git-Part-3.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-1e15d788'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-1e15d788"), loadingWrapper = document.getElementById('pdf-loadingWrapper-1e15d788'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-1e15d788').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-1e15d788').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-1e15d788').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-1e15d788').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> Visual Studio Code - /presentations/vscode/ + //localhost:9999/presentations/vscode/ Mon, 01 Jan 0001 00:00:00 +0000 - /presentations/vscode/ - <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d58c8836"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d58c8836"> <div class="pdf-loading" id="pdf-loading-d58c8836"></div> </div> <div id="overlayText"> <a href="./VSCode.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d58c8836"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d58c8836"> <button id="pdf-prev-d58c8836">Previous</button> <button id="pdf-next-d58c8836">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d58c8836"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d58c8836"></span> </span> <a class="pdf-source" id="pdf-source-d58c8836" href="./VSCode.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d58c8836" href="./VSCode.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/VSCode.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d58c8836'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d58c8836"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d58c8836'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d58c8836').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d58c8836').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d58c8836').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d58c8836').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/NZ5YXnLB8MI?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> + //localhost:9999/presentations/vscode/ + <script type="text/javascript" src= '/js/pdf-js/build/pdf.js'></script> <style> #embed-pdf-container { position: relative; width: 100%; height: auto; min-height: 20vh; } .pdf-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } #the-canvas { border: 1px solid black; direction: ltr; width: 100%; height: auto; display: none; } .pdf-loadingWrapper { display: none; justify-content: center; align-items: center; width: 100%; height: 350px; } .pdf-loading { display: inline-block; width: 50px; height: 50px; border: 3px solid #d2d0d0;; border-radius: 50%; border-top-color: #383838; animation: spin 1s ease-in-out infinite; -webkit-animation: spin 1s ease-in-out infinite; } #overlayText { word-wrap: break-word; display: grid; justify-content: end; } #overlayText a { position: relative; top: 10px; right: 4px; color: #000; margin: auto; background-color: #eeeeee; padding: 0.3em 1em; border: solid 2px; border-radius: 12px; border-color: #00000030; text-decoration: none; } #overlayText svg { height: clamp(1em, 2vw, 1.4em); width: clamp(1em, 2vw, 1.4em); } @keyframes spin { to { -webkit-transform: rotate(360deg); } } @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); } } </style><div class="embed-pdf-container" id="embed-pdf-container-d58c8836"> <div class="pdf-loadingWrapper" id="pdf-loadingWrapper-d58c8836"> <div class="pdf-loading" id="pdf-loading-d58c8836"></div> </div> <div id="overlayText"> <a href="./VSCode.pdf" aria-label="Download" download> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /> </svg> </a> </div> <canvas class="pdf-canvas" id="pdf-canvas-d58c8836"></canvas> </div> <div class="pdf-paginator" id="pdf-paginator-d58c8836"> <button id="pdf-prev-d58c8836">Previous</button> <button id="pdf-next-d58c8836">Next</button> &nbsp; &nbsp; <span> <span class="pdf-pagenum" id="pdf-pagenum-d58c8836"></span> / <span class="pdf-pagecount" id="pdf-pagecount-d58c8836"></span> </span> <a class="pdf-source" id="pdf-source-d58c8836" href="./VSCode.pdf">[pdf]</a> </div> <noscript> View the PDF file <a class="pdf-source" id="pdf-source-noscript-d58c8836" href="./VSCode.pdf">here</a>. </noscript> <script type="text/javascript"> (function(){ var url = '.\/VSCode.pdf'; var hidePaginator = "" === "true"; var hideLoader = "" === "true"; var selectedPageNum = parseInt("") || 1; var pdfjsLib = window['pdfjs-dist/build/pdf']; if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, pageNum = selectedPageNum, pageRendering = false, pageNumPending = null, scale = 3, canvas = document.getElementById('pdf-canvas-d58c8836'), ctx = canvas.getContext('2d'), paginator = document.getElementById("pdf-paginator-d58c8836"), loadingWrapper = document.getElementById('pdf-loadingWrapper-d58c8836'); showPaginator(); showLoader(); function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function(page) { var viewport = page.getViewport({scale: scale}); canvas.height = viewport.height; canvas.width = viewport.width; var renderContext = { canvasContext: ctx, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { pageRendering = false; showContent(); if (pageNumPending !== null) { renderPage(pageNumPending); pageNumPending = null; } }); }); document.getElementById('pdf-pagenum-d58c8836').textContent = num; } function showContent() { loadingWrapper.style.display = 'none'; canvas.style.display = 'block'; } function showLoader() { if(hideLoader) return loadingWrapper.style.display = 'flex'; canvas.style.display = 'none'; } function showPaginator() { if(hidePaginator) return paginator.style.display = 'block'; } function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } document.getElementById('pdf-prev-d58c8836').addEventListener('click', onPrevPage); function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } document.getElementById('pdf-next-d58c8836').addEventListener('click', onNextPage); pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) { pdfDoc = pdfDoc_; var numPages = pdfDoc.numPages; document.getElementById('pdf-pagecount-d58c8836').textContent = numPages; if(pageNum > numPages) { pageNum = numPages } renderPage(pageNum); }); })(); </script> <hr> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/NZ5YXnLB8MI?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> diff --git a/docs/presentations/vscode/index.html b/docs/presentations/vscode/index.html index ced0e44..afb45a5 100644 --- a/docs/presentations/vscode/index.html +++ b/docs/presentations/vscode/index.html @@ -1,6 +1,6 @@ - + Visual Studio Code | Vineel Kovvuri @@ -157,7 +157,7 @@

    Visual Studio Code

    if (pdfjsLib.GlobalWorkerOptions.workerSrc == '') - pdfjsLib.GlobalWorkerOptions.workerSrc = "\/" + 'js/pdf-js/build/pdf.worker.js'; + pdfjsLib.GlobalWorkerOptions.workerSrc = "\/\/localhost:9999\/" + 'js/pdf-js/build/pdf.worker.js'; var pdfDoc = null, diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 8ed71e4..df3268b 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -2,97 +2,100 @@ - /blog/ - 2025-01-14T23:33:54+00:00 + //localhost:9999/blog/ + 2025-01-17T14:03:43+00:00 - / - 2025-01-14T23:33:54+00:00 + //localhost:9999/ + 2025-01-17T14:03:43+00:00 - /tags/rust/ - 2025-01-14T23:33:54+00:00 + //localhost:9999/tags/rust/ + 2025-01-17T14:03:43+00:00 - /blog/rust-from-vs-into-traits-part-2/ - 2025-01-14T23:33:54+00:00 + //localhost:9999/blog/rust-usage-of-cow/ + 2025-01-17T14:03:43+00:00 + + //localhost:9999/tags/ + 2025-01-17T14:03:43+00:00 - /tags/ + //localhost:9999/blog/rust-from-vs-into-traits-part-2/ 2025-01-14T23:33:54+00:00 - /blog/rust-aligned-vs-unaligned-memory-access/ + //localhost:9999/blog/rust-aligned-vs-unaligned-memory-access/ 2025-01-14T19:05:52+00:00 - /blog/rust-sharing-objects/ + //localhost:9999/blog/rust-sharing-objects/ 2025-01-07T00:17:07-07:00 - /blog/rust-from-vs-into-traits/ + //localhost:9999/blog/rust-from-vs-into-traits/ 2025-01-06T06:17:07-07:00 - /blog/compiler-internals/ + //localhost:9999/blog/compiler-internals/ 2019-11-01T18:33:07-07:00 - /tags/compilers/ + //localhost:9999/tags/compilers/ 2019-11-01T18:33:07-07:00 - /blog/uart-from-avr-to-linux-to-logic-analyzer/ + //localhost:9999/blog/uart-from-avr-to-linux-to-logic-analyzer/ 2019-09-20T18:33:07-07:00 - /blog/what-does-it-take-to-write-an-emulator-in-java/ + //localhost:9999/blog/what-does-it-take-to-write-an-emulator-in-java/ 2019-04-10T18:33:07-07:00 - /blog/usermode-breakpoints-from-kd/ + //localhost:9999/blog/usermode-breakpoints-from-kd/ 2019-03-10T18:33:07-07:00 - /blog/signed-unsigned-integer-arithmetic-in-c/ + //localhost:9999/blog/signed-unsigned-integer-arithmetic-in-c/ 2019-02-10T18:33:07-07:00 - /blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ + //localhost:9999/blog/pdb-files-the-glue-between-the-binary-file-and-source-code/ 2019-01-10T18:33:07-07:00 - /blog/pci-express-basics-101/ + //localhost:9999/blog/pci-express-basics-101/ 2018-12-10T18:33:07-07:00 - /blog/lib-files-101/ + //localhost:9999/blog/lib-files-101/ 2018-11-10T18:33:07-07:00 - /blog/how-do-breakpoints-work-in-debuggers/ + //localhost:9999/blog/how-do-breakpoints-work-in-debuggers/ 2018-10-10T18:33:07-07:00 - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ 2018-08-10T18:33:07-07:00 - /tags/asm/ + //localhost:9999/tags/asm/ 2018-08-10T18:33:07-07:00 - /tags/c/ + //localhost:9999/tags/c/ 2018-08-10T18:33:07-07:00 - /tags/reversing/ + //localhost:9999/tags/reversing/ 2018-08-10T18:33:07-07:00 - /blog/c-case-studies/f/ + //localhost:9999/blog/c-case-studies/f/ 2018-07-10T18:33:07-07:00 - /courses/c/ + //localhost:9999/courses/c/ - /categories/ + //localhost:9999/categories/ - /courses/ + //localhost:9999/courses/ - /presentations/git-part-1/ + //localhost:9999/presentations/git-part-1/ - /presentations/git-part-2/ + //localhost:9999/presentations/git-part-2/ - /presentations/git-part-3/ + //localhost:9999/presentations/git-part-3/ - /courses/java/ + //localhost:9999/courses/java/ - /courses/linux/ + //localhost:9999/courses/linux/ - /presentations/ + //localhost:9999/presentations/ - /courses/python/ + //localhost:9999/courses/python/ - /presentations/vscode/ + //localhost:9999/presentations/vscode/ - /vlog/ + //localhost:9999/vlog/ diff --git a/docs/tags/asm/index.html b/docs/tags/asm/index.html index f4d2bf9..b00a612 100644 --- a/docs/tags/asm/index.html +++ b/docs/tags/asm/index.html @@ -1,6 +1,6 @@ - + Asm | Vineel Kovvuri diff --git a/docs/tags/asm/index.xml b/docs/tags/asm/index.xml index 51a0521..6f92175 100644 --- a/docs/tags/asm/index.xml +++ b/docs/tags/asm/index.xml @@ -2,17 +2,17 @@ Asm on Vineel Kovvuri - /tags/asm/ + //localhost:9999/tags/asm/ Recent content in Asm on Vineel Kovvuri Hugo en-us Fri, 10 Aug 2018 18:33:07 -0700 - + A Newbie's Introduction To Compilation Process And Reverse Engineering - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ Fri, 10 Aug 2018 18:33:07 -0700 - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ <h1 id="introduction">Introduction</h1> <p>Compilers are surely the complex programs of all times. Even today, writing a compiler with minimum set of tools is considered to be challenging. This tutorial scratches the surface of different compiler phases involved in translating a given source code to executable and also shows how this information is useful in context of reverse engineering.</p> <p><a href="https://en.wikipedia.org/wiki/GNU_Compiler_Collection">GNU compiler collection</a> provides an excellent set of tools for dissecting the compilation process and to understand the working of bits and bytes in the final executable. For this tutorial I am using the following tools and considers C language to illustrate the examples.</p> diff --git a/docs/tags/c/index.html b/docs/tags/c/index.html index 9b01e95..f871ac4 100644 --- a/docs/tags/c/index.html +++ b/docs/tags/c/index.html @@ -1,6 +1,6 @@ - + C | Vineel Kovvuri diff --git a/docs/tags/c/index.xml b/docs/tags/c/index.xml index 462db20..1a323c9 100644 --- a/docs/tags/c/index.xml +++ b/docs/tags/c/index.xml @@ -2,24 +2,24 @@ C on Vineel Kovvuri - /tags/c/ + //localhost:9999/tags/c/ Recent content in C on Vineel Kovvuri Hugo en-us Fri, 10 Aug 2018 18:33:07 -0700 - + A Newbie's Introduction To Compilation Process And Reverse Engineering - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ Fri, 10 Aug 2018 18:33:07 -0700 - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ <h1 id="introduction">Introduction</h1> <p>Compilers are surely the complex programs of all times. Even today, writing a compiler with minimum set of tools is considered to be challenging. This tutorial scratches the surface of different compiler phases involved in translating a given source code to executable and also shows how this information is useful in context of reverse engineering.</p> <p><a href="https://en.wikipedia.org/wiki/GNU_Compiler_Collection">GNU compiler collection</a> provides an excellent set of tools for dissecting the compilation process and to understand the working of bits and bytes in the final executable. For this tutorial I am using the following tools and considers C language to illustrate the examples.</p> Libspng - C Language Case Study - /blog/c-case-studies/f/ + //localhost:9999/blog/c-case-studies/f/ Tue, 10 Jul 2018 18:33:07 -0700 - /blog/c-case-studies/f/ + //localhost:9999/blog/c-case-studies/f/ <h1 id="build-system">Build System</h1> <p>It uses meson build system to build the library</p> <h1 id="data-structures">Data Structures</h1> <p>It is not using any fancy data structures instead it relies on plain array of objects and uses the traditional realloc function to expand them.</p> <h1 id="miscellaneous">Miscellaneous</h1> <p>All variables are declared as when needed. This deviates from Linux source code. In Linux kernel, declarations are done only in the beginning of a new scope (either at the start of the function or start of a scope)</p> diff --git a/docs/tags/compilers/index.html b/docs/tags/compilers/index.html index fd2a400..40164e7 100644 --- a/docs/tags/compilers/index.html +++ b/docs/tags/compilers/index.html @@ -1,6 +1,6 @@ - + Compilers | Vineel Kovvuri diff --git a/docs/tags/compilers/index.xml b/docs/tags/compilers/index.xml index 3378751..8107f17 100644 --- a/docs/tags/compilers/index.xml +++ b/docs/tags/compilers/index.xml @@ -2,17 +2,17 @@ Compilers on Vineel Kovvuri - /tags/compilers/ + //localhost:9999/tags/compilers/ Recent content in Compilers on Vineel Kovvuri Hugo en-us Fri, 01 Nov 2019 18:33:07 -0700 - + Compiler Internals - /blog/compiler-internals/ + //localhost:9999/blog/compiler-internals/ Fri, 01 Nov 2019 18:33:07 -0700 - /blog/compiler-internals/ + //localhost:9999/blog/compiler-internals/ <h2 id="basics">Basics</h2> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#888">//a.c </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">myadd</span>() { </span></span><span style="display:flex;"><span> <span style="color:#888;font-weight:bold">int</span> sum = <span style="color:#00d;font-weight:bold">10</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">for</span> (<span style="color:#888;font-weight:bold">int</span> i = <span style="color:#00d;font-weight:bold">0</span>; i &lt; <span style="color:#00d;font-weight:bold">100</span>; i++) </span></span><span style="display:flex;"><span> sum += i; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> sum; </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">myadd2</span>() { </span></span><span style="display:flex;"><span> <span style="color:#888;font-weight:bold">int</span> sum = <span style="color:#00d;font-weight:bold">10</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">for</span> (<span style="color:#888;font-weight:bold">int</span> i = <span style="color:#00d;font-weight:bold">0</span>; i &lt; <span style="color:#00d;font-weight:bold">100</span>; i++) </span></span><span style="display:flex;"><span> sum += i*i; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> sum; </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#888;font-weight:bold">int</span> <span style="color:#06b;font-weight:bold">main</span>() { </span></span><span style="display:flex;"><span> <span style="color:#080;font-weight:bold">return</span> <span style="color:#06b;font-weight:bold">myadd</span>(); </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>&gt;cl /c a.c </span></span><span style="display:flex;"><span>&gt;link /dump /symbols a.obj </span></span><span style="display:flex;"><span><span style="color:#00d;font-weight:bold">008</span> <span style="color:#00d;font-weight:bold">00000000</span> SECT3 notype () External | myadd </span></span><span style="display:flex;"><span><span style="color:#00d;font-weight:bold">009</span> <span style="color:#00d;font-weight:bold">00000050</span> SECT3 notype () External | myadd2 </span></span><span style="display:flex;"><span>00A 000000A0 SECT3 notype () External | main </span></span></code></pre></div><p>The <strong>link /dump</strong> command dumps the symbols that are part of the obj file. The compiler cannot optimize myadd2 because technically these unused functions can be accessed by functions in other libs.</p> diff --git a/docs/tags/index.html b/docs/tags/index.html index 5991f37..932a2d5 100644 --- a/docs/tags/index.html +++ b/docs/tags/index.html @@ -1,6 +1,6 @@ - + Tags | Vineel Kovvuri @@ -48,7 +48,7 @@

    Tags

  • - Rust (4) + Rust (5)
  • diff --git a/docs/tags/index.xml b/docs/tags/index.xml index f955a44..2594c56 100644 --- a/docs/tags/index.xml +++ b/docs/tags/index.xml @@ -2,45 +2,45 @@ Tags on Vineel Kovvuri - /tags/ + //localhost:9999/tags/ Recent content in Tags on Vineel Kovvuri Hugo en-us - Tue, 14 Jan 2025 23:33:54 +0000 - + Fri, 17 Jan 2025 14:03:43 +0000 + Rust - /tags/rust/ - Tue, 14 Jan 2025 23:33:54 +0000 - /tags/rust/ + //localhost:9999/tags/rust/ + Fri, 17 Jan 2025 14:03:43 +0000 + //localhost:9999/tags/rust/ Compilers - /tags/compilers/ + //localhost:9999/tags/compilers/ Fri, 01 Nov 2019 18:33:07 -0700 - /tags/compilers/ + //localhost:9999/tags/compilers/ Asm - /tags/asm/ + //localhost:9999/tags/asm/ Fri, 10 Aug 2018 18:33:07 -0700 - /tags/asm/ + //localhost:9999/tags/asm/ C - /tags/c/ + //localhost:9999/tags/c/ Fri, 10 Aug 2018 18:33:07 -0700 - /tags/c/ + //localhost:9999/tags/c/ Reversing - /tags/reversing/ + //localhost:9999/tags/reversing/ Fri, 10 Aug 2018 18:33:07 -0700 - /tags/reversing/ + //localhost:9999/tags/reversing/ diff --git a/docs/tags/reversing/index.html b/docs/tags/reversing/index.html index 250e3d2..14c4394 100644 --- a/docs/tags/reversing/index.html +++ b/docs/tags/reversing/index.html @@ -1,6 +1,6 @@ - + Reversing | Vineel Kovvuri diff --git a/docs/tags/reversing/index.xml b/docs/tags/reversing/index.xml index 4b9046d..4a7f2f9 100644 --- a/docs/tags/reversing/index.xml +++ b/docs/tags/reversing/index.xml @@ -2,17 +2,17 @@ Reversing on Vineel Kovvuri - /tags/reversing/ + //localhost:9999/tags/reversing/ Recent content in Reversing on Vineel Kovvuri Hugo en-us Fri, 10 Aug 2018 18:33:07 -0700 - + A Newbie's Introduction To Compilation Process And Reverse Engineering - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ Fri, 10 Aug 2018 18:33:07 -0700 - /blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ + //localhost:9999/blog/a-newbies-introduction-to-compilation-process-and-reverse-engineering/ <h1 id="introduction">Introduction</h1> <p>Compilers are surely the complex programs of all times. Even today, writing a compiler with minimum set of tools is considered to be challenging. This tutorial scratches the surface of different compiler phases involved in translating a given source code to executable and also shows how this information is useful in context of reverse engineering.</p> <p><a href="https://en.wikipedia.org/wiki/GNU_Compiler_Collection">GNU compiler collection</a> provides an excellent set of tools for dissecting the compilation process and to understand the working of bits and bytes in the final executable. For this tutorial I am using the following tools and considers C language to illustrate the examples.</p> diff --git a/docs/tags/rust/index.html b/docs/tags/rust/index.html index 50d9ba2..5bcacd3 100644 --- a/docs/tags/rust/index.html +++ b/docs/tags/rust/index.html @@ -1,6 +1,6 @@ - + Rust | Vineel Kovvuri @@ -40,6 +40,11 @@

    Blog

    +
  • + 2025/01/17 + Rust: Usage of Cow(Clone on Write) +
  • +
  • 2025/01/14 Rust: From and Into trait - Part 2 diff --git a/docs/tags/rust/index.xml b/docs/tags/rust/index.xml index 85a9e64..447743a 100644 --- a/docs/tags/rust/index.xml +++ b/docs/tags/rust/index.xml @@ -2,38 +2,45 @@ Rust on Vineel Kovvuri - /tags/rust/ + //localhost:9999/tags/rust/ Recent content in Rust on Vineel Kovvuri Hugo en-us - Tue, 14 Jan 2025 23:33:54 +0000 - + Fri, 17 Jan 2025 14:03:43 +0000 + + + Rust: Usage of Cow(Clone on Write) + //localhost:9999/blog/rust-usage-of-cow/ + Fri, 17 Jan 2025 14:03:43 +0000 + //localhost:9999/blog/rust-usage-of-cow/ + <h2 id="rust-usage-of-cowclone-on-write">Rust: Usage of Cow(Clone on Write)</h2> <p>Today, After reading following blog post(<a href="https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/)">https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/)</a>, I finally understood the need for Cow in Rust. Below is my code sample with relevant comments.</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">use</span><span style="color:#bbb"> </span>std::borrow::Cow;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Clone, Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#038">String</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price: <span style="color:#888;font-weight:bold">u32</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">update_book_price</span>&lt;<span style="color:#369">&#39;a</span>&gt;(book: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">Book</span>,<span style="color:#bbb"> </span>price: <span style="color:#888;font-weight:bold">u32</span>)<span style="color:#bbb"> </span>-&gt; <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#369">&#39;a</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If the price matches, there&#39;s no need to create a new book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">if</span><span style="color:#bbb"> </span>book.price<span style="color:#bbb"> </span>==<span style="color:#bbb"> </span>price<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">return</span><span style="color:#bbb"> </span>Cow::Borrowed(book);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If the price does not match, create a new book (updating the title to </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// make it easy to distinguish the objects). </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>Cow::Owned(Book<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#b06;font-weight:bold">format</span>!(<span style="color:#d20;background-color:#fff0f0">&#34;{}-updated&#34;</span>,<span style="color:#bbb"> </span>book.name.clone()),<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>})<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>book<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>Book<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>name: <span style="color:#d20;background-color:#fff0f0">&#34;Rust programming&#34;</span>.to_string(),<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>price: <span style="color:#00d;font-weight:bold">100</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// CASE 1: Since there is no change in price, we get a `Cow` wrapped </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// borrowed version of the existing book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#038">&#39;_</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>update_book_price(&amp;book,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">100</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// The returned `Cow` object is always immutable. The following line will </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// not work even though we can access the object fields via the `Deref` </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// trait: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// updated_book.price = 200; </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming&#34;, price: 100 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If we ever need to own the above object (e.g., for modifying it), we can </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// call `into_owned()` on `Cow` to get a cloned version of the book. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// This cloned object will be mutable. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>updated_book.into_owned();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>updated_book.price<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">200</span>;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming&#34;, price: 200 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// ======================================== </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// CASE 2: Since the price has changed, we get a `Cow` wrapped owned version </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// of the book. This owned version is the object we created in the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `update_book_price()` method. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Cow</span>&lt;<span style="color:#038">&#39;_</span>,<span style="color:#bbb"> </span>Book&gt;<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>update_book_price(&amp;book,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">300</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Again, the returned object is immutable, so the following line will not </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// work: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// updated_book.price = 400; </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming-updated&#34;, price: 300 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// If we ever need to own this object (e.g., for modifying it), we can call </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `into_owned()` on `Cow` to get the owned object. Importantly, in this </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// case, `Cow` simply returns the already owned object instead of cloning </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// it. The returned object will be mutable. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>updated_book: <span style="color:#b06;font-weight:bold">Book</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>updated_book.into_owned();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>updated_book.price<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">400</span>;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>updated_book);<span style="color:#bbb"> </span><span style="color:#888">// Book { name: &#34;Rust programming-updated&#34;, price: 400 } </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 1: `Cow` allows us to defer cloning a borrowed object until it </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// is required for modification (ownership). When ownership is needed, `Cow` </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// provides the following behavior via `into_owned()`: </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// 1. `Cow` either calls `clone()` on the borrowed object. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// 2. Or, `Cow` directly returns the underlying owned object. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 2: With the help of `Cow` (Clone-On-Write), we can design </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// methods optimized to return the borrowed object wrapped inside `Cow`. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// This approach helps delay the cloning process. Specifically, the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `update_book_price()` method returns either a borrowed `Cow` or an owned </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `Cow`, catering to both cases. However, this flexibility is not always </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// necessary. Since every type `T` that `Cow` wraps requires </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// `#[derive(Clone)]`, `Cow` can decide when to clone the borrowed object </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// and when to return the underlying owned object directly, depending on the </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// need when `into_owned()` is called. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Reference: https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/ </span></span></span><span style="display:flex;"><span><span style="color:#888"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div> + Rust: From and Into trait - Part 2 - /blog/rust-from-vs-into-traits-part-2/ + //localhost:9999/blog/rust-from-vs-into-traits-part-2/ Tue, 14 Jan 2025 23:33:54 +0000 - /blog/rust-from-vs-into-traits-part-2/ + //localhost:9999/blog/rust-from-vs-into-traits-part-2/ <h2 id="rust-from-and-into-trait-usage">Rust: From and Into trait usage</h2> <p>Knowing how Rust&rsquo;s <code>From</code> and <code>Into</code> traits work is one part of the story, but being able to use them efficiently is another. In this code sample, we will explore how to define functions or methods that accept parameters which can be converted from and into the expected types.</p> <p>In this code, we have two functions, <code>increment()</code> and <code>increment2()</code>, and we will see how they work with the <code>From</code> trait implemented for the <code>Number</code> type.</p> Rust: Aligned vs Unaligned Memory Access - /blog/rust-aligned-vs-unaligned-memory-access/ + //localhost:9999/blog/rust-aligned-vs-unaligned-memory-access/ Tue, 14 Jan 2025 19:05:52 +0000 - /blog/rust-aligned-vs-unaligned-memory-access/ + //localhost:9999/blog/rust-aligned-vs-unaligned-memory-access/ <h2 id="rust-rust-aligned-vs-unaligned-memory-access">Rust: Rust Aligned vs Unaligned Memory Access</h2> <p>Unlike C, Rust enforces some rules when trying to access memory. Mainly it requires consideration to alignment of the data that we are trying to read. Below code will illustrate the details.</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data: [<span style="color:#888;font-weight:bold">u8</span>;<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">10</span>]<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>[<span style="color:#00d;font-weight:bold">0x11</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x22</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x33</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x44</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x55</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x66</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x77</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x88</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x99</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0xAA</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Alignment Tidbit: Alignment depends on the data type we are using. u8 has </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// an alignment of 1, so u8 values can be accessed at any address. In </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// contrast, u16 has an alignment of 2, so they can only be accessed at </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// addresses aligned by 2. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Case 1: unaligned u16 access from raw pointer. This will panic </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>)<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>;<span style="color:#bbb"> </span><span style="color:#888">// interpreting the underlying address as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>x<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>*ptr;<span style="color:#bbb"> </span><span style="color:#888">// This dereference will panic: misaligned pointer dereference: address must be a multiple of 0x2 but is 0x7ffdec94efcd </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;x: </span><span style="color:#33b;background-color:#fff0f0">{x}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Slices: Accessing elements through a slice will have the same alignment </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// as its underlying data. So this prevent unaligned access. Also we cannot </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpret a u8 array as a u16 slice unlike raw pointer access </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// Case 2: aligned u8 access from slice </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>slice<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;data[<span style="color:#00d;font-weight:bold">1</span>..<span style="color:#00d;font-weight:bold">2</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>value<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>slice[<span style="color:#00d;font-weight:bold">0</span>];<span style="color:#bbb"> </span><span style="color:#888">// This works </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;slice: </span><span style="color:#33b;background-color:#fff0f0">{value}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Case 3: unaligned u16 access from a slice using unsafe. This will panic </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr: *<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u8</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>unaligned_data_ptr: *<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u8</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// slice::from_raw_parts will panic as unaligned *const u8 is being </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpreted as *const u16 . </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>unaligned_slice<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>core::slice::from_raw_parts(data_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">usize</span>)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>value<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>slice[<span style="color:#00d;font-weight:bold">0</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;unaligned_slice: </span><span style="color:#33b;background-color:#fff0f0">{value}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 1: The takeaway here is that when interpreting *const u8 as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// or u32, we cannot simply cast *const u8 as *const u16 and dereference </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// that location and except u16. Instead, we can only access the *const u8 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// as two u8 values and then use bit math to combine those bytes to form a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// u16. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Takeaway 2: When creating an array of u8(with odd number of elements), </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// the address at which the array starts in memory need not be a power of 2. </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// Because u8&#39;s have an alignment of 1. If that is the case, and trying to </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// interpret data + 1 address location as u16 will not trigger a panic. Be </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#888">// aware of that! </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data: [<span style="color:#888;font-weight:bold">u8</span>;<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">5</span>]<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>[<span style="color:#00d;font-weight:bold">0x11</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x22</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x33</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x44</span>,<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">0x55</span>];<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>data_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data.as_ptr();<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>data_ptr.add(<span style="color:#00d;font-weight:bold">1</span>)<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#888;font-weight:bold">u16</span>;<span style="color:#bbb"> </span><span style="color:#888">// interpreting the underlying address as u16 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>x<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>*ptr;<span style="color:#bbb"> </span><span style="color:#888">// This dereference will NOT trigger a panic! </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{x}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div> Rust: Sharing a Single Object Across Multiple Owners - /blog/rust-sharing-objects/ + //localhost:9999/blog/rust-sharing-objects/ Tue, 07 Jan 2025 00:17:07 -0700 - /blog/rust-sharing-objects/ + //localhost:9999/blog/rust-sharing-objects/ <h2 id="rust-sharing-a-single-object-across-multiple-owners">Rust: Sharing a Single Object Across Multiple Owners</h2> <p>Today, I found an interesting way to share a single object(C) among multiple owners(A and B)</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">use</span><span style="color:#bbb"> </span>std::ffi::c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">A</span>&lt;<span style="color:#369">&#39;a</span>&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>C,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">B</span>&lt;<span style="color:#369">&#39;a</span>&gt;<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#369">&#39;a</span> <span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>C,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#888">// Common object C shared between object A and object B </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#c00;font-weight:bold">#[derive(Debug)]</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">struct</span> <span style="color:#b06;font-weight:bold">C</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>val: <span style="color:#888;font-weight:bold">u32</span>,<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">main</span>()<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// - Using stack objects </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;Object c shared b/w multiple stack based objects&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>C<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>val: <span style="color:#00d;font-weight:bold">100</span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>A<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>*(a_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>*(b_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>a_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>b_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">4000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from b </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// - Using heap objects </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;Object c shared b/w multiple heap based objects&#34;</span>);<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>C<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>val: <span style="color:#00d;font-weight:bold">100</span><span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>&amp;<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>common;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>A<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>a_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#038">Box</span>::into_raw(<span style="color:#038">Box</span>::new(a))<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>mut_ref: <span style="color:#080">&amp;</span><span style="color:#b06;font-weight:bold">mut</span><span style="color:#bbb"> </span>c<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>b_ptr<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#038">Box</span>::into_raw(<span style="color:#038">Box</span>::new(b))<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>c_void;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>a_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span><span style="color:#038">Box</span>::&lt;A&gt;::from_raw(a_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>A)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>b_obj<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">unsafe</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span><span style="color:#038">Box</span>::&lt;B&gt;::from_raw(b_ptr<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">as</span><span style="color:#bbb"> </span>*<span style="color:#080;font-weight:bold">mut</span><span style="color:#bbb"> </span>B)<span style="color:#bbb"> </span>};<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>a_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">2000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from a </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 2000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>b_obj.mut_ref.val<span style="color:#bbb"> </span>=<span style="color:#bbb"> </span><span style="color:#00d;font-weight:bold">4000</span>;<span style="color:#bbb"> </span><span style="color:#888">// mutate c from b </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>a_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>println!(<span style="color:#d20;background-color:#fff0f0">&#34;</span><span style="color:#33b;background-color:#fff0f0">{:?}</span><span style="color:#d20;background-color:#fff0f0">&#34;</span>,<span style="color:#bbb"> </span>b_obj.mut_ref.val);<span style="color:#bbb"> </span><span style="color:#888">// 4000 </span></span></span><span style="display:flex;"><span><span style="color:#888"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div><p>Got curious and asked ChatGPT below question:</p> Rust: From vs Into traits - /blog/rust-from-vs-into-traits/ + //localhost:9999/blog/rust-from-vs-into-traits/ Mon, 06 Jan 2025 06:17:07 -0700 - /blog/rust-from-vs-into-traits/ + //localhost:9999/blog/rust-from-vs-into-traits/ <h2 id="why-does-implementing-fromt-on-u-enable-calling-tinto-to-get-u">Why does implementing <code>From&lt;T&gt;</code> on <code>U</code> enable calling <code>T.into()</code> to get <code>U</code>?</h2> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">impl</span><span style="color:#bbb"> </span><span style="color:#038">From</span>&lt;A&gt;<span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">for</span><span style="color:#bbb"> </span>B<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#080;font-weight:bold">fn</span> <span style="color:#06b;font-weight:bold">from</span>(a: <span style="color:#b06;font-weight:bold">A</span>)<span style="color:#bbb"> </span>-&gt; <span style="color:#b06;font-weight:bold">B</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#888">// Convert A to B </span></span></span><span style="display:flex;"><span><span style="color:#888"></span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span>}<span style="color:#bbb"> </span></span></span></code></pre></div><p>By implementing the <code>from()</code> static method on <code>B</code>, you can convert an instance of <code>A</code> to <code>B</code>:</p> <div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>a: <span style="color:#b06;font-weight:bold">A</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>...;<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#080;font-weight:bold">let</span><span style="color:#bbb"> </span>b: <span style="color:#b06;font-weight:bold">B</span><span style="color:#bbb"> </span>=<span style="color:#bbb"> </span>B::from(a);<span style="color:#bbb"> </span><span style="color:#888">// This works </span></span></span></code></pre></div><p>However, in practice, we often avoid using this directly, as it isn&rsquo;t considered idiomatic Rust. Instead, we do the following:</p> diff --git a/docs/vlog/index.html b/docs/vlog/index.html index d43d7fd..d942e0a 100644 --- a/docs/vlog/index.html +++ b/docs/vlog/index.html @@ -1,6 +1,6 @@ - + Vlog | Vineel Kovvuri diff --git a/docs/vlog/index.xml b/docs/vlog/index.xml index b785efe..8304e43 100644 --- a/docs/vlog/index.xml +++ b/docs/vlog/index.xml @@ -2,10 +2,10 @@ Vlog on Vineel Kovvuri - /vlog/ + //localhost:9999/vlog/ Recent content in Vlog on Vineel Kovvuri Hugo en-us - +