    001    /*
    002     * Copyright (C) 2011 The Guava Authors
    003     *
    004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
    005     * in compliance with the License. You may obtain a copy of the License at
    006     *
    007     * http://www.apache.org/licenses/LICENSE-2.0
    008     *
    009     * Unless required by applicable law or agreed to in writing, software distributed under the License
    010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
    011     * or implied. See the License for the specific language governing permissions and limitations under
    012     * the License.
    013     */
    014
    015    package com.google.common.hash;
    016
    017    import com.google.common.annotations.Beta;
    018    import com.google.common.base.Preconditions;
    019
    020    import java.io.OutputStream;
    021
    022    /**
    023     * Funnels for common types. All implementations are serializable.
    024     *
    025     * @author Dimitris Andreou
    026     * @since 11.0
    027     */
    028    @Beta
    029    public final class Funnels {
    030      private Funnels() {}
    031
    032      /**
    033       * Returns a funnel that extracts the bytes from a {@code byte} array.
    034       */
    035      public static Funnel<byte[]> byteArrayFunnel() {
    036        return ByteArrayFunnel.INSTANCE;
    037      }
    038
    039      private enum ByteArrayFunnel implements Funnel<byte[]> {
    040        INSTANCE;
    041
    042        public void funnel(byte[] from, PrimitiveSink into) {
    043          into.putBytes(from);
    044        }
    045
    046        @Override public String toString() {
    047          return "Funnels.byteArrayFunnel()";
    048        }
    049      }
    050
    051      /**
    052       * Returns a funnel that extracts the characters from a {@code CharSequence}.
    053       */
    054      public static Funnel<CharSequence> stringFunnel() {
    055        return StringFunnel.INSTANCE;
    056      }
    057
    058      private enum StringFunnel implements Funnel<CharSequence> {
    059        INSTANCE;
    060
    061        public void funnel(CharSequence from, PrimitiveSink into) {
    062          into.putString(from);
    063        }
    064
    065        @Override public String toString() {
    066          return "Funnels.stringFunnel()";
    067        }
    068      }
    069
    070      /**
    071       * Returns a funnel for integers.
    072       *
    073       * @since 13.0
    074       */
    075      public static Funnel<Integer> integerFunnel() {
    076        return IntegerFunnel.INSTANCE;
    077      }
    078
    079      private enum IntegerFunnel implements Funnel<Integer> {
    080        INSTANCE;
    081
    082        public void funnel(Integer from, PrimitiveSink into) {
    083          into.putInt(from);
    084        }
    085
    086        @Override public String toString() {
    087          return "Funnels.integerFunnel()";
    088        }
    089      }
    090
    091      /**
    092       * Returns a funnel for longs.
    093       *
    094       * @since 13.0
    095       */
    096      public static Funnel<Long> longFunnel() {
    097        return LongFunnel.INSTANCE;
    098      }
    099
    100      private enum LongFunnel implements Funnel<Long> {
    101        INSTANCE;
    102
    103        public void funnel(Long from, PrimitiveSink into) {
    104          into.putLong(from);
    105        }
    106
    107        @Override public String toString() {
    108          return "Funnels.longFunnel()";
    109        }
    110      }
    111
    112      /**
    113       * Wraps a {@code PrimitiveSink} as an {@link OutputStream}, so it is easy to
    114       * {@link Funnel#funnel funnel} an object to a {@code PrimitiveSink}
    115       * if there is already a way to write the contents of the object to an {@code OutputStream}.
    116       *
    117       * <p>The {@code close} and {@code flush} methods of the returned {@code OutputStream}
    118       * do nothing, and no method throws {@code IOException}.
    119       *
    120       * @since 13.0
    121       */
    122      public static OutputStream asOutputStream(PrimitiveSink sink) {
    123        return new SinkAsStream(sink);
    124      }
    125
    126      private static class SinkAsStream extends OutputStream {
    127        final PrimitiveSink sink;
    128        SinkAsStream(PrimitiveSink sink) {
    129          this.sink = Preconditions.checkNotNull(sink);
    130        }
    131
    132        @Override public void write(int b) {
    133          sink.putByte((byte) b);
    134        }
    135
    136        @Override public void write(byte[] bytes) {
    137          sink.putBytes(bytes);
    138        }
    139
    140        @Override public void write(byte[] bytes, int off, int len) {
    141          sink.putBytes(bytes, off, len);
    142        }
    143
    144        @Override public String toString() {
    145          return "Funnels.asOutputStream(" + sink + ")";
    146        }
    147      }
    148    }