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
047 @Override
048 public String toString() {
049 return "Funnels.byteArrayFunnel()";
050 }
051 }
052
053 /**
054 * Returns a funnel that extracts the characters from a {@code CharSequence}.
055 */
056 public static Funnel<CharSequence> stringFunnel() {
057 return StringFunnel.INSTANCE;
058 }
059
060 private enum StringFunnel implements Funnel<CharSequence> {
061 INSTANCE;
062
063 public void funnel(CharSequence from, PrimitiveSink into) {
064 into.putString(from);
065 }
066
067
068 @Override
069 public String toString() {
070 return "Funnels.stringFunnel()";
071 }
072 }
073
074 /**
075 * Returns a funnel for integers.
076 *
077 * @since 13.0
078 */
079 public static Funnel<Integer> integerFunnel() {
080 return IntegerFunnel.INSTANCE;
081 }
082
083 private enum IntegerFunnel implements Funnel<Integer> {
084 INSTANCE;
085
086 public void funnel(Integer from, PrimitiveSink into) {
087 into.putInt(from);
088 }
089
090 @Override
091 public String toString() {
092 return "Funnels.integerFunnel()";
093 }
094 }
095
096 /**
097 * Returns a funnel for longs.
098 *
099 * @since 13.0
100 */
101 public static Funnel<Long> longFunnel() {
102 return LongFunnel.INSTANCE;
103 }
104
105 private enum LongFunnel implements Funnel<Long> {
106 INSTANCE;
107
108 public void funnel(Long from, PrimitiveSink into) {
109 into.putLong(from);
110 }
111
112 @Override
113 public String toString() {
114 return "Funnels.longFunnel()";
115 }
116 }
117
118 /**
119 * Wraps a {@code PrimitiveSink} as an {@link OutputStream}, so it is easy to
120 * {@link Funnel#funnel funnel} an object to a {@code PrimitiveSink}
121 * if there is already a way to write the contents of the object to an {@code OutputStream}.
122 *
123 * <p>The {@code close} and {@code flush} methods of the returned {@code OutputStream}
124 * do nothing, and no method throws {@code IOException}.
125 *
126 * @since 13.0
127 */
128 public static OutputStream asOutputStream(PrimitiveSink sink) {
129 return new SinkAsStream(sink);
130 }
131
132 private static class SinkAsStream extends OutputStream {
133 final PrimitiveSink sink;
134 SinkAsStream(PrimitiveSink sink) {
135 this.sink = Preconditions.checkNotNull(sink);
136 }
137
138 @Override
139 public void write(int b) {
140 sink.putByte((byte) b);
141 }
142
143 @Override
144 public void write(byte[] bytes) {
145 sink.putBytes(bytes);
146 }
147
148 @Override
149 public void write(byte[] bytes, int off, int len) {
150 sink.putBytes(bytes, off, len);
151 }
152
153 @Override
154 public String toString() {
155 return "Funnels.asOutputStream(" + sink + ")";
156 }
157 }
158 }