1 22 package org.xsocket.stream; 23 24 import java.io.IOException ; 25 import java.nio.BufferUnderflowException ; 26 import java.nio.ByteBuffer ; 27 import java.util.LinkedList ; 28 29 30 36 final class ByteBufferParser { 37 38 39 48 public Index find(LinkedList <ByteBuffer > bufferQueue, byte[] delimiter) { 49 return find(bufferQueue, new Index(delimiter)); 50 } 51 52 53 62 public Index find(LinkedList <ByteBuffer > bufferQueue, Index index) { 63 64 int queueSize = bufferQueue.size(); 65 66 for (int bufNr = index.scannedBuffers; (bufNr <queueSize) && (!index.hasDelimiterFound); bufNr++) { 68 69 ByteBuffer buffer = bufferQueue.get(bufNr); 71 72 int savedPos = buffer.position(); 74 int savedLimit = buffer.limit(); 75 76 int contentLength = savedLimit - savedPos; 77 78 bufferLoop: for (int pos = savedPos; ((pos < contentLength) && !index.hasDelimiterFound); pos++) { 80 81 byte b = buffer.get(pos); 82 index.readBytes++; 83 84 if (index.delimiterPos > 0) { 86 if (b == index.delimiterBytes[index.delimiterPos]) { 87 if ((index.delimiterPos + 1) == index.delimiterLength) { 89 index.hasDelimiterFound = true; 90 break bufferLoop; 91 } 92 93 index.delimiterPos++; 95 continue; 96 97 } else { 99 index.delimiterPos = 0; 100 } 101 } 102 103 104 if (index.delimiterPos == 0) { 106 if (b == index.delimiterBytes[index.delimiterPos]) { 107 index.delimiterPos++; 109 110 if (index.delimiterLength == 1) { 112 index.hasDelimiterFound = true; 113 break bufferLoop; 114 } 115 } 116 } 117 } 119 index.scannedBuffers++; 120 121 122 buffer.position(savedPos); 124 buffer.limit(savedLimit); 125 } 126 127 return index; 128 } 129 130 131 132 141 public LinkedList <ByteBuffer > extract(LinkedList <ByteBuffer > inOutBuffer, int length) throws IOException , BufferUnderflowException { 142 143 LinkedList <ByteBuffer > result = new LinkedList <ByteBuffer >(); 144 145 int remainingToExtract = length; 146 ByteBuffer buffer = null; 147 148 do { 149 buffer = inOutBuffer.remove(); 151 if (buffer == null) { 152 throw new BufferUnderflowException (); 153 } 154 155 int bufLength = buffer.limit() - buffer.position(); 157 if (remainingToExtract >= bufLength) { 158 result.addLast(buffer); 160 remainingToExtract -= bufLength; 161 162 } else { 164 int savedLimit = buffer.limit(); 165 166 buffer.limit(buffer.position() + remainingToExtract); 168 ByteBuffer leftPart = buffer.slice(); 169 result.addLast(leftPart); 170 buffer.position(buffer.limit()); 171 buffer.limit(savedLimit); 172 ByteBuffer rightPart = buffer.slice(); 173 inOutBuffer.addFirst(rightPart); 174 break; 175 } 176 177 } while (remainingToExtract > 0); 178 179 return result; 180 } 181 182 183 184 193 public LinkedList <ByteBuffer > extract(LinkedList <ByteBuffer > inOutBuffer, Index index) throws IOException { 194 assert (index.isValid) : "Index is invalid"; 195 assert (index.hasDelimiterFound()); 196 197 LinkedList <ByteBuffer > result = extract(inOutBuffer, index.getReadBytes() - index.getDelimiterLength()); 199 200 extract(inOutBuffer, index.getDelimiterLength()); 202 203 return result; 204 } 205 206 207 208 209 213 public final static class Index { 214 public static final int NULL = -1; 215 216 private boolean isValid = true; 218 private boolean hasDelimiterFound = false; 219 220 221 private byte[] delimiterBytes = null; 223 private int delimiterLength = 0; 224 private int delimiterPos = 0; 225 226 227 private int scannedBuffers = 0; 229 private int readBytes = 0; 230 231 232 233 Index(byte[] delimiterBytes) { 234 this.delimiterBytes = delimiterBytes; 235 this.delimiterLength = delimiterBytes.length; 236 } 237 238 public boolean hasDelimiterFound() { 239 return hasDelimiterFound; 240 } 241 242 public int getReadBytes() { 243 return readBytes; 244 } 245 246 public boolean isDelimiterEquals(byte[] other) { 247 248 if (other.length != delimiterLength) { 249 return false; 250 } 251 252 for (int i = 0; i < delimiterLength; i++) { 253 if (other[i] != delimiterBytes[i]) { 254 return false; 255 } 256 } 257 258 return true; 259 } 260 261 262 int getDelimiterLength() { 263 return delimiterLength; 264 } 265 266 public int getDelimiterPos() { 267 return delimiterPos; 268 } 269 } 270 } | Popular Tags |