text: /*
    Copyright (C) 2007 Thomas Jahns <Thomas.Jahns@gmx.net>
  
    Permission to use, copy, modify, and distribute this software for any
    purpose with or without fee is hereby granted, provided that the above
    copyright notice and this permission notice appear in all copies.
  
    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
  
  #ifndef EIS_SEQUENCEMULTIREAD_H
  #define EIS_SEQUENCEMULTIREAD_H
  /**
   * \file eis-sequencemultiread.h
   * Keeps information about multiple synchronous reads of sequence
   * data, where only one source and multiple consumers exist.
   */
  #include "core/assert_api.h"
  #include "core/minmax_api.h"
  #include "match/eis-seqdatasrc.h"
  
  /** every reader is identified by a unique scalar */
  typedef unsigned consumerID;
  
  /* moves data that can no longer be regenerated to the backlog */
  typedef void (*move2BacklogFunc)(void *backlogState, const void *seqData,
                                   GtUword requestStart, size_t requestLen);
  
  /**
   * basic idea: let this function write the required data to output
   * and also call the move2Backlog callback if any data will be
   * invalidated after this call and is still required by other consumers
   * @return number of elements actually generated (might be short on eof etc.)
   */
  typedef size_t (*generatorFunc)(void *generatorState, void *backlogState,
                                  move2BacklogFunc move2Backlog, void *output,
                                  GtUword generateStart, size_t len,
                                  SeqDataTranslator xltor);
  
  typedef struct seqReaderSet SeqReaderSet;
  
  struct seqReaderSet
  {
    int numConsumers, numAutoConsumers;
    int tagSuperSet;
    struct seqReaderState *consumerList;
    struct seqSinkState *autoConsumerList;
    GtUword backlogStartPos;
    bool fromSuffixsortspace;
    size_t backlogSize, backlogLen, backlogElemSize;
    void *seqDataBacklog, *generatorState;
    generatorFunc generator;
  };
  
  /**
   * @return numReaders if all consumers registered otherwise
   */
  /*
  int
  gt_initSeqReaderSet(SeqReaderSet *readerSet, int initialSuperSet,
                   int numConsumers, int *tags, SeqDataTranslator xltors[],
                   SeqDataReader *generatedReaders, size_t seqElemSize,
                   generatorFunc generator, void *generatorState);
  */
  
  void
  gt_initEmptySeqReaderSet(SeqReaderSet *readerSet, int initialSuperSet,
                           bool fromSuffixsortspace,
                           size_t seqElemSize,
                           generatorFunc generator,
                           void *generatorState);
  
  /**
   * @return readData field will be NULL on error -> test with
   * SDRIsValid */
  SeqDataReader
  gt_seqReaderSetRegisterConsumer(SeqReaderSet *readerSet, int tag,
                               SeqDataTranslator xltor);
  
  /**
   * @brief The registered writer will be called automatically for any
   * data that is to be invalidated.
   *
   * @return false on error, true if successfully registered
   */
  bool
  gt_seqReaderSetRegisterAutoConsumer(SeqReaderSet *readerSet, int tag,
                                   SeqDataWriter writer);
  
  void
  gt_destructSeqReaderSet(SeqReaderSet *readerSet);
  
  #endif
  