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