CompositeMetadata implements Iterable<Entry> { @Override public Iterator<Entry> iterator() { return new Iterator<Entry>() { private int entryIndex = 0; @Override public boolean hasNext() { return hasEntry(CompositeMetadata.this.source, this.entryIndex); } @Override public Entry next() { ByteBuf[] headerAndData = decodeMimeAndContentBuffersSlices( CompositeMetadata.this.source, this.entryIndex, CompositeMetadata.this.retainSlices); ByteBuf header = headerAndData[0]; ByteBuf data = headerAndData[1]; this.entryIndex = computeNextEntryIndex(this.entryIndex, header, data); if (!isWellKnownMimeType(header)) { CharSequence typeString = decodeMimeTypeFromMimeBuffer(header); if (typeString == null) { throw new IllegalStateException("MIME type cannot be null"); } return new ExplicitMimeTimeEntry(data, typeString.toString()); } byte id = decodeMimeIdFromMimeBuffer(header); WellKnownMimeType type = WellKnownMimeType.fromIdentifier(id); if (WellKnownMimeType.UNKNOWN_RESERVED_MIME_TYPE == type) { return new ReservedMimeTypeEntry(data, id); } return new WellKnownMimeTypeEntry(data, type); } }; } CompositeMetadata(ByteBuf source, boolean retainSlices); Stream<Entry> stream(); @Override Iterator<Entry> iterator();  }
@Test void decodeEntryHasNoContentLength() { ByteBuf fakeEntry = Unpooled.buffer(); fakeEntry.writeByte(0); fakeEntry.writeCharSequence("w", CharsetUtil.US_ASCII); CompositeMetadata compositeMetadata = new CompositeMetadata(fakeEntry, false); assertThatIllegalStateException() .isThrownBy(() -> compositeMetadata.iterator().next()) .withMessage("metadata is malformed"); }
@Test void decodeEntryOnDoneBufferThrowsIllegalArgument() { ByteBuf fakeBuffer = ByteBufUtils.getRandomByteBuf(0); CompositeMetadata compositeMetadata = new CompositeMetadata(fakeBuffer, false); assertThatIllegalArgumentException() .isThrownBy(() -> compositeMetadata.iterator().next()) .withMessage("entry index 0 is larger than buffer size"); }
@Test void decodeEntryTooShortForContentLength() { ByteBuf fakeEntry = Unpooled.buffer(); fakeEntry.writeByte(1); fakeEntry.writeCharSequence("w", CharsetUtil.US_ASCII); NumberUtils.encodeUnsignedMedium(fakeEntry, 456); fakeEntry.writeChar('w'); CompositeMetadata compositeMetadata = new CompositeMetadata(fakeEntry, false); assertThatIllegalStateException() .isThrownBy(() -> compositeMetadata.iterator().next()) .withMessage("metadata is malformed"); }
@Test void decodeEntryTooShortForMimeLength() { ByteBuf fakeEntry = Unpooled.buffer(); fakeEntry.writeByte(120); CompositeMetadata compositeMetadata = new CompositeMetadata(fakeEntry, false); assertThatIllegalStateException() .isThrownBy(() -> compositeMetadata.iterator().next()) .withMessage("metadata is malformed"); }
@Test void decodeThreeEntries() { WellKnownMimeType mimeType1 = WellKnownMimeType.APPLICATION_PDF; ByteBuf metadata1 = Unpooled.buffer(); metadata1.writeCharSequence("abcdefghijkl", CharsetUtil.UTF_8); String mimeType2 = "application/custom"; ByteBuf metadata2 = Unpooled.buffer(); metadata2.writeChar('E'); metadata2.writeChar('∑'); metadata2.writeChar('é'); metadata2.writeBoolean(true); metadata2.writeChar('W'); byte reserved = 120; assertThat(WellKnownMimeType.fromIdentifier(reserved)) .as("ensure UNKNOWN RESERVED used in test") .isSameAs(WellKnownMimeType.UNKNOWN_RESERVED_MIME_TYPE); ByteBuf metadata3 = Unpooled.buffer(); metadata3.writeByte(88); CompositeByteBuf compositeMetadataBuffer = ByteBufAllocator.DEFAULT.compositeBuffer(); CompositeMetadataCodec.encodeAndAddMetadata( compositeMetadataBuffer, ByteBufAllocator.DEFAULT, mimeType1, metadata1); CompositeMetadataCodec.encodeAndAddMetadata( compositeMetadataBuffer, ByteBufAllocator.DEFAULT, mimeType2, metadata2); CompositeMetadataCodec.encodeAndAddMetadata( compositeMetadataBuffer, ByteBufAllocator.DEFAULT, reserved, metadata3); Iterator<Entry> iterator = new CompositeMetadata(compositeMetadataBuffer, true).iterator(); assertThat(iterator.next()) .as("entry1") .isNotNull() .satisfies( e -> assertThat(e.getMimeType()).as("entry1 mime type").isEqualTo(mimeType1.getString())) .satisfies( e -> assertThat(((WellKnownMimeTypeEntry) e).getType()) .as("entry1 mime id") .isEqualTo(WellKnownMimeType.APPLICATION_PDF)) .satisfies( e -> assertThat(e.getContent().toString(CharsetUtil.UTF_8)) .as("entry1 decoded") .isEqualTo("abcdefghijkl")); assertThat(iterator.next()) .as("entry2") .isNotNull() .satisfies(e -> assertThat(e.getMimeType()).as("entry2 mime type").isEqualTo(mimeType2)) .satisfies( e -> assertThat(e.getContent()).as("entry2 decoded").isEqualByComparingTo(metadata2)); assertThat(iterator.next()) .as("entry3") .isNotNull() .satisfies(e -> assertThat(e.getMimeType()).as("entry3 mime type").isNull()) .satisfies( e -> assertThat(((ReservedMimeTypeEntry) e).getType()) .as("entry3 mime id") .isEqualTo(reserved)) .satisfies( e -> assertThat(e.getContent()).as("entry3 decoded").isEqualByComparingTo(metadata3)); assertThat(iterator.hasNext()).as("has no more than 3 entries").isFalse(); }