示例#1
0
  /**
   * Load enough bytes from channel to buffer. After the loading process, the caller can make sure
   * the amount in buffer is of size 'amount' if we haven't reached the end of channel.
   *
   * @param amount The amount of bytes in buffer after returning, no larger than bufferSize
   * @param reload Whether to reload or append
   */
  private void fillBuffer(long amount, boolean reload) {
    try {
      if (amount > bufferSize) {
        amount = bufferSize;
      }
      // Read all remaining bytes if the requested amount reach the end
      // of channel.
      if (channelSize - channel.position() < amount) {
        amount = channelSize - channel.position();
      }

      if (in == null) {
        switch (bufferType) {
          case HEAP:
            in = ByteBuffer.allocate(bufferSize, false);
            break;
          case DIRECT:
            in = ByteBuffer.allocate(bufferSize, true);
            break;
          case AUTO:
            in = ByteBuffer.allocate(bufferSize);
            break;
          default:
            in = ByteBuffer.allocate(bufferSize);
        }
        channel.read(in.buf());
        in.flip();
        useLoadBuf = true;
      }

      if (!useLoadBuf) {
        return;
      }

      if (reload || in.remaining() < amount) {
        if (!reload) {
          in.compact();
        } else {
          in.clear();
        }
        channel.read(in.buf());
        in.flip();
      }

    } catch (Exception e) {
      log.error("Error fillBuffer", e);
    }
  }
示例#2
0
  /** Tests that two simple receives work. */
  public void testMultipleSimpleReceives() {
    int len = 1000;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));

    harness.recv(buf.rewind());

    assertEquals(0, sentMessages.size());
    assertEquals(2, receivedMessages.size());

    actual = receivedMessages.get(1);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }
示例#3
0
  /** Tests handling of exceptions during dispatch. */
  public void testReceiveHandlingException() {
    int len = 1000;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    RuntimeException expectedEx = new RuntimeException("Dummy exception for testing filter recv");

    harness.setExceptionOnNextCompleteMessage(expectedEx);

    // This recv will fail to process the message
    harness.recv(buf);
    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    // Send a second message, expecting the first to have been dropped.
    buf.rewind();
    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());
  }
示例#4
0
  /**
   * Tests that complete messages are delivered even when the message arrives one byte at a time
   * from the network. Then tests that a second message can still be received all-at-once.
   */
  public void testPartialOneByteReceives() {
    int len = 32;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    for (; buf.hasRemaining(); buf.skip(1)) {
      assertEquals(0, sentMessages.size());
      assertEquals(0, receivedMessages.size());
      ByteBuffer singleByte = buf.slice().limit(1);
      harness.recv(singleByte);
    }

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));

    harness.recv(buf.rewind());

    assertEquals(0, sentMessages.size());
    assertEquals(2, receivedMessages.size());

    actual = receivedMessages.get(1);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }
示例#5
0
  /** Tests handling of exceptions during dispatch. */
  public void testReceiveHandlingExceptionPartial() {
    int len1 = 400;
    int len2 = 600;
    int len = len1 + len2;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    ByteBuffer part1 = buf.slice().limit(len1 + 4);

    ByteBuffer part2 = ByteBuffer.allocate(len2 + len2 + 4, false);
    buf.rewind();
    buf.skip(len1 + 4);
    part2.put(buf);
    buf.rewind();
    buf.skip(len1 + 4);
    part2.putInt(len2);
    part2.put(buf);
    part2.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.recv(part1);

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    RuntimeException expectedEx = new RuntimeException("Dummy exception for testing filter recv");

    harness.setExceptionOnNextCompleteMessage(expectedEx);

    // This recv should process the second message.
    harness.recv(part2);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);
    assertEquals(len2, actual.length);
  }
  @Override
  public ByteBuffer encodedContent() {
    ByteBuffer ret = ByteBuffer.allocate(32);
    ret.setAutoExpand(true);

    User.writeTo(user, ret);

    ret.flip();

    return ret;
  }
示例#7
0
  /**
   * 转换为字节数组,包括长度
   *
   * @return
   */
  public byte[] getByties() {
    int size = countSize();

    ByteBuffer buffer = ByteBuffer.allocate(size);

    writeBuffer(buffer);

    buffer.flip();

    byte[] ret = new byte[size];

    buffer.get(ret);

    return ret;
  }
示例#8
0
  /** {@inheritDoc} */
  public synchronized ITag readTag() {
    long oldPos = getCurrentPosition();
    ITag tag = readTagHeader();

    if (tagPosition == 0 && tag.getDataType() != TYPE_METADATA && generateMetadata) {
      // Generate initial metadata automatically
      setCurrentPosition(oldPos);
      KeyFrameMeta meta = analyzeKeyFrames();
      tagPosition++;
      if (meta != null) {
        return createFileMeta();
      }
    }

    ByteBuffer body = ByteBuffer.allocate(tag.getBodySize(), false);

    // XXX Paul: this assists in 'properly' handling damaged FLV files
    long newPosition = getCurrentPosition() + tag.getBodySize();
    if (newPosition <= getTotalBytes()) {
      int limit;
      while (getCurrentPosition() < newPosition) {
        fillBuffer(newPosition - getCurrentPosition());
        if (getCurrentPosition() + in.remaining() > newPosition) {
          limit = in.limit();
          in.limit((int) (newPosition - getCurrentPosition()) + in.position());
          body.put(in);
          in.limit(limit);
        } else {
          body.put(in);
        }
      }

      body.flip();
      tag.setBody(body);
      tagPosition++;
    }

    return tag;
  }
示例#9
0
  /**
   * Create tag for metadata event.
   *
   * @return Metadata event tag
   */
  private ITag createFileMeta() {
    // Create tag for onMetaData event
    ByteBuffer buf = ByteBuffer.allocate(1024);
    buf.setAutoExpand(true);
    Output out = new Output(buf);

    // Duration property
    out.writeString("onMetaData");
    Map<Object, Object> props = new HashMap<Object, Object>();
    props.put("duration", duration / 1000.0);
    if (firstVideoTag != -1) {
      long old = getCurrentPosition();
      setCurrentPosition(firstVideoTag);
      readTagHeader();
      fillBuffer(1);
      byte frametype = in.get();
      // Video codec id
      props.put("videocodecid", frametype & MASK_VIDEO_CODEC);
      setCurrentPosition(old);
    }
    if (firstAudioTag != -1) {
      long old = getCurrentPosition();
      setCurrentPosition(firstAudioTag);
      readTagHeader();
      fillBuffer(1);
      byte frametype = in.get();
      // Audio codec id
      props.put("audiocodecid", (frametype & MASK_SOUND_FORMAT) >> 4);
      setCurrentPosition(old);
    }
    props.put("canSeekToEnd", true);
    out.writeMap(props, new Serializer());
    buf.flip();

    ITag result = new Tag(IoConstants.TYPE_METADATA, 0, buf.limit(), null, 0);
    result.setBody(buf);
    return result;
  }
示例#10
0
  /** Tests that the send filter correctly prepends the message length. */
  public void testSend() {
    int len = 1000;
    byte[] sendData = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(sendData);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    byte[] expected = new byte[buf.remaining()];
    buf.get(expected);

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.send(sendData);

    assertEquals(1, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    byte[] actual = sentMessages.get(0);

    assertTrue("Incorrect send!", Arrays.equals(actual, expected));
  }