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 }