1 /* Copyright 2002-2021 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.orekit.errors.OrekitException;
20 import org.orekit.errors.OrekitMessages;
21
22 /** Encoded messages as a sequence of bytes.
23 * @author Luc Maisonobe
24 * @since 11.0
25 */
26 public abstract class AbstractEncodedMessages implements EncodedMessage {
27
28 /** Current byte (as an int). */
29 private int current;
30
31 /** Remaining bits in current byte. */
32 private int remaining;
33
34 /** {@inheritDoc} */
35 @Override
36 public void start() {
37 this.remaining = 0;
38 }
39
40 /** Fetch the next byte from the message.
41 * @return next byte from the message, as a primitive integer,
42 * or -1 if end of data has been reached
43 */
44 protected abstract int fetchByte();
45
46 /** {@inheritDoc} */
47 @Override
48 public long extractBits(final int n) {
49
50 // safety check
51 if (n > 63) {
52 throw new OrekitException(OrekitMessages.TOO_LARGE_DATA_TYPE, n);
53 }
54
55 // initialization
56 long value = 0l;
57
58 // bits gathering loop
59 int needed = n;
60 while (needed > 0) {
61
62 if (remaining == 0) {
63 // we need to fetch one more byte
64 final int read = fetchByte();
65 if (read == -1) {
66 // end was unexpected
67 throw new OrekitException(OrekitMessages.END_OF_ENCODED_MESSAGE);
68 }
69 current = read & 0xFF;
70 remaining = 8;
71 }
72
73 final int nbBits = Math.min(remaining, needed);
74 value = (value << nbBits) | (current >>> (8 - nbBits));
75 current = (current << nbBits) & 0xFF;
76 remaining -= nbBits;
77 needed -= nbBits;
78
79 }
80
81 return value;
82
83 }
84
85 }