1 // 2 // ======================================================================== 3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 4 // ------------------------------------------------------------------------ 5 // All rights reserved. This program and the accompanying materials 6 // are made available under the terms of the Eclipse Public License v1.0 7 // and Apache License v2.0 which accompanies this distribution. 8 // 9 // The Eclipse Public License is available at 10 // http://www.eclipse.org/legal/epl-v10.html 11 // 12 // The Apache License v2.0 is available at 13 // http://www.opensource.org/licenses/apache2.0.php 14 // 15 // You may elect to redistribute this code under either of these licenses. 16 // ======================================================================== 17 // 18 19 package org.eclipse.jetty.io; 20 21 import java.util.ArrayList; 22 import java.util.HashMap; 23 import java.util.Map.Entry; 24 25 import org.eclipse.jetty.util.StringMap; 26 27 /* ------------------------------------------------------------------------------- */ 28 /** 29 * Stores a collection of {@link Buffer} objects. 30 * Buffers are stored in an ordered collection and can retreived by index or value 31 * 32 */ 33 public class BufferCache 34 { 35 private final HashMap _bufferMap=new HashMap(); 36 private final StringMap _stringMap=new StringMap(StringMap.CASE_INSENSTIVE); 37 private final ArrayList _index= new ArrayList(); 38 39 /* ------------------------------------------------------------------------------- */ 40 /** Add a buffer to the cache at the specified index. 41 * @param value The content of the buffer. 42 */ add(String value, int ordinal)43 public CachedBuffer add(String value, int ordinal) 44 { 45 CachedBuffer buffer= new CachedBuffer(value, ordinal); 46 _bufferMap.put(buffer, buffer); 47 _stringMap.put(value, buffer); 48 while ((ordinal - _index.size()) >= 0) 49 _index.add(null); 50 if (_index.get(ordinal)==null) 51 _index.add(ordinal, buffer); 52 return buffer; 53 } 54 get(int ordinal)55 public CachedBuffer get(int ordinal) 56 { 57 if (ordinal < 0 || ordinal >= _index.size()) 58 return null; 59 return (CachedBuffer)_index.get(ordinal); 60 } 61 get(Buffer buffer)62 public CachedBuffer get(Buffer buffer) 63 { 64 return (CachedBuffer)_bufferMap.get(buffer); 65 } 66 get(String value)67 public CachedBuffer get(String value) 68 { 69 return (CachedBuffer)_stringMap.get(value); 70 } 71 lookup(Buffer buffer)72 public Buffer lookup(Buffer buffer) 73 { 74 if (buffer instanceof CachedBuffer) 75 return buffer; 76 77 Buffer b= get(buffer); 78 if (b == null) 79 { 80 if (buffer instanceof Buffer.CaseInsensitve) 81 return buffer; 82 return new ByteArrayBuffer.CaseInsensitive(buffer.asArray(),0,buffer.length(),Buffer.IMMUTABLE); 83 } 84 85 return b; 86 } 87 getBest(byte[] value, int offset, int maxLength)88 public CachedBuffer getBest(byte[] value, int offset, int maxLength) 89 { 90 Entry entry = _stringMap.getBestEntry(value, offset, maxLength); 91 if (entry!=null) 92 return (CachedBuffer)entry.getValue(); 93 return null; 94 } 95 lookup(String value)96 public Buffer lookup(String value) 97 { 98 Buffer b= get(value); 99 if (b == null) 100 { 101 return new CachedBuffer(value,-1); 102 } 103 return b; 104 } 105 toString(Buffer buffer)106 public String toString(Buffer buffer) 107 { 108 return lookup(buffer).toString(); 109 } 110 getOrdinal(String value)111 public int getOrdinal(String value) 112 { 113 CachedBuffer buffer = (CachedBuffer)_stringMap.get(value); 114 return buffer==null?-1:buffer.getOrdinal(); 115 } 116 getOrdinal(Buffer buffer)117 public int getOrdinal(Buffer buffer) 118 { 119 if (buffer instanceof CachedBuffer) 120 return ((CachedBuffer)buffer).getOrdinal(); 121 buffer=lookup(buffer); 122 if (buffer!=null && buffer instanceof CachedBuffer) 123 return ((CachedBuffer)buffer).getOrdinal(); 124 return -1; 125 } 126 127 public static class CachedBuffer extends ByteArrayBuffer.CaseInsensitive 128 { 129 private final int _ordinal; 130 private HashMap _associateMap=null; 131 CachedBuffer(String value, int ordinal)132 public CachedBuffer(String value, int ordinal) 133 { 134 super(value); 135 _ordinal= ordinal; 136 } 137 getOrdinal()138 public int getOrdinal() 139 { 140 return _ordinal; 141 } 142 getAssociate(Object key)143 public CachedBuffer getAssociate(Object key) 144 { 145 if (_associateMap==null) 146 return null; 147 return (CachedBuffer)_associateMap.get(key); 148 } 149 150 // TODO Replace Associate with a mime encoding specific solution setAssociate(Object key, CachedBuffer associate)151 public void setAssociate(Object key, CachedBuffer associate) 152 { 153 if (_associateMap==null) 154 _associateMap=new HashMap(); 155 _associateMap.put(key,associate); 156 } 157 } 158 159 160 @Override toString()161 public String toString() 162 { 163 return "CACHE["+ 164 "bufferMap="+_bufferMap+ 165 ",stringMap="+_stringMap+ 166 ",index="+_index+ 167 "]"; 168 } 169 } 170