/** * GRANITE DATA SERVICES * Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S. * * This file is part of the Granite Data Services Platform. * * Granite Data Services is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Granite Data Services is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA, or see <http://www.gnu.org/licenses/>. */ package org.granite.messaging.jmf.codec.std.impl; import java.io.IOException; import java.io.OutputStream; import java.util.HashSet; import org.granite.messaging.jmf.CodecRegistry; import org.granite.messaging.jmf.DumpContext; import org.granite.messaging.jmf.InputContext; import org.granite.messaging.jmf.JMFEncodingException; import org.granite.messaging.jmf.OutputContext; import org.granite.messaging.jmf.codec.StandardCodec; import org.granite.messaging.jmf.codec.std.HashSetCodec; import org.granite.messaging.jmf.codec.std.impl.util.IntegerUtil; /** * @author Franck WOLFF */ public class HashSetCodecImpl extends AbstractStandardCodec<HashSet<?>> implements HashSetCodec { protected static final int INDEX_OR_LENGTH_BYTE_COUNT_OFFSET = 5; public int getObjectType() { return JMF_HASH_SET; } public Class<?> getObjectClass() { return HashSet.class; } public void encode(OutputContext ctx, HashSet<?> v) throws IOException { final OutputStream os = ctx.getOutputStream(); int indexOfStoredObject = ctx.indexOfObject(v); if (indexOfStoredObject >= 0) { int count = IntegerUtil.significantIntegerBytesCount0(indexOfStoredObject); os.write(0x80 | (count << INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) | JMF_HASH_SET); IntegerUtil.encodeInteger(ctx, indexOfStoredObject, count); } else { ctx.addToObjects(v); Object[] snapshot = v.toArray(); int count = IntegerUtil.significantIntegerBytesCount0(snapshot.length); os.write((count << INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) | JMF_HASH_SET); IntegerUtil.encodeInteger(ctx, snapshot.length, count); for (Object element : snapshot) ctx.writeObject(element); } } public HashSet<?> decode(InputContext ctx, int parameterizedJmfType) throws IOException, ClassNotFoundException { int indexOrLength = IntegerUtil.decodeInteger(ctx, (parameterizedJmfType >>> INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) & 0x03); if ((parameterizedJmfType & 0x80) != 0) return (HashSet<?>)ctx.getObject(indexOrLength); HashSet<Object> v = new HashSet<Object>(indexOrLength); ctx.addToObjects(v); for (int index = 0; index < indexOrLength; index++) v.add(ctx.readObject()); return v; } public void dump(DumpContext ctx, int parameterizedJmfType) throws IOException { final CodecRegistry codecRegistry = ctx.getSharedContext().getCodecRegistry(); int jmfType = codecRegistry.extractJmfType(parameterizedJmfType); if (jmfType != JMF_HASH_SET) throw newBadTypeJMFEncodingException(jmfType, parameterizedJmfType); int indexOrLength = IntegerUtil.decodeInteger(ctx, (parameterizedJmfType >>> INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) & 0x03); if ((parameterizedJmfType & 0x80) != 0) { String v = (String)ctx.getObject(indexOrLength); ctx.indentPrintLn("<" + v + "@" + indexOrLength + ">"); return; } String v = HashSet.class.getName() + "[" + indexOrLength + "]"; int indexOfStoredObject = ctx.addToObjects(v); ctx.indentPrintLn(v + "@" + indexOfStoredObject + " {"); ctx.incrIndent(1); for (int index = 0; index < indexOrLength; index++) { parameterizedJmfType = ctx.safeRead(); jmfType = codecRegistry.extractJmfType(parameterizedJmfType); StandardCodec<?> codec = codecRegistry.getCodec(jmfType); if (codec == null) throw new JMFEncodingException("No codec for JMF type: " + jmfType); codec.dump(ctx, parameterizedJmfType); } ctx.incrIndent(-1); ctx.indentPrintLn("}"); } }