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}