001/* 002 * JGrapes Event Driven Framework 003 * Copyright (C) 2016-2018 Michael N. Lipp 004 * 005 * This program is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Affero General Public License as published by 007 * the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License 013 * for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License along 016 * with this program; if not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jgrapes.io.events; 020 021import java.nio.Buffer; 022import java.nio.ByteBuffer; 023import java.nio.CharBuffer; 024import org.jgrapes.io.util.ManagedBuffer; 025 026/** 027 * This event signals that a new chunk of internally generated data is to be 028 * forwarded to some destination. This type of 029 * event is commonly used for data flowing out of the application. 030 */ 031public class Output<T extends Buffer> extends IOEvent<T> { 032 033 /** 034 * Create a new output event with the given buffer and optionally flips 035 * it. Used internally for constructor ("super(...)") invocations that 036 * don't flip the buffer. 037 * 038 * @param buffer the buffer with the data 039 * @param flip if the buffer should be flipped 040 * @param endOfRecord if the event ends a data record 041 */ 042 private Output(ManagedBuffer<T> buffer, boolean flip, boolean endOfRecord) { 043 super(buffer, endOfRecord); 044 if (flip) { 045 buffer.flip(); 046 } 047 } 048 049 /** 050 * Create a new event from an existing event. This constructor 051 * is useful if the data is to be forwarded to another channel 052 * by a new event. 053 * 054 * The buffer is reused in the new event (the lock count is 055 * incremented). 056 * 057 * @param event the existing event 058 */ 059 public Output(Output<T> event) { 060 this(event.buffer(), false, event.isEndOfRecord()); 061 event.buffer().lockBuffer(); 062 } 063 064 /** 065 * Create a new event with the given buffer. The buffer must 066 * have been prepared for invoking `get`-methods. 067 * 068 * @param buffer the buffer with the data 069 * @param endOfRecord if the event ends a data record 070 */ 071 public static <B extends Buffer> Output<B> fromSource( 072 ManagedBuffer<B> buffer, boolean endOfRecord) { 073 return new Output<>(buffer, false, endOfRecord); 074 } 075 076 /** 077 * Create a new event with the given buffer. Creating the event 078 * flips the buffer, which is assumed to have been used for 079 * collecting data up to now. 080 * 081 * @param buffer the buffer with the data 082 * @param endOfRecord if the event ends a data record 083 */ 084 public static <B extends Buffer> Output<B> fromSink( 085 ManagedBuffer<B> buffer, boolean endOfRecord) { 086 return new Output<>(buffer, true, endOfRecord); 087 } 088 089 /** 090 * Convenience method that creates a 091 * {@code Output<CharBuffer>} event from a {@link String}. 092 * 093 * @param data the string to wrap 094 * @param endOfRecord if the event ends a data record 095 * @return the event 096 */ 097 public static Output<CharBuffer> 098 from(String data, boolean endOfRecord) { 099 return new Output<>(ManagedBuffer.wrap( 100 CharBuffer.wrap(data)), false, endOfRecord); 101 } 102 103 /** 104 * Convenience method that creates a 105 * {@code Output<ByteBuffer>} event from a `byte[]`. 106 * 107 * @param data the array to wrap 108 * @param endOfRecord if the event ends a data record 109 * @return the event 110 */ 111 public static Output<ByteBuffer> 112 from(byte[] data, boolean endOfRecord) { 113 return new Output<>(ManagedBuffer.wrap(ByteBuffer.wrap(data)), 114 false, endOfRecord); 115 } 116}