<?php
/**
 * 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
 *
 *     https://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.
 */

/**
 * @package Avro
 */

/**
 * Methods for handling 64-bit operations using the GMP extension.
 *
 * This is a naive and hackish implementation that is intended
 * to work well enough to support Avro. It has not been tested
 * beyond what's needed to decode and encode long values.
 *
 * @package Avro
 */
class AvroGMP {

  /**
   * @var resource memoized GMP resource for zero
   */
  private static $gmp_0;

  /**
   * @returns resource GMP resource for zero
   */
  private static function gmp_0()
  {
    if (!isset(self::$gmp_0))
      self::$gmp_0 = gmp_init('0');
    return self::$gmp_0;
  }

  /**
   * @var resource memoized GMP resource for one (1)
   */
  private static $gmp_1;

  /**
   * @returns resource GMP resource for one (1)
   */
  private static function gmp_1()
  {
    if (!isset(self::$gmp_1))
      self::$gmp_1 = gmp_init('1');
    return self::$gmp_1;
  }

  /**
   * @var resource memoized GMP resource for two (2)
   */
  private static $gmp_2;

  /**
   * @returns resource GMP resource for two (2)
   */
  private static function gmp_2()
  {
    if (!isset(self::$gmp_2))
      self::$gmp_2 = gmp_init('2');
    return self::$gmp_2;
  }

  /**
   * @var resource memoized GMP resource for 0x7f
   */
  private static $gmp_0x7f;

  /**
   * @returns resource GMP resource for 0x7f
   */
  private static function gmp_0x7f()
  {
    if (!isset(self::$gmp_0x7f))
      self::$gmp_0x7f = gmp_init('0x7f');
    return self::$gmp_0x7f;
  }

  /**
   * @var resource memoized GMP resource for 64-bit ~0x7f
   */
  private static $gmp_n0x7f;

  /**
   * @returns resource GMP resource for 64-bit ~0x7f
   */
  private static function gmp_n0x7f()
  {
    if (!isset(self::$gmp_n0x7f))
      self::$gmp_n0x7f = gmp_init('0xffffffffffffff80');
    return self::$gmp_n0x7f;
  }

  /**
   * @var resource memoized GMP resource for 64-bits of 1
   */
  private static $gmp_0xfs;

  /**
   * @returns resource GMP resource for 64-bits of 1
   */
  private static function gmp_0xfs()
  {
    if (!isset(self::$gmp_0xfs))
      self::$gmp_0xfs = gmp_init('0xffffffffffffffff');
    return self::$gmp_0xfs;
  }

  /**
   * @param GMP resource
   * @returns GMP resource 64-bit two's complement of input.
   */
  static function gmp_twos_complement($g)
  {
    return gmp_neg(gmp_sub(gmp_pow(self::gmp_2(), 64), $g));
  }

  /**
   * @interal Only works up to shift 63 (doesn't wrap bits around).
   * @param resource|int|string $g
   * @param int $shift number of bits to shift left
   * @returns resource $g shifted left
   */
  static function shift_left($g, $shift)
  {
    if (0 == $shift)
      return $g;

    if (0 > gmp_sign($g))
      $g = self::gmp_twos_complement($g);

    $m = gmp_mul($g, gmp_pow(self::gmp_2(), $shift));
    $m = gmp_and($m, self::gmp_0xfs());
    if (gmp_testbit($m, 63))
      $m = gmp_neg(gmp_add(gmp_and(gmp_com($m), self::gmp_0xfs()),
                           self::gmp_1()));
    return $m;
  }

  /**
   * Arithmetic right shift
   * @param resource|int|string $g
   * @param int $shift number of bits to shift right
   * @returns resource $g shifted right $shift bits
   */
  static function shift_right($g, $shift)
  {
    if (0 == $shift)
      return $g;

    if (0 <= gmp_sign($g))
      $m = gmp_div($g, gmp_pow(self::gmp_2(), $shift));
    else // negative
    {
      $g = gmp_and($g, self::gmp_0xfs());
      $m = gmp_div($g, gmp_pow(self::gmp_2(), $shift));
      $m = gmp_and($m, self::gmp_0xfs());
      for ($i = 63; $i >= (63 - $shift); $i--)
        gmp_setbit($m, $i);

      $m = gmp_neg(gmp_add(gmp_and(gmp_com($m), self::gmp_0xfs()),
                           self::gmp_1()));
    }

    return $m;
  }

  /**
   * @param int|str $n integer (or string representation of integer) to encode
   * @return string $bytes of the long $n encoded per the Avro spec
   */
  static function encode_long($n)
  {
    $g = gmp_init($n);
    $g = gmp_xor(self::shift_left($g, 1),
                 self::shift_right($g, 63));
    $bytes = '';
    while (0 != gmp_cmp(self::gmp_0(), gmp_and($g, self::gmp_n0x7f())))
    {
      $bytes .= chr(gmp_intval(gmp_and($g, self::gmp_0x7f())) | 0x80);
      $g = self::shift_right($g, 7);
    }
    $bytes .= chr(gmp_intval($g));
    return $bytes;
  }

  /**
   * @param int[] $bytes array of ascii codes of bytes to decode
   * @return string represenation of decoded long.
   */
  static function decode_long_from_array($bytes)
  {
    $b = array_shift($bytes);
    $g = gmp_init($b & 0x7f);
    $shift = 7;
    while (0 != ($b & 0x80))
    {
      $b = array_shift($bytes);
      $g = gmp_or($g, self::shift_left(($b & 0x7f), $shift));
      $shift += 7;
    }
    $val = gmp_xor(self::shift_right($g, 1), gmp_neg(gmp_and($g, 1)));
    return gmp_strval($val);
  }

}
