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
015package com.google.common.hash;
016
017import com.google.common.annotations.Beta;
018import com.google.common.base.Preconditions;
019
020import 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
029public 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}