/*
 * 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.
 */

package org.apache.datasketches;

import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.UnsafeUtil;
import org.apache.datasketches.memory.WritableMemory;

/**
 * Methods of serializing and deserializing arrays of Long.
 *
 * @author Alexander Saydakov
 */
public class ArrayOfLongsSerDe extends ArrayOfItemsSerDe<Long> {

  @Override
  public byte[] serializeToByteArray(final Long[] items) {
    final byte[] bytes = new byte[Long.BYTES * items.length];
    final WritableMemory mem = WritableMemory.wrap(bytes);
    long offsetBytes = 0;
    for (int i = 0; i < items.length; i++) {
      mem.putLong(offsetBytes, items[i]);
      offsetBytes += Long.BYTES;
    }
    return bytes;
  }

  @Override
  public Long[] deserializeFromMemory(final Memory mem, final int length) {
    UnsafeUtil.checkBounds(0, (long)length * Long.BYTES, mem.getCapacity());
    final Long[] array = new Long[length];
    long offsetBytes = 0;
    for (int i = 0; i < length; i++) {
      array[i] = mem.getLong(offsetBytes);
      offsetBytes += Long.BYTES;
    }
    return array;
  }

}
