Java tutorial
/** * Copyright (c) 2010 Martin Geisse * * This file is distributed under the terms of the MIT license. */ package name.martingeisse.stackd.common.cubes; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import name.martingeisse.common.util.CompressionUtil; import name.martingeisse.stackd.common.StackdConstants; import name.martingeisse.stackd.common.geometry.ClusterSize; import org.apache.commons.lang3.ArrayUtils; /** * This type of cubes object stores a cube matrix directly. It is the * fallback data type if no other type works well. */ public class RawCubes extends Cubes { /** * the cubes */ private final byte[] cubes; /** * Constructor. */ private RawCubes(final byte[] cubes) { this.cubes = cubes; } /** * Getter method for the cubes. * @return the cubes */ public byte[] getCubes() { return cubes; } /* (non-Javadoc) * @see name.martingeisse.stackd.common.cubes.Cubes#compressToStreamInternal(name.martingeisse.stackd.common.geometry.ClusterSize, java.io.OutputStream) */ @Override protected void compressToStreamInternal(final ClusterSize clusterSize, final OutputStream stream) throws IOException { // TODO try uniform // write cubes stream.write(1); stream.write( CompressionUtil.deflate(cubes, StackdConstants.INTERACTIVE_SECTION_DATA_COMPRESSION_DICTIONARY)); } /** * Decompresses and deserializes an object of this type from the specified array, * skipping the first byte since it is assumed to contain the compression scheme. * * @param clusterSize the cluster size * @param compressedData the compressed data * @return the cubes object, or null if not successful */ public static RawCubes decompress(final ClusterSize clusterSize, final byte[] compressedData) { final byte[] deflatedCubes = ArrayUtils.subarray(compressedData, 1, compressedData.length); final byte[] cubes = CompressionUtil.inflate(deflatedCubes, StackdConstants.INTERACTIVE_SECTION_DATA_COMPRESSION_DICTIONARY); return new RawCubes(cubes); } /** * Builds an instance of this type from the specified cube data. * * @param cubes the cube data * @return the cubes object */ public static RawCubes build(final byte[] cubes) { return new RawCubes(cubes); } /** * Builds an instance of this type, filled uniformly with a single cube type. * @param clusterSize the cluster size * @param cubeType the cube type to fill the returned object with * @return the cubes object */ public static RawCubes buildUniform(final ClusterSize clusterSize, final byte cubeType) { final byte[] cubes = new byte[clusterSize.getCellCount()]; Arrays.fill(cubes, cubeType); return new RawCubes(cubes); } /* (non-Javadoc) * @see name.martingeisse.stackd.common.cubes.Cubes#getCubeTypeIndicesUsed() */ @Override public byte[] getCubeTypeIndicesUsed() { // build an array of flags that tell which cube types are used, as well // as the number of different cube types final boolean[] usedFlags = new boolean[256]; int usedCount = 0; for (int i = 0; i < cubes.length; i++) { final int cubeTypeIndex = (cubes[i] & 0xff); if (!usedFlags[cubeTypeIndex]) { usedFlags[cubeTypeIndex] = true; usedCount++; } } // build the result array final byte[] result = new byte[usedCount]; usedCount = 0; for (int i = 0; i < 256; i++) { if (usedFlags[i]) { result[usedCount] = (byte) i; usedCount++; } } return result; } /* (non-Javadoc) * @see name.martingeisse.stackd.common.cubes.Cubes#getCubeRelative(name.martingeisse.stackd.common.geometry.ClusterSize, int, int, int) */ @Override public byte getCubeRelative(final ClusterSize clusterSize, final int x, final int y, final int z) { return cubes[getRelativeCubeIndex(clusterSize, x, y, z)]; } /* (non-Javadoc) * @see name.martingeisse.stackd.common.cubes.Cubes#setCubeRelative(name.martingeisse.stackd.common.geometry.ClusterSize, int, int, int, byte) */ @Override public Cubes setCubeRelative(final ClusterSize clusterSize, final int x, final int y, final int z, final byte value) { cubes[getRelativeCubeIndex(clusterSize, x, y, z)] = value; return this; } /** * */ final int getRelativeCubeIndex(final ClusterSize clusterSize, final int x, final int y, final int z) { final int size = clusterSize.getSize(); if (x < 0 || y < 0 || z < 0 || x >= size || y >= size || z >= size) { throw new IndexOutOfBoundsException(); } return (x * size + y) * size + z; } /* (non-Javadoc) * @see name.martingeisse.stackd.common.cubes.Cubes#convertToRawCubes(name.martingeisse.stackd.common.geometry.ClusterSize) */ @Override public RawCubes convertToRawCubes(ClusterSize clusterSize) { return this; } /* (non-Javadoc) * @see name.martingeisse.stackd.common.cubes.Cubes#clone() */ @Override public RawCubes clone() { return new RawCubes(Arrays.copyOf(cubes, cubes.length)); } }