001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.location;
020
021import java.io.*;
022
023import org.jppf.utils.streams.BoundedByteArrayOutputStream;
024
025/**
026 * Wrapper fro manipulating a block of data in memory.
027 * This implementation of the {@link Location} interface allows writing to and reading from a <code>byte</code> array.
028 * @author Laurent Cohen
029 */
030public class MemoryLocation extends AbstractLocation<byte[]> {
031  /**
032   * Explicit serialVersionUID.
033   */
034  private static final long serialVersionUID = 1L;
035  /**
036   * Start offset in the byte array.
037   */
038  private int offset = 0;
039  /**
040   * Length of data to handle.
041   */
042  private int len = -1;
043
044  /**
045   * Initialize this location and create a buffer of the specified size.
046   * The size is cast to an {@code int} value before the internal buffer is initialized.
047   * @param size the size of the buffer handled by this memory location.
048   */
049  public MemoryLocation(final long size) {
050    this(new byte[(int) size], 0, (int) size);
051  }
052
053  /**
054   * Initialize this location with the specified buffer.
055   * @param buffer an array of bytes.
056   */
057  public MemoryLocation(final byte[] buffer) {
058    this(buffer, 0, buffer.length);
059  }
060
061  /**
062   * Initialize this location with the specified byte array.
063   * @param buffer an array of bytes.
064   * @param offset the start position in the array of bytes.
065   * @param len the length of the buffer.
066   */
067  public MemoryLocation(final byte[] buffer, final int offset, final int len) {
068    super(buffer);
069    this.offset = offset;
070    this.len = len;
071  }
072
073  @Override
074  public InputStream getInputStream() throws Exception {
075    return new ByteArrayInputStream(path, offset, len);
076  }
077
078  @Override
079  public OutputStream getOutputStream() throws Exception {
080    return new BoundedByteArrayOutputStream(path, offset, len);
081  }
082
083  /**
084   * Get the size of the data this location points to.
085   * @return the size as a long value, or -1 if the file does not exist.
086   */
087  @Override
088  public long size() {
089    return len;
090  }
091
092  /**
093   * Get the content at this location as an array of bytes. This method is
094   * overridden from {@link AbstractLocation#toByteArray() AbstractLocation.toByteArray()} for improved performance.
095   * @return a byte array with a length equals to this location's size and starting at the offset specified in the constructor, if any.
096   */
097  @Override
098  public byte[] toByteArray() {
099    if ((offset == 0) && (len == path.length)) return path;
100    final byte[] buf = new byte[len];
101    System.arraycopy(path, offset, buf, 0, len);
102    return buf;
103  }
104}