001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package org.granite.messaging.jmf.codec.std.impl; 023 024import java.io.IOException; 025import java.io.OutputStream; 026import java.util.ArrayList; 027 028import org.granite.messaging.jmf.CodecRegistry; 029import org.granite.messaging.jmf.DumpContext; 030import org.granite.messaging.jmf.InputContext; 031import org.granite.messaging.jmf.JMFEncodingException; 032import org.granite.messaging.jmf.OutputContext; 033import org.granite.messaging.jmf.codec.StandardCodec; 034import org.granite.messaging.jmf.codec.std.ArrayListCodec; 035import org.granite.messaging.jmf.codec.std.impl.util.IntegerUtil; 036 037/** 038 * @author Franck WOLFF 039 */ 040public class ArrayListCodecImpl extends AbstractStandardCodec<ArrayList<?>> implements ArrayListCodec { 041 042 protected static final int INDEX_OR_LENGTH_BYTE_COUNT_OFFSET = 5; 043 044 public int getObjectType() { 045 return JMF_ARRAY_LIST; 046 } 047 048 public Class<?> getObjectClass() { 049 return ArrayList.class; 050 } 051 052 public void encode(OutputContext ctx, ArrayList<?> v) throws IOException { 053 final OutputStream os = ctx.getOutputStream(); 054 055 int indexOfStoredObject = ctx.indexOfObject(v); 056 if (indexOfStoredObject >= 0) { 057 int count = IntegerUtil.significantIntegerBytesCount0(indexOfStoredObject); 058 os.write(0x80 | (count << INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) | JMF_ARRAY_LIST); 059 IntegerUtil.encodeInteger(ctx, indexOfStoredObject, count); 060 } 061 else { 062 ctx.addToObjects(v); 063 064 Object[] snapshot = v.toArray(); 065 066 int count = IntegerUtil.significantIntegerBytesCount0(snapshot.length); 067 os.write((count << INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) | JMF_ARRAY_LIST); 068 IntegerUtil.encodeInteger(ctx, snapshot.length, count); 069 070 for (Object element : snapshot) 071 ctx.writeObject(element); 072 } 073 } 074 075 public ArrayList<?> decode(InputContext ctx, int parameterizedJmfType) throws IOException, ClassNotFoundException { 076 int indexOrLength = IntegerUtil.decodeInteger(ctx, (parameterizedJmfType >>> INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) & 0x03); 077 if ((parameterizedJmfType & 0x80) != 0) 078 return (ArrayList<?>)ctx.getObject(indexOrLength); 079 080 ArrayList<Object> v = new ArrayList<Object>(indexOrLength); 081 ctx.addToObjects(v); 082 083 for (int index = 0; index < indexOrLength; index++) 084 v.add(index, ctx.readObject()); 085 086 return v; 087 } 088 089 public void dump(DumpContext ctx, int parameterizedJmfType) throws IOException { 090 final CodecRegistry codecRegistry = ctx.getSharedContext().getCodecRegistry(); 091 092 int jmfType = codecRegistry.extractJmfType(parameterizedJmfType); 093 094 if (jmfType != JMF_ARRAY_LIST) 095 throw newBadTypeJMFEncodingException(jmfType, parameterizedJmfType); 096 097 int indexOrLength = IntegerUtil.decodeInteger(ctx, (parameterizedJmfType >>> INDEX_OR_LENGTH_BYTE_COUNT_OFFSET) & 0x03); 098 if ((parameterizedJmfType & 0x80) != 0) { 099 String v = (String)ctx.getObject(indexOrLength); 100 ctx.indentPrintLn("<" + v + "@" + indexOrLength + ">"); 101 return; 102 } 103 104 String v = ArrayList.class.getName() + "[" + indexOrLength + "]"; 105 int indexOfStoredObject = ctx.addToObjects(v); 106 ctx.indentPrintLn(v + "@" + indexOfStoredObject + " {"); 107 ctx.incrIndent(1); 108 109 for (int index = 0; index < indexOrLength; index++) { 110 parameterizedJmfType = ctx.safeRead(); 111 jmfType = codecRegistry.extractJmfType(parameterizedJmfType); 112 StandardCodec<?> codec = codecRegistry.getCodec(jmfType); 113 114 if (codec == null) 115 throw new JMFEncodingException("No codec for JMF type: " + jmfType); 116 117 codec.dump(ctx, parameterizedJmfType); 118 119 } 120 121 ctx.incrIndent(-1); 122 ctx.indentPrintLn("}"); 123 } 124}