Elijah
Elijah

Reputation: 13604

How does subtracting .as_ptr() values work?

Looking at a code snippet for parsing HTTP requests provided as part of the Tokio examples, I see the following code:

    let toslice = |a: &[u8]| {
        let start = a.as_ptr() as usize - src.as_ptr() as usize;
        assert!(start < src.len());
        (start, start + a.len())
    };

As I understand, the above code snippet it is getting the pointer location for the input vector a and the pointer location for a variable outside the scope of the closure and subtracting them. Then it returns a tuple containing this calculated value and the calculated value plus the length of the input vector.

What is this trying to accomplish? One could end up with a negative number and then panic because it wouldn't cast to usize. In fact, when I compile the example, this is exactly what happens when the input is the bytes for the string GET or POST, but not for other values. Is this a performance optimization for doing some sort of substring from a vector?

Upvotes: 0

Views: 82

Answers (1)

jw013
jw013

Reputation: 1808

Yes this is just subtracting pointers. The missing context is the closure clearly intends that a must be a subslice (substring) of the closed-over src slice. Thus toslice(a) ends up returning the start and end indices of a inside src. More explicitly, let (start, end) = toslice(a); means src[start] is a[0] (not just equal value, they are the same address), and src[end - 1] is the last byte of a.

Violating this context assumption will likely produce panics. That's fine because this closure is a local variable that is only used locally and not exposed to any unknown users, so the only calls to the closure are in the example you linked and they evidently all satisfy the constraint.

Upvotes: 3

Related Questions