public E take() throws InterruptedException { Node<E> x; final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; takeLock.lockInterruptibly(); try { try { while (count.get() == 0) notEmpty.await(); } catch (InterruptedException ie) { notEmpty.signal(); // propagate to a non-interrupted thread throw ie; } x = extract(); if (count.getAndDecrement() > 1) notEmpty.signal(); } finally { takeLock.unlock(); } E result = x.item; // temporary clearence x.item = null; x.next = null; return result; }
public E poll() { final AtomicInteger count = this.count; if (count.get() == 0) return null; Node<E> x = null; final ReentrantLock takeLock = this.takeLock; takeLock.lock(); try { if (count.get() > 0) { x = extract(); if (count.getAndDecrement() > 1) notEmpty.signal(); } } finally { takeLock.unlock(); } if (x != null) { E result = x.item; // temporary clearence x.item = null; x.next = null; return result; } return null; }
@Override public Object invoke(MethodInvocation invocation) throws Throwable { try { free.getAndIncrement(); return invocation.proceed(); } finally { free.getAndDecrement(); } }
public int allocateRequestId(@NotNull Channel channel) { int requestId = requestIdCounter.getAndIncrement(); if (requestId >= Short.MAX_VALUE) { requestIdCounter.set(0); requestId = requestIdCounter.getAndDecrement(); } requests.put(requestId, channel); return requestId; }
public byte[] readFully(InputStream st) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); int read; try { while (readLen.getAndDecrement() > 0 && (read = st.read()) != -1) { stream.write(read); } } catch (IOException e) { throw new RuntimeException(e); } return stream.toByteArray(); }
private synchronized void removeTaskAttempt(int volumeId, TaskAttempt taskAttempt) { if (!unassignedTaskForEachVolume.containsKey(volumeId)) return; LinkedHashSet<TaskAttempt> tasks = unassignedTaskForEachVolume.get(volumeId); if (tasks.remove(taskAttempt)) { remainTasksNum.getAndDecrement(); } if (tasks.isEmpty()) { unassignedTaskForEachVolume.remove(volumeId); if (volumeId > REMOTE) { diskVolumeLoads.remove(volumeId); } } }
public void run() { Session session; log.info(this + " using connection " + connection); try { session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(destination); while (true) { int remaining = remainingToSend.getAndDecrement(); if (remaining <= 0) { break; } // Message m = session.createTextMessage("test"); Message m = session.createTextMessage("test-" + System.currentTimeMillis()); producer.send(m); remaining--; if (remaining < 0) { remaining = 0; } if (sleepBetweenSendsMs > 0) { log.info( "sleeping " + (sleepBetweenSendsMs / 1000) + " second(s) after sending the message, " + remaining + " message(s) remaining ..."); Thread.sleep(sleepBetweenSendsMs); } messagesSent.incrementAndGet(); } } catch (Exception e) { log.info("thread " + Thread.currentThread().getName() + " failed: " + e); } finally { try { barrier.await(); } catch (Exception e) { log.info("failed to wait on barrier: " + e); } } }
public static GridView getGridView(boolean top) { GridView gridView = new GridView(); gridView.setViewId("viewId" + counter.getAndDecrement()); gridView.setTitle("请假单"); gridView.addCell(new PropCell("标题一", "值一")); RowCell rowCell = new RowCell(); rowCell.addPropCell(new PropCell("标题一", "值一")); rowCell.addPropCell(new PropCell("标题二", "值二")); gridView.addCell(rowCell); gridView.addCell(new PropCell("标题二", "值二")); IteratorCell iteratorCell = new IteratorCell(); ArrayList<PropCell> propCells = new ArrayList<PropCell>(); propCells.add(new PropCell("标题一", "值一")); propCells.add(new PropCell("标题二", "值二")); propCells.add(new PropCell("标题三", "值三")); iteratorCell.addPropCells(propCells); propCells = new ArrayList<PropCell>(); propCells.add(new PropCell("标题一", "值一")); propCells.add(new PropCell("标题二", "值二")); propCells.add(new PropCell("标题三", "值三")); iteratorCell.addPropCells(propCells); gridView.addCell(iteratorCell); if (top) { GridView gridView2 = getGridView(false); gridView2.setTitle("明细一"); gridView.addGridView(gridView2); gridView2 = getGridView(false); gridView2.setTitle("明细二"); gridView.addGridView(gridView2); } return gridView; }
public int prevStatementIndex(Class<?> clazz) { AtomicInteger atomic = statementIndexes.get(clazz); if (atomic == null) statementIndexes.put(clazz, atomic = new AtomicInteger()); return atomic.getAndDecrement(); }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof SpdyDataFrame) { /* * SPDY Data frame processing requirements: * * If an endpoint receives a data frame for a Stream-ID which is not open * and the endpoint has not sent a GOAWAY frame, it must issue a stream error * with the error code INVALID_STREAM for the Stream-ID. * * If an endpoint which created the stream receives a data frame before receiving * a SYN_REPLY on that stream, it is a protocol error, and the recipient must * issue a stream error with the getStatus code PROTOCOL_ERROR for the Stream-ID. * * If an endpoint receives multiple data frames for invalid Stream-IDs, * it may close the session. * * If an endpoint refuses a stream it must ignore any data frames for that stream. * * If an endpoint receives a data frame after the stream is half-closed from the * sender, it must send a RST_STREAM frame with the getStatus STREAM_ALREADY_CLOSED. * * If an endpoint receives a data frame after the stream is closed, it must send * a RST_STREAM frame with the getStatus PROTOCOL_ERROR. */ SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg; int streamId = spdyDataFrame.streamId(); int deltaWindowSize = -1 * spdyDataFrame.content().readableBytes(); int newSessionWindowSize = spdySession.updateReceiveWindowSize(SPDY_SESSION_STREAM_ID, deltaWindowSize); // Check if session window size is reduced beyond allowable lower bound if (newSessionWindowSize < 0) { issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR); return; } // Send a WINDOW_UPDATE frame if less than half the session window size remains if (newSessionWindowSize <= initialSessionReceiveWindowSize / 2) { int sessionDeltaWindowSize = initialSessionReceiveWindowSize - newSessionWindowSize; spdySession.updateReceiveWindowSize(SPDY_SESSION_STREAM_ID, sessionDeltaWindowSize); SpdyWindowUpdateFrame spdyWindowUpdateFrame = new DefaultSpdyWindowUpdateFrame(SPDY_SESSION_STREAM_ID, sessionDeltaWindowSize); ctx.writeAndFlush(spdyWindowUpdateFrame); } // Check if we received a data frame for a Stream-ID which is not open if (!spdySession.isActiveStream(streamId)) { spdyDataFrame.release(); if (streamId <= lastGoodStreamId) { issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR); } else if (!sentGoAwayFrame) { issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM); } return; } // Check if we received a data frame for a stream which is half-closed if (spdySession.isRemoteSideClosed(streamId)) { spdyDataFrame.release(); issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_ALREADY_CLOSED); return; } // Check if we received a data frame before receiving a SYN_REPLY if (!isRemoteInitiatedId(streamId) && !spdySession.hasReceivedReply(streamId)) { spdyDataFrame.release(); issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR); return; } /* * SPDY Data frame flow control processing requirements: * * Recipient should not send a WINDOW_UPDATE frame as it consumes the last data frame. */ // Update receive window size int newWindowSize = spdySession.updateReceiveWindowSize(streamId, deltaWindowSize); // Window size can become negative if we sent a SETTINGS frame that reduces the // size of the transfer window after the peer has written data frames. // The value is bounded by the length that SETTINGS frame decrease the window. // This difference is stored for the session when writing the SETTINGS frame // and is cleared once we send a WINDOW_UPDATE frame. if (newWindowSize < spdySession.getReceiveWindowSizeLowerBound(streamId)) { spdyDataFrame.release(); issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR); return; } // Window size became negative due to sender writing frame before receiving SETTINGS // Send data frames upstream in initialReceiveWindowSize chunks if (newWindowSize < 0) { while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) { SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame( streamId, spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain()); ctx.writeAndFlush(partialDataFrame); } } // Send a WINDOW_UPDATE frame if less than half the stream window size remains if (newWindowSize <= initialReceiveWindowSize / 2 && !spdyDataFrame.isLast()) { int streamDeltaWindowSize = initialReceiveWindowSize - newWindowSize; spdySession.updateReceiveWindowSize(streamId, streamDeltaWindowSize); SpdyWindowUpdateFrame spdyWindowUpdateFrame = new DefaultSpdyWindowUpdateFrame(streamId, streamDeltaWindowSize); ctx.writeAndFlush(spdyWindowUpdateFrame); } // Close the remote side of the stream if this is the last frame if (spdyDataFrame.isLast()) { halfCloseStream(streamId, true, ctx.newSucceededFuture()); } } else if (msg instanceof SpdySynStreamFrame) { /* * SPDY SYN_STREAM frame processing requirements: * * If an endpoint receives a SYN_STREAM with a Stream-ID that is less than * any previously received SYN_STREAM, it must issue a session error with * the getStatus PROTOCOL_ERROR. * * If an endpoint receives multiple SYN_STREAM frames with the same active * Stream-ID, it must issue a stream error with the getStatus code PROTOCOL_ERROR. * * The recipient can reject a stream by sending a stream error with the * getStatus code REFUSED_STREAM. */ SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg; int streamId = spdySynStreamFrame.streamId(); // Check if we received a valid SYN_STREAM frame if (spdySynStreamFrame.isInvalid() || !isRemoteInitiatedId(streamId) || spdySession.isActiveStream(streamId)) { issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR); return; } // Stream-IDs must be monotonically increasing if (streamId <= lastGoodStreamId) { issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR); return; } // Try to accept the stream byte priority = spdySynStreamFrame.priority(); boolean remoteSideClosed = spdySynStreamFrame.isLast(); boolean localSideClosed = spdySynStreamFrame.isUnidirectional(); if (!acceptStream(streamId, priority, remoteSideClosed, localSideClosed)) { issueStreamError(ctx, streamId, SpdyStreamStatus.REFUSED_STREAM); return; } } else if (msg instanceof SpdySynReplyFrame) { /* * SPDY SYN_REPLY frame processing requirements: * * If an endpoint receives multiple SYN_REPLY frames for the same active Stream-ID * it must issue a stream error with the getStatus code STREAM_IN_USE. */ SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg; int streamId = spdySynReplyFrame.streamId(); // Check if we received a valid SYN_REPLY frame if (spdySynReplyFrame.isInvalid() || isRemoteInitiatedId(streamId) || spdySession.isRemoteSideClosed(streamId)) { issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM); return; } // Check if we have received multiple frames for the same Stream-ID if (spdySession.hasReceivedReply(streamId)) { issueStreamError(ctx, streamId, SpdyStreamStatus.STREAM_IN_USE); return; } spdySession.receivedReply(streamId); // Close the remote side of the stream if this is the last frame if (spdySynReplyFrame.isLast()) { halfCloseStream(streamId, true, ctx.newSucceededFuture()); } } else if (msg instanceof SpdyRstStreamFrame) { /* * SPDY RST_STREAM frame processing requirements: * * After receiving a RST_STREAM on a stream, the receiver must not send * additional frames on that stream. * * An endpoint must not send a RST_STREAM in response to a RST_STREAM. */ SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg; removeStream(spdyRstStreamFrame.streamId(), ctx.newSucceededFuture()); } else if (msg instanceof SpdySettingsFrame) { SpdySettingsFrame spdySettingsFrame = (SpdySettingsFrame) msg; int settingsMinorVersion = spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_MINOR_VERSION); if (settingsMinorVersion >= 0 && settingsMinorVersion != minorVersion) { // Settings frame had the wrong minor version issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR); return; } int newConcurrentStreams = spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_MAX_CONCURRENT_STREAMS); if (newConcurrentStreams >= 0) { remoteConcurrentStreams = newConcurrentStreams; } // Persistence flag are inconsistent with the use of SETTINGS to communicate // the initial window size. Remove flags from the sender requesting that the // value be persisted. Remove values that the sender indicates are persisted. if (spdySettingsFrame.isPersisted(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE)) { spdySettingsFrame.removeValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE); } spdySettingsFrame.setPersistValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE, false); int newInitialWindowSize = spdySettingsFrame.getValue(SpdySettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE); if (newInitialWindowSize >= 0) { updateInitialSendWindowSize(newInitialWindowSize); } } else if (msg instanceof SpdyPingFrame) { /* * SPDY PING frame processing requirements: * * Receivers of a PING frame should send an identical frame to the sender * as soon as possible. * * Receivers of a PING frame must ignore frames that it did not initiate */ SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg; if (isRemoteInitiatedId(spdyPingFrame.id())) { ctx.writeAndFlush(spdyPingFrame); return; } // Note: only checks that there are outstanding pings since uniqueness is not enforced if (pings.get() == 0) { return; } pings.getAndDecrement(); } else if (msg instanceof SpdyGoAwayFrame) { receivedGoAwayFrame = true; } else if (msg instanceof SpdyHeadersFrame) { SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg; int streamId = spdyHeadersFrame.streamId(); // Check if we received a valid HEADERS frame if (spdyHeadersFrame.isInvalid()) { issueStreamError(ctx, streamId, SpdyStreamStatus.PROTOCOL_ERROR); return; } if (spdySession.isRemoteSideClosed(streamId)) { issueStreamError(ctx, streamId, SpdyStreamStatus.INVALID_STREAM); return; } // Close the remote side of the stream if this is the last frame if (spdyHeadersFrame.isLast()) { halfCloseStream(streamId, true, ctx.newSucceededFuture()); } } else if (msg instanceof SpdyWindowUpdateFrame) { /* * SPDY WINDOW_UPDATE frame processing requirements: * * Receivers of a WINDOW_UPDATE that cause the window size to exceed 2^31 * must send a RST_STREAM with the getStatus code FLOW_CONTROL_ERROR. * * Sender should ignore all WINDOW_UPDATE frames associated with a stream * after sending the last frame for the stream. */ SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg; int streamId = spdyWindowUpdateFrame.streamId(); int deltaWindowSize = spdyWindowUpdateFrame.deltaWindowSize(); // Ignore frames for half-closed streams if (streamId != SPDY_SESSION_STREAM_ID && spdySession.isLocalSideClosed(streamId)) { return; } // Check for numerical overflow if (spdySession.getSendWindowSize(streamId) > Integer.MAX_VALUE - deltaWindowSize) { if (streamId == SPDY_SESSION_STREAM_ID) { issueSessionError(ctx, SpdySessionStatus.PROTOCOL_ERROR); } else { issueStreamError(ctx, streamId, SpdyStreamStatus.FLOW_CONTROL_ERROR); } return; } updateSendWindowSize(ctx, streamId, deltaWindowSize); } ctx.fireChannelRead(msg); }
@Test public void testReadBlockedThenWriteBlockedThenReadableThenWritable() throws Exception { final AtomicInteger size = new AtomicInteger(1024 * 1024); final AtomicReference<Exception> failure = new AtomicReference<>(); final CountDownLatch latch1 = new CountDownLatch(1); final CountDownLatch latch2 = new CountDownLatch(1); final AtomicBoolean writeBlocked = new AtomicBoolean(); init( new Interested() { @Override public void onFillable(EndPoint endPoint, AbstractConnection connection) { ByteBuffer input = BufferUtil.allocate(2); int read = fill(endPoint, input); if (read == 1) { byte b = input.get(); if (b == 1) { connection.fillInterested(); ByteBuffer output = ByteBuffer.allocate(size.get()); endPoint.write(new Callback() {}, output); latch1.countDown(); } else { latch2.countDown(); } } else { failure.set(new Exception("Unexpectedly read " + read + " bytes")); } } @Override public void onIncompleteFlush() { writeBlocked.set(true); } private int fill(EndPoint endPoint, ByteBuffer buffer) { try { return endPoint.fill(buffer); } catch (IOException x) { failure.set(x); return 0; } } }); Socket client = new Socket(); client.connect(connector.getLocalAddress()); client.setSoTimeout(5000); SocketChannel server = connector.accept(); server.configureBlocking(false); selectorManager.accept(server); OutputStream clientOutput = client.getOutputStream(); clientOutput.write(1); clientOutput.flush(); Assert.assertTrue(latch1.await(5, TimeUnit.SECONDS)); // We do not read to keep the socket write blocked clientOutput.write(2); clientOutput.flush(); Assert.assertTrue(latch2.await(5, TimeUnit.SECONDS)); // Sleep before reading to allow waking up the server only for read Thread.sleep(1000); // Now read what was written, waking up the server for write InputStream clientInput = client.getInputStream(); while (size.getAndDecrement() > 0) clientInput.read(); client.close(); Assert.assertNull(failure.get()); }
/** * Subtract one from this reduction variable and return the previous value. * * @return Previous value. */ public int getAndDecrement() { return myValue.getAndDecrement(); }
/** 1. 将AtomicInteger中维护的int值减一, 再返回原来的值, 也就是 i = i--; */ public void testGetAndDecrement() { AtomicInteger ai = new AtomicInteger(); System.out.println(ai.getAndDecrement()); // 0 }
public HttpUrl pingDSM(ServerInfoJson infoJson) { // set timeout to 5 seconds final OkHttpClient client = defaultClient .newBuilder() .connectTimeout(5, TimeUnit.SECONDS) .readTimeout(5, TimeUnit.SECONDS) .build(); ServerJson serverJson = infoJson.server; if (serverJson == null) { throw new IllegalArgumentException("serverJson == null"); } ServiceJson serviceJson = infoJson.service; if (serviceJson == null) { throw new IllegalArgumentException("serviceJson == null"); } int port = serviceJson.port; int externalPort = serviceJson.ext_port; // internal address(192.168.x.x/10.x.x.x) ExecutorService executor = Executors.newFixedThreadPool(10); CompletionService<String> internalService = new ExecutorCompletionService<>(executor); List<InterfaceJson> ifaces = serverJson._interface; AtomicInteger internalCount = new AtomicInteger(0); if (ifaces != null) { for (final InterfaceJson iface : ifaces) { internalService.submit(createPingTask(client, iface.ip, port)); internalCount.incrementAndGet(); if (iface.ipv6 != null) { for (Ipv6Json ipv6 : iface.ipv6) { String ipv6Address = "[" + ipv6.address + "]"; internalService.submit(createPingTask(client, ipv6Address, port)); internalCount.incrementAndGet(); } } } } // host address(ddns/fqdn) ExecutorCompletionService<String> hostService = new ExecutorCompletionService<>(executor); AtomicInteger hostCount = new AtomicInteger(0); // ddns if (!Util.isEmpty(serverJson.ddns) && !serverJson.ddns.equals("NULL")) { hostService.submit(createPingTask(client, serverJson.ddns, port)); hostCount.incrementAndGet(); } // fqdn if (!Util.isEmpty(serverJson.fqdn) && !serverJson.fqdn.equals("NULL")) { hostService.submit(createPingTask(client, serverJson.fqdn, port)); hostCount.incrementAndGet(); } // external address(public ip address) ExecutorCompletionService<String> externalService = new ExecutorCompletionService<>(executor); AtomicInteger externalCount = new AtomicInteger(0); if (serverJson.external != null) { String ip = serverJson.external.ip; if (!Util.isEmpty(ip)) { externalService.submit( createPingTask(client, ip, (externalPort != 0) ? externalPort : port)); externalCount.incrementAndGet(); } String ipv6 = serverJson.external.ipv6; if (!Util.isEmpty(ipv6) && !ipv6.equals("::")) { externalService.submit( createPingTask(client, "[" + ipv6 + "]", (externalPort != 0) ? externalPort : port)); externalCount.incrementAndGet(); } } while (internalCount.getAndDecrement() > 0) { try { Future<String> future = internalService.take(); if (future != null) { String host = future.get(); if (!Util.isEmpty(host)) { return requestUrl.newBuilder().host(host).port(port).build(); } } } catch (InterruptedException | ExecutionException ignored) { } } while (hostCount.getAndDecrement() > 0) { try { Future<String> future = hostService.take(); if (future != null) { String host = future.get(); if (!Util.isEmpty(host)) { return requestUrl.newBuilder().host(host).port(port).build(); } } } catch (InterruptedException | ExecutionException ignored) { } } while (externalCount.getAndDecrement() > 0) { try { Future<String> future = externalService.take(); if (future != null) { String host = future.get(); if (!Util.isEmpty(host)) { return requestUrl.newBuilder().host(host).port(port).build(); } } } catch (InterruptedException | ExecutionException ignored) { // ignored.printStackTrace(); } } // shutdown executors executor.shutdownNow(); return null; }
/** getAndDecrement returns previous value and decrements */ public void testGetAndDecrement() { AtomicInteger ai = new AtomicInteger(1); assertEquals(1, ai.getAndDecrement()); assertEquals(0, ai.getAndDecrement()); assertEquals(-1, ai.getAndDecrement()); }
/** End a Backend API method that writes the database. */ private void writerEnd() { threadWriteCount.getAndDecrement(); threadTotalCount.getAndDecrement(); }
/** End a Backend API method that reads the database. */ private void readerEnd() { threadTotalCount.getAndDecrement(); }
private static void doParse( TreeNode root, ByteBuffer input, AtomicInteger i, AtomicInteger line) { TreeNode node = null; char c = 0; boolean whitespace = true; boolean delimit = false; for (; i.get() < input.limit(); i.getAndIncrement()) { c = (char) input.get(i.get()); // System.out.printf("[%d]", (int) c); switch (c) { case '\\': { delimit = true; break; } case '\n': line.getAndIncrement(); // $FALL-THROUGH$ case '\t': case '\r': case ' ': { if (delimit) delimit = false; if (!whitespace) { whitespace = true; if (node != null) { node.end = i.get() - 1; root.add(node); node = null; } } break; } case '"': { if (delimit) { delimit = false; if (whitespace) { whitespace = false; node = new TreeNode(input, i.get()); node.line = line.get(); node.start = i.get(); } } else { whitespace = true; TreeNode childNode = new TreeNode(input, i.get()); childNode.line = line.get(); childNode.start = i.get(); for (i.getAndIncrement(); i.get() < input.limit(); i.getAndIncrement()) { c = (char) input.get(i.get()); if (!delimit && (c == '"')) { break; } else if (c == '\\') { delimit = true; } else { delimit = false; } } delimit = false; childNode.end = i.get(); root.add(childNode); } break; } case '\'': { if (delimit) { delimit = false; if (whitespace) { whitespace = false; node = new TreeNode(input, i.get()); node.line = line.get(); node.start = i.get(); } } else { whitespace = true; TreeNode childNode = new TreeNode(input, i.get()); childNode.line = line.get(); childNode.start = i.get(); for (i.getAndIncrement(); i.get() < input.limit(); i.getAndIncrement()) { c = (char) input.get(i.get()); if (!delimit && (c == '\'')) { break; } else if (c == '\\') { delimit = true; } else { delimit = false; } } delimit = false; childNode.end = i.get(); root.add(childNode); } break; } case '{': case '(': case '[': { if (delimit) { delimit = false; if (whitespace) { whitespace = false; node = new TreeNode(input, i.get()); node.line = line.get(); node.start = i.get(); } } else { whitespace = true; if (node != null) { node.end = i.get() - 1; root.add(node); node = null; } TreeNode childNode = new TreeNode(input, i.get()); childNode.line = line.get(); childNode.start = i.get(); childNode.enter = i.get(); i.getAndIncrement(); doParse(childNode, input, i, line); childNode.exitLine = line.get(); childNode.exit = i.get() - 1; childNode.end = i.get() - 1; root.add(childNode); i.getAndDecrement(); } break; } case '}': case ')': case ']': { if (delimit) delimit = false; if (node != null) { node.end = i.get() - 1; root.add(node); node = null; } i.getAndIncrement(); return; } case ';': case ',': { if (!whitespace) { whitespace = true; if (node != null) { node.end = i.get() - 1; root.add(node); node = null; } } node = new TreeNode(input, i.get()); node.line = line.get(); node.start = i.get(); node.end = i.get(); root.add(node); node = null; break; } default: { if (delimit) delimit = false; if (whitespace) { whitespace = false; node = new TreeNode(input, i.get()); node.line = line.get(); node.start = i.get(); } break; } } } if ((node != null) && (node.end == -1)) { node.end = i.get() - 1; // input.length - 1; root.add(node); } }