/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "InputStream.h"
#include <algorithm>
#include "MemoryOutputStream.h"
#include "big_endian.h"

namespace rocketmq {
int64 InputStream::getNumBytesRemaining() {
  int64 len = getTotalLength();

  if (len >= 0)
    len -= getPosition();

  return len;
}

char InputStream::readByte() {
  char temp = 0;
  read(&temp, 1);
  return temp;
}

bool InputStream::readBool() {
  return readByte() != 0;
}

short InputStream::readShortBigEndian() {
  char temp[2];

  if (read(temp, 2) == 2) {
    short int v;
    ReadBigEndian(temp, &v);
    return v;
  }

  return 0;
}

int InputStream::readIntBigEndian() {
  char temp[4];

  if (read(temp, 4) == 4) {
    int v;
    ReadBigEndian(temp, &v);
    return v;
  }
  return 0;
}

int64 InputStream::readInt64BigEndian() {
  char asBytes[8];
  uint64 asInt64;

  if (read(asBytes, 8) == 8) {
    ReadBigEndian(asBytes, &asInt64);
    return asInt64;
  }
  return 0;
}

float InputStream::readFloatBigEndian() {
  union {
    int32 asInt;
    float asFloat;
  } n;
  n.asInt = (int32)readIntBigEndian();
  return n.asFloat;
}

double InputStream::readDoubleBigEndian() {
  union {
    int64 asInt;
    double asDouble;
  } n;
  n.asInt = readInt64BigEndian();
  return n.asDouble;
}

size_t InputStream::readIntoMemoryBlock(MemoryBlock& block, size_t numBytes) {
  MemoryOutputStream mo(block, true);
  return (size_t)mo.writeFromInputStream(*this, numBytes);
}

//==============================================================================
void InputStream::skipNextBytes(int64 numBytesToSkip) {
  if (numBytesToSkip > 0) {
    const int skipBufferSize = (int)std::min(numBytesToSkip, (int64)16384);
    char* temp = static_cast<char*>(std::malloc(skipBufferSize * sizeof(char)));

    while (numBytesToSkip > 0 && !isExhausted())
      numBytesToSkip -= read(temp, (int)std::min(numBytesToSkip, (int64)skipBufferSize));

    std::free(temp);
  }
}
}  // namespace rocketmq
