1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.adservices.service.common.bhttp;
18 
19 import android.annotation.NonNull;
20 
21 /**
22  * Utility class read or write FRC 9000 variable length integer.
23  *
24  * @see <a href="https://datatracker.ietf.org/doc/html/rfc9000#name-variable-length-integer-enc">FRC
25  *     9000 Variable Length Integer</a>
26  */
27 public class Frc9000VariableLengthIntegerUtil {
28 
29     /** Returns the byte array represents the given integer. */
30     @NonNull
toFrc9000Int(long i)31     public static byte[] toFrc9000Int(long i) {
32         if ((i & 0xc000000000000000L) != 0) {
33             throw new IllegalArgumentException(
34                     "FRC 9000 can not represents larger then 0x4000000000000000L or negative"
35                             + " integer.");
36         }
37         if (i >= 0x40000000) {
38             return new byte[] {
39                 (byte) (0xc0 | (i >> 56)), // Replace first 2 bits as 0b11.
40                 (byte) (i >> 48),
41                 (byte) (i >> 40),
42                 (byte) (i >> 32),
43                 (byte) (i >> 24),
44                 (byte) (i >> 16),
45                 (byte) (i >> 8),
46                 (byte) i
47             };
48         }
49         if (i >= 0x00004000) {
50             return new byte[] {
51                 (byte) (0x80 | (i >> 24)), // Replace first 2 bits as 0b10.
52                 (byte) (i >> 16),
53                 (byte) (i >> 8),
54                 (byte) i
55             };
56         }
57         if (i >= 0x00000040) {
58             return new byte[] {
59                 (byte) (0x40 | (i >> 8)), // Replace first 2 bits as 0b01.
60                 (byte) i
61             };
62         }
63         return new byte[] {(byte) i};
64     }
65 }
66