1 /* Copyright 2002-2022 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.gnss.metric.parser;
18
19 import org.hipparchus.util.FastMath;
20 import org.orekit.errors.OrekitException;
21 import org.orekit.errors.OrekitMessages;
22
23 /** Encoded messages as a sequence of bytes.
24 * @author Luc Maisonobe
25 * @since 11.0
26 */
27 public abstract class AbstractEncodedMessages implements EncodedMessage {
28
29 /** Current byte (as an int). */
30 private int current;
31
32 /** Remaining bits in current byte. */
33 private int remaining;
34
35 /** {@inheritDoc} */
36 @Override
37 public void start() {
38 this.remaining = 0;
39 }
40
41 /** Fetch the next byte from the message.
42 * @return next byte from the message, as a primitive integer,
43 * or -1 if end of data has been reached
44 */
45 protected abstract int fetchByte();
46
47 /** {@inheritDoc} */
48 @Override
49 public long extractBits(final int n) {
50
51 // safety check
52 if (n > 63) {
53 throw new OrekitException(OrekitMessages.TOO_LARGE_DATA_TYPE, n);
54 }
55
56 // initialization
57 long value = 0l;
58
59 // bits gathering loop
60 int needed = n;
61 while (needed > 0) {
62
63 if (remaining == 0) {
64 // we need to fetch one more byte
65 final int read = fetchByte();
66 if (read == -1) {
67 // end was unexpected
68 throw new OrekitException(OrekitMessages.END_OF_ENCODED_MESSAGE);
69 }
70 current = read & 0xFF;
71 remaining = 8;
72 }
73
74 final int nbBits = FastMath.min(remaining, needed);
75 value = (value << nbBits) | (current >>> (8 - nbBits));
76 current = (current << nbBits) & 0xFF;
77 remaining -= nbBits;
78 needed -= nbBits;
79
80 }
81
82 return value;
83
84 }
85
86 }