fidl_codec/
util.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::error::{Error, Result};

const ENCODE_RECURSION_LIMIT: usize = 32;

/// How much to add to a size to pad it to a multiple of 8
pub(crate) fn alignment_padding_for_size(sz: usize) -> usize {
    // Saturating ops prevent an overflow. The result is probably wrong
    // afterward but if an object is about to overflow a usize we're probably
    // gonna fail soon. This just gives the more sophisticated code upstairs
    // time to notice.
    ((sz.saturating_add(7usize)) & !7usize).saturating_sub(sz)
}

/// Tag for a FIDL message to identify it as a request or a response.
pub(crate) enum Direction {
    Request,
    Response,
}

impl std::string::ToString for Direction {
    fn to_string(&self) -> String {
        match self {
            Direction::Request => "request",
            Direction::Response => "response",
        }
        .to_owned()
    }
}

/// Helper object for counting recursion level.
#[derive(Copy, Clone)]
pub(crate) struct RecursionCounter(usize);

impl RecursionCounter {
    /// Create a new recursion counter.
    pub fn new() -> Self {
        Self(0)
    }

    /// Create a new recursion counter from this one with one more level of
    /// recursion recorded. Duplicating the counter and keeping the old one
    /// around means you can "decrement" by just throwing away the new counter
    /// and going back to the old one. The resulting usage pattern is an
    /// RAII-style frame guard.
    pub fn next(&self) -> Result<Self> {
        if self.0 == ENCODE_RECURSION_LIMIT {
            Err(Error::RecursionLimitExceeded)
        } else {
            Ok(Self(self.0 + 1))
        }
    }
}