AbstractEncodedMessages.java

  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. import org.hipparchus.util.FastMath;
  19. import org.orekit.errors.OrekitException;
  20. import org.orekit.errors.OrekitMessages;

  21. /** Encoded messages as a sequence of bytes.
  22.  * @author Luc Maisonobe
  23.  * @since 11.0
  24.  */
  25. public abstract class AbstractEncodedMessages implements EncodedMessage {

  26.     /** Current byte (as an int). */
  27.     private int current;

  28.     /** Remaining bits in current byte. */
  29.     private int remaining;

  30.     /** {@inheritDoc} */
  31.     @Override
  32.     public void start() {
  33.         this.remaining  = 0;
  34.     }

  35.     /** Fetch the next byte from the message.
  36.      * @return next byte from the message, as a primitive integer,
  37.      * or -1 if end of data has been reached
  38.      */
  39.     protected abstract int fetchByte();

  40.     /** {@inheritDoc} */
  41.     @Override
  42.     public long extractBits(final int n) {

  43.         // safety check
  44.         if (n > 63) {
  45.             throw new OrekitException(OrekitMessages.TOO_LARGE_DATA_TYPE, n);
  46.         }

  47.         // initialization
  48.         long value = 0l;

  49.         // bits gathering loop
  50.         int needed = n;
  51.         while (needed > 0) {

  52.             if (remaining == 0) {
  53.                 // we need to fetch one more byte
  54.                 final int read = fetchByte();
  55.                 if (read == -1) {
  56.                     // end was unexpected
  57.                     throw new OrekitException(OrekitMessages.END_OF_ENCODED_MESSAGE);
  58.                 }
  59.                 current   = read & 0xFF;
  60.                 remaining = 8;
  61.             }

  62.             final int nbBits = FastMath.min(remaining, needed);
  63.             value      = (value << nbBits) | (current >>> (8 - nbBits));
  64.             current    = (current << nbBits) & 0xFF;
  65.             remaining -= nbBits;
  66.             needed    -= nbBits;

  67.         }

  68.         return value;

  69.     }

  70. }