text:
package com.google.android.exoplayer2.source.hls;

import android.os.Handler;
import android.support.annotation.IntDef;
import android.util.Log;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.extractor.DummyTrackOutput;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.SampleQueue;
import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * Loads {@link HlsMediaChunk}s obtained from a {@link HlsChunkSource}, and provides
 * {@link SampleStream}s from which the loaded media can be consumed.
 */
/* package */ final class HlsSampleStreamWrapper implements Loader.Callback<Chunk>,
    Loader.ReleaseCallback, SequenceableLoader, ExtractorOutput, UpstreamFormatChangedListener {

  /**
   * A callback to be notified of events.
   */
  public interface Callback extends SequenceableLoader.Callback<HlsSampleStreamWrapper> {

    /**
     * Called when the wrapper has been prepared.
     */
    void onPrepared();

    /**
     * Called to schedule a {@link #continueLoading(long)} call when the playlist referred by the
     * given url changes.
     */
    void onPlaylistRefreshRequired(HlsMasterPlaylist.HlsUrl playlistUrl);

  }

  private static final String TAG = "HlsSampleStreamWrapper";

  public static final int SAMPLE_QUEUE_INDEX_PENDING = -1;
  public static final int SAMPLE_QUEUE_INDEX_NO_MAPPING_FATAL = -2;
  public static final int SAMPLE_QUEUE_INDEX_NO_MAPPING_NON_FATAL = -3;

  @Retention(RetentionPolicy.SOURCE)
  @IntDef({PRIMARY_TYPE_NONE, PRIMARY_TYPE_TEXT, PRIMARY_TYPE_AUDIO, PRIMARY_TYPE_VIDEO})
  private @interface PrimaryTrackType {}

  private static final int PRIMARY_TYPE_NONE = 0;
  private static final int PRIMARY_TYPE_TEXT = 1;
  private static final int PRIMARY_TYPE_AUDIO = 2;
  private static final int PRIMARY_TYPE_VIDEO = 3;

  private final int trackType;
  private final Callback callback;
  private final HlsChunkSource chunkSource;
  private final Allocator allocator;
  private final Format muxedAudioFormat;
  private final int minLoadableRetryCount;
  private final Loader loader;
  private final EventDispatcher eventDispatcher;
  private final HlsChunkSource.HlsChunkHolder nextChunkHolder;
  private final ArrayList<HlsMediaChunk> mediaChunks;
  private final List<HlsMediaChunk> readOnlyMediaChunks;
  private final Runnable maybeFinishPrepareRunnable;
  private final Runnable onTracksEndedRunnable;
  private final Handler handler;
  private final ArrayList<HlsSampleStream> hlsSampleStreams;

  private SampleQueue[] sampleQueues;
  private int[] sampleQueueTrackIds;
  private boolean audioSampleQueueMappingDone;
  private int audioSampleQueueIndex;
  private boolean videoSampleQueueMappingDone;
  private int videoSampleQueueIndex;
  private boolean sampleQueuesBuilt;
  private boolean prepared;
  private int enabledTrackGroupCount;
  private Format downstreamTrackFormat;
  private boolean released;

  // Tracks are complicated in HLS. See documentation of buildTracks for details.
  // Indexed by track (as exposed by this source).
  private TrackGroupArray trackGroups;
  private TrackGroupArray optionalTrackGroups;
  // Indexed by track group.
  private int[] trackGroupToSampleQueueIndex;
  private int primaryTrackGroupIndex;
  private boolean haveAudioVideoSampleQueues;
  private boolean[] sampleQueuesEnabledStates;
  private boolean[] sampleQueueIsAudioVideoFlags;

  private long lastSeekPositionUs;
  private long pendingResetPositionUs;
  private boolean pendingResetUpstreamFormats;
  private boolean seenFirstTrackSelection;
  private boolean loadingFinished;

  // Accessed only by the loading thread.
  private boolean tracksEnded;
  private long sampleOffsetUs;

  /**
   * @param trackType The type of the track. One of the {@link C} {@code TRACK_TYPE_*} constants.
   * @param callback A callback for the wrapper.
   * @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained.
   * @param allocator An {@link Allocator} from which to obtain media buffer allocations.
   * @param positionUs The position from which to start loading media.
   * @param muxedAudioFormat Optional muxed audio {@link Format} as defined by the master playlist.
   * @param minLoadableRetryCount The minimum number of times that the source should retry a load
   *     before propagating an error.
   * @param eventDispatcher A dispatcher to notify of events.
   */
  public HlsSampleStreamWrapper(int trackType, Callback callback, HlsChunkSource chunkSource,
      Allocator allocator, long positionUs, Format muxedAudioFormat, int minLoadableRetryCount,
      EventDispatcher eventDispatcher) {
    this.trackType = trackType;
    this.callback = callback;
    this.chunkSource = chunkSource;
    this.allocator = allocator;
    this.muxedAudioFormat = muxedAudioFormat;
    this.minLoadableRetryCount = minLoadableRetryCount;
    this.eventDispatcher = eventDispatcher;
    loader = new Loader("Loader:HlsSampleStreamWrapper");
    nextChunkHolder = new HlsChunkSource.HlsChunkHolder();
    sampleQueueTrackIds = new int[0];
    audioSampleQueueIndex = C.INDEX_UNSET;
    videoSampleQueueIndex = C.INDEX_UNSET;
    sampleQueues = new SampleQueue[0];
    sampleQueueIsAudioVideoFlags = new boolean[0];
    sampleQueuesEnabledStates = new boolean[0];
    mediaChunks = new ArrayList<>();
    readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks);
    hlsSampleStreams = new ArrayList<>();
    maybeFinishPrepareRunnable =
        new Runnable() {
          @Override
          public void run() {
            maybeFinishPrepare();
          }
        };
    onTracksEndedRunnable =
        new Runnable() {
          @Override
          public void run() {
            onTracksEnded();
          }
        };
    handler = new Handler();
    lastSeekPositionUs = positionUs;
    pendingResetPositionUs = positionUs;
  }

  public void continuePreparing() {
    if (!prepared) {
      continueLoading(lastSeekPositionUs);
    }
  }

  /**
   * Prepares the sample stream wrapper with master playlist information.
   *
   * @param trackGroups The {@link TrackGroupArray} to expose.
   * @param primaryTrackGroupIndex The index of the adaptive track group.
   * @param optionalTrackGroups A subset of {@code trackGroups} that should not trigger a failure if
   *     not found in the media playlist's segments.
   */
  public void prepareWithMasterPlaylistInfo(
      TrackGroupArray trackGroups,
      int primaryTrackGroupIndex,
      TrackGroupArray optionalTrackGroups) {
    prepared = true;
    this.trackGroups = trackGroups;
    this.optionalTrackGroups = optionalTrackGroups;
    this.primaryTrackGroupIndex = primaryTrackGroupIndex;
    callback.onPrepared();
  }

  public void maybeThrowPrepareError() throws IOException {
    maybeThrowError();
  }

  public TrackGroupArray getTrackGroups() {
    return trackGroups;
  }

  public int bindSampleQueueToSampleStream(int trackGroupIndex) {
    int sampleQueueIndex = trackGroupToSampleQueueIndex[trackGroupIndex];
    if (sampleQueueIndex == C.INDEX_UNSET) {
      return optionalTrackGroups.indexOf(trackGroups.get(trackGroupIndex)) == C.INDEX_UNSET
          ? SAMPLE_QUEUE_INDEX_NO_MAPPING_FATAL
          : SAMPLE_QUEUE_INDEX_NO_MAPPING_NON_FATAL;
    }
    if (sampleQueuesEnabledStates[sampleQueueIndex]) {
      // This sample queue is already bound to a different sample stream.
      return SAMPLE_QUEUE_INDEX_NO_MAPPING_FATAL;
    }
    sampleQueuesEnabledStates[sampleQueueIndex] = true;
    return sampleQueueIndex;
  }

  public void unbindSampleQueue(int trackGroupIndex) {
    int sampleQueueIndex = trackGroupToSampleQueueIndex[trackGroupIndex];
    Assertions.checkState(sampleQueuesEnabledStates[sampleQueueIndex]);
    sampleQueuesEnabledStates[sampleQueueIndex] = false;
  }

  /**
   * Called by the parent {@link HlsMediaPeriod} when a track selection occurs.
   *
   * @param selections The renderer track selections.
   * @param mayRetainStreamFlags Flags indicating whether the existing sample stream can be retained
   *     for each selection. A {@code true} value indicates that the selection is unchanged, and
   *     that the caller does not require that the sample stream be recreated.
   * @param streams The existing sample streams, which will be updated to reflect the provided
   *     selections.
   * @param streamResetFlags Will be updated to indicate new sample streams, and sample streams that
   *     have been retained but with the requirement that the consuming renderer be reset.
   * @param positionUs The current playback position in microseconds.
   * @param forceReset If true then a reset is forced (i.e. a seek will be performed with in-buffer
   *     seeking disabled).
   * @return Whether this wrapper requires the parent {@link HlsMediaPeriod} to perform a seek as
   *     part of the track selection.
   */
  public boolean selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
      SampleStream[] streams, boolean[] streamResetFlags, long positionUs, boolean forceReset) {
    Assertions.checkState(prepared);
    int oldEnabledTrackGroupCount = enabledTrackGroupCount;
    // Deselect old tracks.
    for (int i = 0; i < selections.length; i++) {
      if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
        enabledTrackGroupCount--;
        ((HlsSampleStream) streams[i]).unbindSampleQueue();
        streams[i] = null;
      }
    }
    // We'll always need to seek if we're being forced to reset, or if this is a first selection to
    // a position other than the one we started preparing with, or if we're making a selection
    // having previously disabled all tracks.
    boolean seekRequired =
        forceReset
            || (seenFirstTrackSelection
                ? oldEnabledTrackGroupCount == 0
                : positionUs != lastSeekPositionUs);
    // Get the old (i.e. current before the loop below executes) primary track selection. The new
    // primary selection will equal the old one unless it's changed in the loop.
    TrackSelection oldPrimaryTrackSelection = chunkSource.getTrackSelection();
    TrackSelection primaryTrackSelection = oldPrimaryTrackSelection;
    // Select new tracks.
    for (int i = 0; i < selections.length; i++) {
      if (streams[i] == null && selections[i] != null) {
        enabledTrackGroupCount++;
        TrackSelection selection = selections[i];
        int trackGroupIndex = trackGroups.indexOf(selection.getTrackGroup());
        if (trackGroupIndex == primaryTrackGroupIndex) {
          primaryTrackSelection = selection;
          chunkSource.selectTracks(selection);
        }
        streams[i] = new HlsSampleStream(this, trackGroupIndex);
        streamResetFlags[i] = true;
        if (trackGroupToSampleQueueIndex != null) {
          ((HlsSampleStream) streams[i]).bindSampleQueue();
        }
        // If there's still a chance of avoiding a seek, try and seek within the sample queue.
        if (sampleQueuesBuilt && !seekRequired) {
          SampleQueue sampleQueue = sampleQueues[trackGroupToSampleQueueIndex[trackGroupIndex]];
          sampleQueue.rewind();
          // A seek can be avoided if we're able to advance to the current playback position in the
          // sample queue, or if we haven't read anything from the queue since the previous seek
          // (this case is common for sparse tracks such as metadata tracks). In all other cases a
          // seek is required.
          seekRequired = sampleQueue.advanceTo(positionUs, true, true) == SampleQueue.ADVANCE_FAILED
              && sampleQueue.getReadIndex() != 0;
        }
      }
    }

    if (enabledTrackGroupCount == 0) {
      chunkSource.reset();
      downstreamTrackFormat = null;
      mediaChunks.clear();
      if (loader.isLoading()) {
        if (sampleQueuesBuilt) {
          // Discard as much as we can synchronously.
          for (SampleQueue sampleQueue : sampleQueues) {
            sampleQueue.discardToEnd();
          }
        }
        loader.cancelLoading();
      } else {
        resetSampleQueues();
      }
    } else {
      if (!mediaChunks.isEmpty()
          && !Util.areEqual(primaryTrackSelection, oldPrimaryTrackSelection)) {
        // The primary track selection has changed and we have buffered media. The buffered media
        // may need to be discarded.
        boolean primarySampleQueueDirty = false;
        if (!seenFirstTrackSelection) {
          long bufferedDurationUs = positionUs < 0 ? -positionUs : 0;
          primaryTrackSelection.updateSelectedTrack(positionUs, bufferedDurationUs, C.TIME_UNSET);
          int chunkIndex = chunkSource.getTrackGroup().indexOf(getLastMediaChunk().trackFormat);
          if (primaryTrackSelection.getSelectedIndexInTrackGroup() != chunkIndex) {
            // This is the first selection and the chunk loaded during preparation does not match
            // the initially selected format.
            primarySampleQueueDirty = true;
          }
        } else {
          // The primary sample queue contains media buffered for the old primary track selection.
          primarySampleQueueDirty = true;
        }
        if (primarySampleQueueDirty) {
          forceReset = true;
          seekRequired = true;
          pendingResetUpstreamFormats = true;
        }
      }
      if (seekRequired) {
        seekToUs(positionUs, forceReset);
        // We'll need to reset renderers consuming from all streams due to the seek.
        for (int i = 0; i < streams.length; i++) {
          if (streams[i] != null) {
            streamResetFlags[i] = true;
          }
        }
      }
    }

    updateSampleStreams(streams);
    seenFirstTrackSelection = true;
    return seekRequired;
  }

  public void discardBuffer(long positionUs, boolean toKeyframe) {
    if (!sampleQueuesBuilt) {
      return;
    }
    int sampleQueueCount = sampleQueues.length;
    for (int i = 0; i < sampleQueueCount; i++) {
      sampleQueues[i].discardTo(positionUs, toKeyframe, sampleQueuesEnabledStates[i]);
    }
  }

  /**
   * Attempts to seek to the specified position in microseconds.
   *
   * @param positionUs The seek position in microseconds.
   * @param forceReset If true then a reset is forced (i.e. in-buffer seeking is disabled).
   * @return Whether the wrapper was reset, meaning the wrapped sample queues were reset. If false,
   *     an in-buffer seek was performed.
   */
  public boolean seekToUs(long positionUs, boolean forceReset) {
    lastSeekPositionUs = positionUs;
    // If we're not forced to reset nor have a pending reset, see if we can seek within the buffer.
    if (sampleQueuesBuilt && !forceReset && !isPendingReset() && seekInsideBufferUs(positionUs)) {
      return false;
    }
    // We were unable to seek within the buffer, so need to reset.
    pendingResetPositionUs = positionUs;
    loadingFinished = false;
    mediaChunks.clear();
    if (loader.isLoading()) {
      loader.cancelLoading();
    } else {
      resetSampleQueues();
    }
    return true;
  }

  public void release() {
    if (prepared) {
      // Discard as much as we can synchronously. We only do this if we're prepared, since otherwise
      // sampleQueues may still be being modified by the loading thread.
      for (SampleQueue sampleQueue : sampleQueues) {
        sampleQueue.discardToEnd();
      }
    }
    loader.release(this);
    handler.removeCallbacksAndMessages(null);
    released = true;
    hlsSampleStreams.clear();
  }

  @Override
  public void onLoaderReleased() {
    resetSampleQueues();
  }

  public void setIsTimestampMaster(boolean isTimestampMaster) {
    chunkSource.setIsTimestampMaster(isTimestampMaster);
  }

  public boolean onPlaylistError(HlsUrl url, boolean shouldBlacklist) {
    return chunkSource.onPlaylistError(url, shouldBlacklist);
  }

  // SampleStream implementation.

  public boolean isReady(int sampleQueueIndex) {
    return loadingFinished || (!isPendingReset() && sampleQueues[sampleQueueIndex].hasNextSample());
  }

  public void maybeThrowError() throws IOException {
    loader.maybeThrowError();
    chunkSource.maybeThrowError();
  }

  public int readData(int sampleQueueIndex, FormatHolder formatHolder, DecoderInputBuffer buffer,
      boolean requireFormat) {
    if (isPendingReset()) {
      return C.RESULT_NOTHING_READ;
    }

    // TODO: Split into discard (in discardBuffer) and format change (here and in skipData) steps.
    if (!mediaChunks.isEmpty()) {
      int discardToMediaChunkIndex = 0;
      while (discardToMediaChunkIndex < mediaChunks.size() - 1
          && finishedReadingChunk(mediaChunks.get(discardToMediaChunkIndex))) {
        discardToMediaChunkIndex++;
      }
      if (discardToMediaChunkIndex > 0) {
        Util.removeRange(mediaChunks, 0, discardToMediaChunkIndex);
      }
      HlsMediaChunk currentChunk = mediaChunks.get(0);
      Format trackFormat = currentChunk.trackFormat;
      if (!trackFormat.equals(downstreamTrackFormat)) {
        eventDispatcher.downstreamFormatChanged(trackType, trackFormat,
            currentChunk.trackSelectionReason, currentChunk.trackSelectionData,
            currentChunk.startTimeUs);
      }
      downstreamTrackFormat = trackFormat;
    }

    return sampleQueues[sampleQueueIndex].read(formatHolder, buffer, requireFormat, loadingFinished,
        lastSeekPositionUs);
  }

  public int skipData(int sampleQueueIndex, long positionUs) {
    if (isPendingReset()) {
      return 0;
    }

    SampleQueue sampleQueue = sampleQueues[sampleQueueIndex];
    if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
      return sampleQueue.advanceToEnd();
    } else {
      int skipCount = sampleQueue.advanceTo(positionUs, true, true);
      return skipCount == SampleQueue.ADVANCE_FAILED ? 0 : skipCount;
    }
  }

  // SequenceableLoader implementation

  @Override
  public long getBufferedPositionUs() {
    if (loadingFinished) {
      return C.TIME_END_OF_SOURCE;
    } else if (isPendingReset()) {
      return pendingResetPositionUs;
    } else {
      long bufferedPositionUs = lastSeekPositionUs;
      HlsMediaChunk lastMediaChunk = getLastMediaChunk();
      HlsMediaChunk lastCompletedMediaChunk = lastMediaChunk.isLoadCompleted() ? lastMediaChunk
          : mediaChunks.size() > 1 ? mediaChunks.get(mediaChunks.size() - 2) : null;
      if (lastCompletedMediaChunk != null) {
        bufferedPositionUs = Math.max(bufferedPositionUs, lastCompletedMediaChunk.endTimeUs);
      }
      if (sampleQueuesBuilt) {
        for (SampleQueue sampleQueue : sampleQueues) {
          bufferedPositionUs =
              Math.max(bufferedPositionUs, sampleQueue.getLargestQueuedTimestampUs());
        }
      }
      return bufferedPositionUs;
    }
  }

  @Override
  public long getNextLoadPositionUs() {
    if (isPendingReset()) {
      return pendingResetPositionUs;
    } else {
      return loadingFinished ? C.TIME_END_OF_SOURCE : getLastMediaChunk().endTimeUs;
    }
  }

  @Override
  public boolean continueLoading(long positionUs) {
    if (loadingFinished || loader.isLoading()) {
      return false;
    }

    List<HlsMediaChunk> chunkQueue;
    long loadPositionUs;
    if (isPendingReset()) {
      chunkQueue = Collections.emptyList();
      loadPositionUs = pendingResetPositionUs;
    } else {
      chunkQueue = readOnlyMediaChunks;
      loadPositionUs = getLastMediaChunk().endTimeUs;
    }
    chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
    boolean endOfStream = nextChunkHolder.endOfStream;
    Chunk loadable = nextChunkHolder.chunk;
    HlsMasterPlaylist.HlsUrl playlistToLoad = nextChunkHolder.playlist;
    nextChunkHolder.clear();

    if (endOfStream) {
      pendingResetPositionUs = C.TIME_UNSET;
      loadingFinished = true;
      return true;
    }

    if (loadable == null) {
      if (playlistToLoad != null) {
        callback.onPlaylistRefreshRequired(playlistToLoad);
      }
      return false;
    }

    if (isMediaChunk(loadable)) {
      pendingResetPositionUs = C.TIME_UNSET;
      HlsMediaChunk mediaChunk = (HlsMediaChunk) loadable;
      mediaChunk.init(this);
      mediaChunks.add(mediaChunk);
    }
    long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount);
    eventDispatcher.loadStarted(
        loadable.dataSpec,
        loadable.dataSpec.uri,
        loadable.type,
        trackType,
        loadable.trackFormat,
        loadable.trackSelectionReason,
        loadable.trackSelectionData,
        loadable.startTimeUs,
        loadable.endTimeUs,
        elapsedRealtimeMs);
    return true;
  }

  @Override
  public void reevaluateBuffer(long positionUs) {
    // Do nothing.
  }

  // Loader.Callback implementation.

  @Override
  public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) {
    chunkSource.onChunkLoadCompleted(loadable);
    eventDispatcher.loadCompleted(
        loadable.dataSpec,
        loadable.getUri(),
        loadable.type,
        trackType,
        loadable.trackFormat,
        loadable.trackSelectionReason,
        loadable.trackSelectionData,
        loadable.startTimeUs,
        loadable.endTimeUs,
        elapsedRealtimeMs,
        loadDurationMs,
        loadable.bytesLoaded());
    if (!prepared) {
      continueLoading(lastSeekPositionUs);
    } else {
      callback.onContinueLoadingRequested(this);
    }
  }

  @Override
  public void onLoadCanceled(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs,
      boolean released) {
    eventDispatcher.loadCanceled(
        loadable.dataSpec,
        loadable.getUri(),
        loadable.type,
        trackType,
        loadable.trackFormat,
        loadable.trackSelectionReason,
        loadable.trackSelectionData,
        loadable.startTimeUs,
        loadable.endTimeUs,
        elapsedRealtimeMs,
        loadDurationMs,
        loadable.bytesLoaded());
    if (!released) {
      resetSampleQueues();
      if (enabledTrackGroupCount > 0) {
        callback.onContinueLoadingRequested(this);
      }
    }
  }

  @Override
  public LoadErrorAction onLoadError(
      Chunk loadable,
      long elapsedRealtimeMs,
      long loadDurationMs,
      IOException error,
      int errorCount) {
    long bytesLoaded = loadable.bytesLoaded();
    boolean isMediaChunk = isMediaChunk(loadable);
    boolean cancelable = !isMediaChunk || bytesLoaded == 0;
    boolean canceled = false;
    if (chunkSource.onChunkLoadError(loadable, cancelable, error)) {
      if (isMediaChunk) {
        HlsMediaChunk removed = mediaChunks.remove(mediaChunks.size() - 1);
        Assertions.checkState(removed == loadable);
        if (mediaChunks.isEmpty()) {
          pendingResetPositionUs = lastSeekPositionUs;
        }
      }
      canceled = true;
    }
    eventDispatcher.loadError(
        loadable.dataSpec,
        loadable.getUri(),
        loadable.type,
        trackType,
        loadable.trackFormat,
        loadable.trackSelectionReason,
        loadable.trackSelectionData,
        loadable.startTimeUs,
        loadable.endTimeUs,
        elapsedRealtimeMs,
        loadDurationMs,
        loadable.bytesLoaded(),
        error,
        canceled);
    if (canceled) {
      if (!prepared) {
        continueLoading(lastSeekPositionUs);
      } else {
        callback.onContinueLoadingRequested(this);
      }
      return Loader.DONT_RETRY;
    } else {
      return error instanceof ParserException ? Loader.DONT_RETRY_FATAL : Loader.RETRY;
    }
  }

  // Called by the consuming thread, but only when there is no loading thread.

  /**
   * Initializes the wrapper for loading a chunk.
   *
   * @param chunkUid The chunk's uid.
   * @param shouldSpliceIn Whether the samples parsed from the chunk should be spliced into any
   *     samples already queued to the wrapper.
   * @param reusingExtractor Whether the extractor for the chunk has already been used for preceding
   *     chunks.
   */
  public void init(int chunkUid, boolean shouldSpliceIn, boolean reusingExtractor) {
    if (!reusingExtractor) {
      audioSampleQueueMappingDone = false;
      videoSampleQueueMappingDone = false;
    }
    for (SampleQueue sampleQueue : sampleQueues) {
      sampleQueue.sourceId(chunkUid);
    }
    if (shouldSpliceIn) {
      for (SampleQueue sampleQueue : sampleQueues) {
        sampleQueue.splice();
      }
    }
  }

  // ExtractorOutput implementation. Called by the loading thread.

  @Override
  public TrackOutput track(int id, int type) {
    int trackCount = sampleQueues.length;

    // Audio and video tracks are handled manually to ignore ids.
    if (type == C.TRACK_TYPE_AUDIO) {
      if (audioSampleQueueIndex != C.INDEX_UNSET) {
        if (audioSampleQueueMappingDone) {
          return sampleQueueTrackIds[audioSampleQueueIndex] == id
              ? sampleQueues[audioSampleQueueIndex]
              : createDummyTrackOutput(id, type);
        }
        audioSampleQueueMappingDone = true;
        sampleQueueTrackIds[audioSampleQueueIndex] = id;
        return sampleQueues[audioSampleQueueIndex];
      } else if (tracksEnded) {
        return createDummyTrackOutput(id, type);
      }
    } else if (type == C.TRACK_TYPE_VIDEO) {
      if (videoSampleQueueIndex != C.INDEX_UNSET) {
        if (videoSampleQueueMappingDone) {
          return sampleQueueTrackIds[videoSampleQueueIndex] == id
              ? sampleQueues[videoSampleQueueIndex]
              : createDummyTrackOutput(id, type);
        }
        videoSampleQueueMappingDone = true;
        sampleQueueTrackIds[videoSampleQueueIndex] = id;
        return sampleQueues[videoSampleQueueIndex];
      } else if (tracksEnded) {
        return createDummyTrackOutput(id, type);
      }
    } else /* sparse track */ {
      for (int i = 0; i < trackCount; i++) {
        if (sampleQueueTrackIds[i] == id) {
          return sampleQueues[i];
        }
      }
      if (tracksEnded) {
        return createDummyTrackOutput(id, type);
      }
    }
    SampleQueue trackOutput = new SampleQueue(allocator);
    trackOutput.setSampleOffsetUs(sampleOffsetUs);
    trackOutput.setUpstreamFormatChangeListener(this);
    sampleQueueTrackIds = Arrays.copyOf(sampleQueueTrackIds, trackCount + 1);
    sampleQueueTrackIds[trackCount] = id;
    sampleQueues = Arrays.copyOf(sampleQueues, trackCount + 1);
    sampleQueues[trackCount] = trackOutput;
    sampleQueueIsAudioVideoFlags = Arrays.copyOf(sampleQueueIsAudioVideoFlags, trackCount + 1);
    sampleQueueIsAudioVideoFlags[trackCount] = type == C.TRACK_TYPE_AUDIO
        || type == C.TRACK_TYPE_VIDEO;
    haveAudioVideoSampleQueues |= sampleQueueIsAudioVideoFlags[trackCount];
    if (type == C.TRACK_TYPE_AUDIO) {
      audioSampleQueueMappingDone = true;
      audioSampleQueueIndex = trackCount;
    } else if (type == C.TRACK_TYPE_VIDEO) {
      videoSampleQueueMappingDone = true;
      videoSampleQueueIndex = trackCount;
    }
    sampleQueuesEnabledStates = Arrays.copyOf(sampleQueuesEnabledStates, trackCount + 1);
    return trackOutput;
  }

  @Override
  public void endTracks() {
    tracksEnded = true;
    handler.post(onTracksEndedRunnable);
  }

  @Override
  public void seekMap(SeekMap seekMap) {
    // Do nothing.
  }

  // UpstreamFormatChangedListener implementation. Called by the loading thread.

  @Override
  public void onUpstreamFormatChanged(Format format) {
    handler.post(maybeFinishPrepareRunnable);
  }

  // Called by the loading thread.

  public void setSampleOffsetUs(long sampleOffsetUs) {
    this.sampleOffsetUs = sampleOffsetUs;
    for (SampleQueue sampleQueue : sampleQueues) {
      sampleQueue.setSampleOffsetUs(sampleOffsetUs);
    }
  }

  // Internal methods.

  private void updateSampleStreams(SampleStream[] streams) {
    hlsSampleStreams.clear();
    for (SampleStream stream : streams) {
      if (stream != null) {
        hlsSampleStreams.add((HlsSampleStream) stream);
      }
    }
  }

  private boolean finishedReadingChunk(HlsMediaChunk chunk) {
    int chunkUid = chunk.uid;
    int sampleQueueCount = sampleQueues.length;
    for (int i = 0; i < sampleQueueCount; i++) {
      if (sampleQueuesEnabledStates[i] && sampleQueues[i].peekSourceId() == chunkUid) {
        return false;
      }
    }
    return true;
  }

  private void resetSampleQueues() {
    for (SampleQueue sampleQueue : sampleQueues) {
      sampleQueue.reset(pendingResetUpstreamFormats);
    }
    pendingResetUpstreamFormats = false;
  }

  private void onTracksEnded() {
    sampleQueuesBuilt = true;
    maybeFinishPrepare();
  }

  private void maybeFinishPrepare() {
    if (released || trackGroupToSampleQueueIndex != null || !sampleQueuesBuilt) {
      return;
    }
    for (SampleQueue sampleQueue : sampleQueues) {
      if (sampleQueue.getUpstreamFormat() == null) {
        return;
      }
    }
    if (trackGroups != null) {
      // The track groups were created with master playlist information. They only need to be mapped
      // to a sample queue.
      mapSampleQueuesToMatchTrackGroups();
    } else {
      // Tracks are created using media segment information.
      buildTracksFromSampleStreams();
      prepared = true;
      callback.onPrepared();
    }
  }

  private void mapSampleQueuesToMatchTrackGroups() {
    int trackGroupCount = trackGroups.length;
    trackGroupToSampleQueueIndex = new int[trackGroupCount];
    Arrays.fill(trackGroupToSampleQueueIndex, C.INDEX_UNSET);
    for (int i = 0; i < trackGroupCount; i++) {
      for (int queueIndex = 0; queueIndex < sampleQueues.length; queueIndex++) {
        SampleQueue sampleQueue = sampleQueues[queueIndex];
        if (formatsMatch(sampleQueue.getUpstreamFormat(), trackGroups.get(i).getFormat(0))) {
          trackGroupToSampleQueueIndex[i] = queueIndex;
          break;
        }
      }
    }
    for (HlsSampleStream sampleStream : hlsSampleStreams) {
      sampleStream.bindSampleQueue();
    }
  }

  /**
   * Builds tracks that are exposed by this {@link HlsSampleStreamWrapper} instance, as well as
   * internal data-structures required for operation.
   *
   * <p>Tracks in HLS are complicated. A HLS master playlist contains a number of "variants". Each
   * variant stream typically contains muxed video, audio and (possibly) additional audio, metadata
   * and caption tracks. We wish to allow the user to select between an adaptive track that spans
   * all variants, as well as each individual variant. If multiple audio tracks are present within
   * each variant then we wish to allow the user to select between those also.
   *
   * <p>To do this, tracks are constructed as follows. The {@link HlsChunkSource} exposes (N+1)
   * tracks, where N is the number of variants defined in the HLS master playlist. These consist of
   * one adaptive track defined to span all variants and a track for each individual variant. The
   * adaptive track is initially selected. The extractor is then prepared to discover the tracks
   * inside of each variant stream. The two sets of tracks are then combined by this method to
   * create a third set, which is the set exposed by this {@link HlsSampleStreamWrapper}:
   *
   * <ul>
   *   <li>The extractor tracks are inspected to infer a "primary" track type. If a video track is
   *       present then it is always the primary type. If not, audio is the primary type if present.
   *       Else text is the primary type if present. Else there is no primary type.
   *   <li>If there is exactly one extractor track of the primary type, it's expanded into (N+1)
   *       exposed tracks, all of which correspond to the primary extractor track and each of which
   *       corresponds to a different chunk source track. Selecting one of these tracks has the
   *       effect of switching the selected track on the chunk source.
   *   <li>All other extractor tracks are exposed directly. Selecting one of these tracks has the
   *       effect of selecting an extractor track, leaving the selected track on the chunk source
   *       unchanged.
   * </ul>
   */
  private void buildTracksFromSampleStreams() {
    // Iterate through the extractor tracks to discover the "primary" track type, and the index
    // of the single track of this type.
    @PrimaryTrackType int primaryExtractorTrackType = PRIMARY_TYPE_NONE;
    int primaryExtractorTrackIndex = C.INDEX_UNSET;
    int extractorTrackCount = sampleQueues.length;
    for (int i = 0; i < extractorTrackCount; i++) {
      String sampleMimeType = sampleQueues[i].getUpstreamFormat().sampleMimeType;
      @PrimaryTrackType int trackType;
      if (MimeTypes.isVideo(sampleMimeType)) {
        trackType = PRIMARY_TYPE_VIDEO;
      } else if (MimeTypes.isAudio(sampleMimeType)) {
        trackType = PRIMARY_TYPE_AUDIO;
      } else if (MimeTypes.isText(sampleMimeType)) {
        trackType = PRIMARY_TYPE_TEXT;
      } else {
        trackType = PRIMARY_TYPE_NONE;
      }
      if (trackType > primaryExtractorTrackType) {
        primaryExtractorTrackType = trackType;
        primaryExtractorTrackIndex = i;
      } else if (trackType == primaryExtractorTrackType
          && primaryExtractorTrackIndex != C.INDEX_UNSET) {
        // We have multiple tracks of the primary type. We only want an index if there only exists a
        // single track of the primary type, so unset the index again.
        primaryExtractorTrackIndex = C.INDEX_UNSET;
      }
    }

    TrackGroup chunkSourceTrackGroup = chunkSource.getTrackGroup();
    int chunkSourceTrackCount = chunkSourceTrackGroup.length;

    // Instantiate the necessary internal data-structures.
    primaryTrackGroupIndex = C.INDEX_UNSET;
    trackGroupToSampleQueueIndex = new int[extractorTrackCount];
    for (int i = 0; i < extractorTrackCount; i++) {
      trackGroupToSampleQueueIndex[i] = i;
    }

    // Construct the set of exposed track groups.
    TrackGroup[] trackGroups = new TrackGroup[extractorTrackCount];
    for (int i = 0; i < extractorTrackCount; i++) {
      Format sampleFormat = sampleQueues[i].getUpstreamFormat();
      if (i == primaryExtractorTrackIndex) {
        Format[] formats = new Format[chunkSourceTrackCount];
        for (int j = 0; j < chunkSourceTrackCount; j++) {
          formats[j] = deriveFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat, true);
        }
        trackGroups[i] = new TrackGroup(formats);
        primaryTrackGroupIndex = i;
      } else {
        Format trackFormat = primaryExtractorTrackType == PRIMARY_TYPE_VIDEO
            && MimeTypes.isAudio(sampleFormat.sampleMimeType) ? muxedAudioFormat : null;
        trackGroups[i] = new TrackGroup(deriveFormat(trackFormat, sampleFormat, false));
      }
    }
    this.trackGroups = new TrackGroupArray(trackGroups);
    Assertions.checkState(optionalTrackGroups == null);
    optionalTrackGroups = TrackGroupArray.EMPTY;
  }

  private HlsMediaChunk getLastMediaChunk() {
    return mediaChunks.get(mediaChunks.size() - 1);
  }

  private boolean isPendingReset() {
    return pendingResetPositionUs != C.TIME_UNSET;
  }

  /**
   * Attempts to seek to the specified position within the sample queues.
   *
   * @param positionUs The seek position in microseconds.
   * @return Whether the in-buffer seek was successful.
   */
  private boolean seekInsideBufferUs(long positionUs) {
    int sampleQueueCount = sampleQueues.length;
    for (int i = 0; i < sampleQueueCount; i++) {
      SampleQueue sampleQueue = sampleQueues[i];
      sampleQueue.rewind();
      boolean seekInsideQueue = sampleQueue.advanceTo(positionUs, true, false)
          != SampleQueue.ADVANCE_FAILED;
      // If we have AV tracks then an in-queue seek is successful if the seek into every AV queue
      // is successful. We ignore whether seeks within non-AV queues are successful in this case, as
      // they may be sparse or poorly interleaved. If we only have non-AV tracks then a seek is
      // successful only if the seek into every queue succeeds.
      if (!seekInsideQueue && (sampleQueueIsAudioVideoFlags[i] || !haveAudioVideoSampleQueues)) {
        return false;
      }
    }
    return true;
  }

  /**
   * Derives a track format using master playlist and sample format information.
   *
   * @param playlistFormat The format information obtained from the master playlist.
   * @param sampleFormat The format information obtained from the samples.
   * @param propagateBitrate Whether the bitrate from the playlist format should be included in the
   *     derived format.
   * @return The derived track format.
   */
  private static Format deriveFormat(
      Format playlistFormat, Format sampleFormat, boolean propagateBitrate) {
    if (playlistFormat == null) {
      return sampleFormat;
    }
    int bitrate = propagateBitrate ? playlistFormat.bitrate : Format.NO_VALUE;
    int sampleTrackType = MimeTypes.getTrackType(sampleFormat.sampleMimeType);
    String codecs = Util.getCodecsOfType(playlistFormat.codecs, sampleTrackType);
    String mimeType = MimeTypes.getMediaMimeType(codecs);
    if (mimeType == null) {
      mimeType = sampleFormat.sampleMimeType;
    }
    return sampleFormat.copyWithContainerInfo(
        playlistFormat.id,
        mimeType,
        codecs,
        bitrate,
        playlistFormat.width,
        playlistFormat.height,
        playlistFormat.selectionFlags,
        playlistFormat.language);
  }

  private static boolean isMediaChunk(Chunk chunk) {
    return chunk instanceof HlsMediaChunk;
  }

  private static boolean formatsMatch(Format manifestFormat, Format sampleFormat) {
    String manifestFormatMimeType = manifestFormat.sampleMimeType;
    String sampleFormatMimeType = sampleFormat.sampleMimeType;
    int manifestFormatTrackType = MimeTypes.getTrackType(manifestFormatMimeType);
    if (manifestFormatTrackType != C.TRACK_TYPE_TEXT) {
      return manifestFormatTrackType == MimeTypes.getTrackType(sampleFormatMimeType);
    } else if (!Util.areEqual(manifestFormatMimeType, sampleFormatMimeType)) {
      return false;
    }
    if (MimeTypes.APPLICATION_CEA608.equals(manifestFormatMimeType)
        || MimeTypes.APPLICATION_CEA708.equals(manifestFormatMimeType)) {
      return manifestFormat.accessibilityChannel == sampleFormat.accessibilityChannel;
    }
    return true;
  }

  private static DummyTrackOutput createDummyTrackOutput(int id, int type) {
    Log.w(TAG, "Unmapped track with id " + id + " of type " + type);
    return new DummyTrackOutput();
  }
}


text:
import { config } from '../../config'

// export { config }

export default () =>
hello world

redpajama_set_name: RedPajamaGithub


text:
package biz.pavonis.golservice.internal;

import org.junit.Before;
import org.junit.Test;

import biz.pavonis.golservice.api.GameOfLifeService;
import biz.pavonis.golservice.api.GameOfLifeServiceBuilder;

public class GameOfLifeServiceImplTest {

    private GameOfLifeService target;

    @Before
    public void setUp() throws Exception {
        target = new GameOfLifeServiceBuilder().setHeight(5000).setWidth(5000).setTickInterval(50).build();
    }

    @Test
    public void test() throws InterruptedException {
        target.start();
        Thread.sleep(5000);
        System.out.println(target.getLatestGeneration().getCount());
    }

}


text:
/*******************************************************************************/
/** \file
 *
 *
 * This file contains interrupt related functions in the SAS/SATA TD layer
 *
 */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <dev/pms/config.h>

#include <dev/pms/freebsd/driver/common/osenv.h>
#include <dev/pms/freebsd/driver/common/ostypes.h>
#include <dev/pms/freebsd/driver/common/osdebug.h>

#include <dev/pms/RefTisa/sallsdk/api/sa.h>
#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>

#include <dev/pms/RefTisa/tisa/api/titypes.h>
#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiglobal.h>

#ifdef FDS_SM
#include <dev/pms/RefTisa/sat/api/sm.h>
#include <dev/pms/RefTisa/sat/api/smapi.h>
#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
#endif

#ifdef FDS_DM
#include <dev/pms/RefTisa/discovery/api/dm.h>
#include <dev/pms/RefTisa/discovery/api/dmapi.h>
#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
#endif

#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
#include <dev/pms/freebsd/driver/common/osstring.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>

#ifdef INITIATOR_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
#endif

#ifdef TARGET_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
#endif

#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>

/*****************************************************************************
*! \biref  tiCOMInterruptHandler
*
*  Purpose: This function is called to service the hardware interrupt of the
*           hardware.
*
*  \param tiRoot:   Pointer to initiator specific root data structure  for this
*                   instance of the driver.
*
*  \param channelNum: The zero-base channel number of the controller.
*                     0xFFFFFFFF indicates that the OS-App Specific layer does
*                     not provide the channel number. The TD/LL Layer needs to
*                     discover of any of its own channels that are causing the
*                     interrupt.
*
*  \return None
*
*  \note - The only thing that this API will do is to acknowledge and mask
*          the necessary hardware interrupt register. The actual processing
*          of the interrupt handler is done in tiCOMDelayedInterruptHandler().
*
*****************************************************************************/
FORCEINLINE bit32
tiCOMInterruptHandler(
                      tiRoot_t * tiRoot,
                      bit32      channelNum)
{
  tdsaRoot_t      *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
  tdsaContext_t   *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
  agsaRoot_t      *agRoot = &(tdsaAllShared->agRootNonInt);
  bit32           interruptPending = agFALSE;

  interruptPending = saInterruptHandler(agRoot, channelNum);

  return interruptPending;

} /* tiCOMInterruptHandler() */

/*****************************************************************************
*! \brief tiCOMDelayedInterruptHandler
*
*  Purpose: This function is called to process the task associated with the
*           interrupt handler. The task that this handler needs to do includes:
*           completion of I/O, login event, error event, etc
*
*  \param tiRoot:     Pointer to initiator specific root data structure for
*                     this instance of the driver.
*  \param channelNum: The zero-base channel number of the controller.
*                     0xFFFFFFFF indicates that the OS-App Specific layer does
*                     not provide the channel number. The TD/LL Layer needs to
*                     discover of any of its own channels that are causing the
*                     interrupt.
*  \param count:      Count on how many items (such as IO completion) need to
*                     be processed in this context.
*  \param interruptContext: The thread/process context within which this
*                           function is called.
*
*             tiInterruptContext:     this function is called within an
*                                     interrupt context.
*             tiNonInterruptContext:  this function is called outside an
*                                     interrupt context.
*  \return None
*
*****************************************************************************/
FORCEINLINE
bit32
tiCOMDelayedInterruptHandler(
                             tiRoot_t  *tiRoot,
                             bit32     channelNum,
                             bit32     count,
                             bit32     context
                             )
{
  tdsaRoot_t      *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
  tdsaContext_t   *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
  agsaRoot_t      *agRoot = agNULL;
  bit32            completed = 0;

  TDSA_OUT_ENTER(tiRoot);

  if(context == tiInterruptContext)
  {
    agRoot = &(tdsaAllShared->agRootInt);
  }
  else
  {
    agRoot = &(tdsaAllShared->agRootNonInt);
  }

  completed = saDelayedInterruptHandler(agRoot, channelNum, count);

  if(completed == 0)
  {
    TI_DBG3(("tiCOMDelayedInterruptHandler: processedMsgCount zero\n"));
  }

  TDSA_OUT_LEAVE(tiRoot);

  return(completed);
} /* tiCOMDelayedInterruptHandler() */

/*****************************************************************************
*! \brief tiCOMSystemInterruptsActive
*
*  Purpose: This function is called to indicate whether interrupts are
*           active or not from this point in time.
*
*  \param tiRoot:        Pointer to initiator specific root data structure for
*                        this instance of the driver.
*  \param sysIntsActive: Boolean value either true or false
*
*  \return None
*
*****************************************************************************/
osGLOBAL void
tiCOMSystemInterruptsActive(
                            tiRoot_t * tiRoot,
                            bit32 sysIntsActive
                            )
{

  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
  agsaRoot_t     *agRoot;
  agRoot = &(tdsaAllShared->agRootNonInt);

#ifdef SPC_POLLINGMODE
  if(sysIntsActive)  return;
#endif /* SPC_POLLINGMODE */

  tdsaAllShared->flags.sysIntsActive = sysIntsActive;

  TI_DBG6(("tiCOMSystemInterruptsActive: start\n"));
  /* enable low level interrupts */
  if(agRoot->sdkData != agNULL)
  {
    saSystemInterruptsActive(
                             agRoot,
                             (agBOOLEAN) tdsaAllShared->flags.sysIntsActive
                             );
  }

  TI_DBG6(("tiCOMSystemInterruptsActive: end\n"));
} /* tiCOMSystemInterruptsActive */

osGLOBAL void
tiComCountActiveIORequests(
                            tiRoot_t * tiRoot
                          )
{
  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
  agsaRoot_t     *agRoot;
  agRoot = &(tdsaAllShared->agRootNonInt);
  saCountActiveIORequests(agRoot );
}

/*****************************************************************************
*! \brief tiCOMInterruptEnable
*
*  Purpose: This function is called to enable an interrupts on the specified channel
*           active or not from this point in time.
*
*  \param tiRoot:        Pointer to initiator specific root data structure for
*                        this instance of the driver.
*  \param : channelNum   vector number for MSIX  Zero for legacy interrupt
*
*  \return None
*
*****************************************************************************/
osGLOBAL FORCEINLINE
void
tiCOMInterruptEnable(
                      tiRoot_t * tiRoot,
                      bit32      channelNum)
{
  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
  agsaRoot_t     *agRoot;
  agRoot = &(tdsaAllShared->agRootNonInt);

  saSystemInterruptsEnable(agRoot, channelNum);
}


text:
/**
 * @author theo
 *
 */
@org.eclipse.jdt.annotation.NonNullByDefault
package io.zrz.zulu.validator;


text:
/** @name Formatted output functions
 *
 * The following formatted output functions are implemented here:
 * kprintf, kvprintf, snprintf, vsnprintf. These are scaled down
 * versions of those documented in the manual page printf(3), with
 * kprintf and kvprintf printf and vprintf which use the polling TTY
 * driver for output.
 *
 * The only data types supported are integer (32-bit), char and a
 * pointer (type identifiers d, i, o, u, x, X, c, s, p, no length
 * specifiers (e.g. l) are supported.
 *
 * The formatting _cannot_ refer to the parameter by number
 * (i.e. the *-format).
 *
 * The following restrictions apply to the modifiers:
 *
 * \begin{tabular}{l|l}
 * \hline
 *
 *  # (alternate form) & Supported for x,X         \\
 *  0 (zero padding)   & Supported for o,u,x,X,p   \\
 *  - (left adjust)    & Not supported             \\
 *  space              & Supported (d,i)           \\
 *  +                  & Supported (d,i)           \\
 *  Field width        & Supported for o,u,x,X,p   \\
 *  Precision          & Supported for o,u,x,X,s,p \\
 *
 * \end{tabular}
 */

#include "lib/libc.h"
#include "drivers/polltty.h"
#include "kernel/interrupt.h"
#include "kernel/spinlock.h"

/* determine whether to output to TTY or a memory buffer */
#define FLAG_TTY     0x8000

static int vxnprintf(char*, int, const char*, va_list, int);

spinlock_t kprintf_slock = 0;

/* corresponding to vprintf(3) */
int kvprintf(const char *fmt, va_list ap) {
  int written;
  interrupt_status_t intr_state;

  intr_state = _interrupt_disable();
  spinlock_acquire(&kprintf_slock);

  written = vxnprintf((char*)0, 0x7fffffff, fmt, ap, FLAG_TTY);

  spinlock_release(&kprintf_slock);
  _interrupt_set_state(intr_state);

  return written;
}

/* corresponding to printf(3) */
int kprintf(const char *fmt, ...) {
  va_list ap;
  int written;
  interrupt_status_t intr_state;

  intr_state = _interrupt_disable();
  spinlock_acquire(&kprintf_slock);

  va_start(ap, fmt);
  written = vxnprintf((char*)0, 0x7fffffff, fmt, ap, FLAG_TTY);
  va_end(ap);

  spinlock_release(&kprintf_slock);
  _interrupt_set_state(intr_state);

  return written;
}

/* (almost) vsnprintf(3) */
int vsnprintf(char *str, int size, const char  *fmt, va_list ap) {
  return vxnprintf(str, size, fmt, ap, 0);
}

/* (almost) snprintf(3) */
int snprintf(char *str, int size, const  char  *fmt, ...) {
  va_list ap;
  int written;

  va_start(ap, fmt);
  written = vxnprintf(str, size, fmt, ap, 0);
  va_end(ap);
  return written;
}

#define FLAG_SMALLS  0x01
#define FLAG_ALT     0x02
#define FLAG_ZEROPAD 0x04
#define FLAG_LEFT    0x08
#define FLAG_SPACE   0x10
#define FLAG_SIGN    0x20

/* output the given char either to the string or to the TTY */
static void printc(char *buf, char c, int flags) {
  if (flags & FLAG_TTY) {
    /* do not output (terminating) zeros to TTY */
    if (c != '\0') polltty_putchar(c); /* synched in k(v)printf */
  } else
    *buf = c;
}

/* Output 'n' in base 'base' into buffer 'buf' or to TTY.  At least
 * 'prec' numbers are output, padding with zeros if needed, and at
 * least 'width' characters are output, padding with spaces on the
 * left if needed. 'flags' tells whether to use the buffer or TTY for
 * output and whether to use capital digits.
 */
static int print_uint(char *buf,
                      int size,
                      unsigned int n,
                      unsigned int base,
                      int flags,
                      int prec,
                      int width)
{
  static const char digits[32] = "0123456789ABCDEF0123456789abcdef";
  char rev[11]; /* space for 32-bit int in octal */
  int i = 0, written = 0;

  if (size <= 0) return 0;

  /* produce the number string in reverse order to the temp buffer 'rev' */
  do {
    if (flags & FLAG_SMALLS)
      rev[i] = digits[16 + n % base];
    else
      rev[i] = digits[n % base];
    i++;
    n /= base;
  } while (n != 0);

  /* limit precision and field with */
  prec = MIN(prec, 11);
  width = MIN(width, 11);

  /* zero pad until at least 'prec' digits written */
  while(i < prec) {
    rev[i] = '0';
    i++;
  }

  /* pad with spaces until at least 'width' chars written */
  while(i < width) {
    rev[i] = ' ';
    i++;
  }

  /* output the produced string in reverse order */
  i--;
  while(i >= 0 && written < size) {
    printc(buf++, rev[i], flags);
    written++;
    i--;
  }

  return written;
}

/* Scan a 10-base nonnegative integer from string 's'. The scanned
 * integer is returned, and '*next' is set to point to the string
 * immediately following the scanned integer.
 */
static int scan_int(const char *s, const char **next) {
  int value = 0;

  while(*s > '0' && *s < '9') {
    value = 10*value + (int)(*s - '0');
    s++;
  }

  if (next != NULL) *next = s;
  return value;
}

/* Output a formatted string 'fmt' with variable arguments 'ap' into
 * the string 'buf' or to TTY, depending on 'flags'. At most 'size'
 * characters are written (including the trailing '\0'). Returns the
 * number of characters actually written.
 */
static int vxnprintf(char *buf,
                     int size,
                     const char *fmt,
                     va_list ap,
                     int flags)
{
  int written = 0, w, moremods;
  int width, prec;
  char ch, *s;
  unsigned int uarg;
  int arg;

  if (size <= 0) return 0;

  while(written < size) {
    ch = *fmt++;
    if (ch == '\0') break;

    /* normal character => just output it */
    if (ch != '%') {
      printc(buf++, ch, flags);
      written++;
      continue;
    }

    /* to get here, ch == '%' */
    ch = *fmt++;
    if (ch == '\0') break;

    flags &= FLAG_TTY; /*  preserve only the TTY flag */
    width = prec = -1;
    moremods = 1;

    /* read flags and modifiers (width+precision): */
    do {
      switch(ch) {
      case '#': /* alternative output */
        flags |= FLAG_ALT;
        break;

      case '0': /* zero padding */
        flags |= FLAG_ZEROPAD;
        break;

      case ' ': /* space in place of '-' */
        flags |= FLAG_SPACE;
        break;

      case '+': /* '+' in place of '-' */
        flags |= FLAG_SIGN;
        break;

      case '-': /* left align the field */
        flags |= FLAG_LEFT;
        break;

      case '.': /* value precision */
        prec = scan_int(fmt, &fmt);
        break;

      case '1': case '2': case '3': case '4': case '5':
      case '6': case '7': case '8': case '9': /* field width */
        width = scan_int(fmt-1, &fmt);
        break;

      default: /* no more modifiers to scan */
        moremods = 0;
      }

      if (moremods) ch = *fmt++;
    } while(moremods && ch != '\0');

    if (ch == '\0') break;

    /* read the type of the argument : */
    switch(ch) {
    case 'i': /* signed integer */
    case 'd':
      arg = va_arg(ap, int);

      if (arg < 0) { /* negative value, print '-' and negate */
        printc(buf++, '-', flags);
        written++;
        arg = -arg;
      } if (flags & FLAG_SIGN) { /* '+' in place of '-' */
        printc(buf++, '+', flags);
        written++;
      } else if (flags & FLAG_SPACE) { /* ' ' in place of '-' */
        printc(buf++, ' ', flags);
        written++;
      }

      w = print_uint(buf, size-written, arg, 10, flags, 0, 0);
      buf += w;
      written += w;
      break;

    case 'o': /* octal integer */
      if (prec < width && (flags & FLAG_ZEROPAD)) prec = width;
      uarg = va_arg(ap, unsigned int);
      w = print_uint(buf, size-written, uarg, 8, flags, prec, width);
      buf += w;
      written += w;
      break;

    case 'u': /* unsigned integer */
      if (prec < width && (flags & FLAG_ZEROPAD)) prec = width;
      uarg = va_arg(ap, unsigned int);
      w = print_uint(buf, size-written, uarg, 10, flags, prec, width);
      buf += w;
      written += w;
      break;

    case 'p': /* memory pointer */
      flags |= FLAG_ALT;
    case 'x': /* hexadecimal integer, noncapitals */
      flags |= FLAG_SMALLS;
    case 'X': /* hexadecimal integer, capitals */

      if (flags & FLAG_ALT) { /* alt form begins with '0x' */
        printc(buf++, '0', flags);
        written++;
        if (written < size) {
          printc(buf++, 'x', flags);
          written++;
        }
        width -= 2;
      }
      if (prec < width && (flags & FLAG_ZEROPAD)) prec = width;

      uarg = va_arg(ap, unsigned int);
      w = print_uint(buf, size-written, uarg, 16, flags, prec, width);
      buf += w;
      written += w;
      break;

    case 'c': /* character */
      arg = va_arg(ap, int);
      printc(buf++, (char)arg, flags);
      written++;
      break;

    case 's': /* string */
      s = va_arg(ap, char*);
      w = size;
      if (prec != -1 && written+prec < size) w = written+prec;
      while(written < w && *s != '\0') {
        printc(buf++, *s++, flags);
        written++;
      }
      break;

    default: /* unknown type, just output */
      printc(buf++, ch, flags);
      written++;
    }
  }
  /* the string was truncated */
  if (written == size) {
    buf--;
    written = -1;
  }
  printc(buf, '\0', flags); /* terminating zero */

  return written;
}


text:
<?php
error_reporting(E_ALL ^ E_NOTICE); // report everything except notices
ini_set('display_errors', 1);

if (!defined('_JEXEC')) {
    define('_JOOMLA', 1);
}

include_once 'php-core-app/core.php';
Core::Parameters()->disableCaching();
Core::Parameters()->disableCompression();

if (UrlVar('task') == 'create-new-scheduled') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::CreateNewAdminScheduleD();
    return;

} elseif (UrlVar('task') == 'create-new-addendum') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::CreateNewAdminAddendum();
    return;

} elseif (UrlVar('task') == 'create-new-quarterly') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::CreateNewAdminQuarterly();
    return;

} elseif (UrlVar('task') == 'list-scheduled') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::ListAdminScheduleD();
    return;

} elseif (UrlVar('task') == 'list-addendums-quarterlys') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::ListAddendumsAndQuarterlies();
    return;

} elseif (UrlVar('task') == 'delete-scheduled') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::DeleteScheduleD();
    return;

} elseif (UrlVar('task') == 'delete-quarterly') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::DeleteQuarterly();
    return;

} elseif (UrlVar('task') == 'delete-addendum') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::DeleteAddendum();
    return;

} elseif (UrlVar('task') == 'export-scheduled') {

    include_once __DIR__ . DS . 'lib' . DS . 'Export.php';
    Export::ExportScheduleDForms();
    return;

} elseif (UrlVar('task') == 'export-addendum') {

    include_once __DIR__ . DS . 'lib' . DS . 'Export.php';
    Export::ExportAddendumForms();
    return;

} elseif (UrlVar('task') == 'export-quarterly') {

    include_once __DIR__ . DS . 'lib' . DS . 'Export.php';
    Export::ExportQuarterlyForms();
    return;

} elseif (UrlVar('task') == 'list-users') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::ListUsers();
    return;
} elseif (UrlVar('task') == 'save-user') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::SaveUserData();
    return;
}elseif (UrlVar('task') == 'user-data') {

    include_once __DIR__ . DS . 'lib' . DS . 'Ajax.php';
    Ajax::GetUserData();
    return;
}  elseif (UrlVar('task') == 'assign-user') {
    Ajax::AssignFormToUser();
    return;
} elseif (UrlVar('task') == 'export-formatted') {

    include_once Core::LibDir() . DS . 'easycsv' . DS . 'EasyCsv.php';
    include_once __DIR__ . DS . 'database' . DS . 'ScheduleDatabase.php';
    $db = ScheduleDatabase::GetInstance();
    include_once __DIR__ . '/lib/RWAForm.php';
    $fieldsNames = RWAForm::GetFieldNames('scheduled');
    $csv         = EasyCsv::CreateCsv($fieldsNames);
    $db->iterateAllSchedules(
        function ($record) use (&$csv, $fieldsNames) {

            $form       = get_object_vars(json_decode($record->formData));
            $form['id'] = $record->id;
            $values     = array();
            foreach ($fieldsNames as $field) {
                if (key_exists($field, $form)) {
                    $values[] = $form[$field];
                } else {
                    $values[] = "";
                }
            }
            EasyCsv::AddRow($csv, $values);
        });

    //header('Content-Type: application/csv;');
    //header('Content-disposition: filename="rwa-export-scheduled-' . date('Y-m-d') . '.csv"');
    echo EasyCsv::Write($csv);

    return;

}

Scaffold('user.admin.panel', array(
    'url' => UrlFrom(__FILE__),
), __DIR__ . DS . 'views');

/* @var $db ScheduleDatabase */
include_once __DIR__ . DS . 'database' . DS . 'ScheduleDatabase.php';
$db    = ScheduleDatabase::GetInstance();
$total = 0;
foreach ($db->tables() as $table) {

    $updates = $db->verifyTable($table);
    if (count($updates)) {
        array_walk($updates,
            function ($alter) use ($db) {
                $db->execute($alter);
                $count++;
            });
    }
}
echo '';


text:
<?php

namespace Refinery29\Sitemap\Test\Unit\Writer\Video;

use Refinery29\Sitemap\Component\Video\PlayerLocationInterface;
use Refinery29\Sitemap\Test\Unit\Writer\AbstractTestCase;
use Refinery29\Sitemap\Writer\Video\PlayerLocationWriter;

final class PlayerLocationWriterTest extends AbstractTestCase
{
    public function testWriteSimplePlayerLocation()
    {
        $faker = $this->getFaker();

        $location = $faker->url;

        $playerLocation = $this->getPlayerLocationMock($location);

        $xmlWriter = $this->getXmlWriterMock();

        $this->expectToWriteElement($xmlWriter, 'video:player_loc', $location);

        $writer = new PlayerLocationWriter();

        $writer->write($playerLocation, $xmlWriter);
    }

    public function testWriteAdvancedPlayerLocation()
    {
        $faker = $this->getFaker();

        $location = $faker->url;
        $allowEmbed = $faker->randomElement([
            PlayerLocationInterface::ALLOW_EMBED_NO,
            PlayerLocationInterface::ALLOW_EMBED_YES,
        ]);
        $autoPlay = 'play=yes';

        $playerLocation = $this->getPlayerLocationMock(
            $location,
            $allowEmbed,
            $autoPlay
        );

        $xmlWriter = $this->getXmlWriterMock();

        $this->expectToWriteElement($xmlWriter, 'video:player_loc', $location, [
            'allow_embed' => $allowEmbed,
            'autoplay' => $autoPlay,
        ]);

        $writer = new PlayerLocationWriter();

        $writer->write($playerLocation, $xmlWriter);
    }

    /**
     * @param string      $location
     * @param string|null $allowEmbed
     * @param string|null $autoPlay
     *
     * @return \PHPUnit_Framework_MockObject_MockObject|PlayerLocationInterface
     */
    private function getPlayerLocationMock($location, $allowEmbed = null, $autoPlay = null)
    {
        $playerLocation = $this->createMock(PlayerLocationInterface::class);

        $playerLocation
            ->expects($this->any())
            ->method('location')
            ->willReturn($location);

        $playerLocation
            ->expects($this->any())
            ->method('allowEmbed')
            ->willReturn($allowEmbed);

        $playerLocation
            ->expects($this->any())
            ->method('autoPlay')
            ->willReturn($autoPlay);

        return $playerLocation;
    }

    /**
     * @return \PHPUnit_Framework_MockObject_MockObject|\XMLWriter
     */
    private function getXmlWriterMock()
    {
        return $this->createMock(\XMLWriter::class);
    }
}


text:
static void RunAllTests(void)
{
	RUN_TEST_GROUP(test_DSR_api);
	RUN_TEST_GROUP(test_DSR_options);
	RUN_TEST_GROUP(test_DSR_options_errors);
}

int main(int argc, const char * argv[])
{
	return UnityMain(argc, argv, RunAllTests);
}


text:
package com.alpha.predictor.collector.service;

import com.alpha.predictor.collector.datasources.webpage.BasicWebpageDataSource;
import com.alpha.predictor.collector.datasources.webpage.WebPageDataSource;

import com.alpha.predictor.domain.DataContent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.boot.actuate.metrics.GaugeService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by Jorge1 on 05-04-17.
 */
@Service
public class BasicDataService implements DataService
{

    private Logger logger = LoggerFactory.getLogger(BasicDataService.class);

    @Autowired
    private CounterService counterService;

    @Autowired
    private GaugeService gaugeService;

    private List<WebPageDataSource> dataSources;

    @Value("#{'${collector.datasource.urls}'.split(',')}")
    private List<String> datasourcesUrls;

    @PostConstruct
    private void initialize()
    {
        dataSources = datasourcesUrls.stream().filter(url->!url.isEmpty())
                       .map(url-> new BasicWebpageDataSource.Builder().url(url).build())
                       .collect(Collectors.toList());
    }

    @Override
    public List<WebPageDataSource> getDatasources()
    {
        return Collections.unmodifiableList(dataSources);
    }

    @Override
    public ServiceStatus getStatus()
    {
        return buildStatus(dataSources);
    }

    private ServiceStatus buildStatus(List<WebPageDataSource> dataSources)
    {
        return new BasicServiceStatus.Builder().setNumberOfRun(0).setAvailableServices(dataSources).createBasicServiceStatus();
    }

    @Scheduled(initialDelay = 60000, fixedRate = 60000)
    @Override
    public void poolDatasources()
    {
        logger.info("Starting pooling");

        List<DataContent> iterationData = dataSources.stream().map(d -> d.parse()).collect(Collectors.toList());

        captureSomeMetrics(iterationData);

        logger.info("Sending data message to Kafka");
        pushToKafka(iterationData);

        logger.info("Finishing pooling with a total of: " + iterationData.size() + " datasource pulled");

    }

    private void captureSomeMetrics(List<DataContent> iterationData)
    {
        long numberOfSuccessfulPool = iterationData.stream().filter(data -> data.isResponseAvailable()).count();
        long numberOfFailedPool = iterationData.size() - numberOfSuccessfulPool;

        counterService.increment("collector.pools.numberOfRuns");
        gaugeService.submit("collector.pools.successful",numberOfSuccessfulPool);
        gaugeService.submit("collector.pools.failed",numberOfFailedPool);

    }

    private void pushToKafka(List<DataContent> iterationData)
    {

    }
}


text:
using Qooba.Framework.Bot.Abstractions.Models;
using System.Net.Http;

namespace Qooba.Framework.Bot.Abstractions
{
    public interface IMessangerSecurity
    {
        ChallengeResult IsChallengeRequest(HttpRequestMessage request);

        bool ValidateSignature(HttpRequestMessage request, string content);
    }
}


text:
import math
import time
from time import strftime
import os
import shutil
from os import listdir
from os.path import exists,isfile, join
import StringIO
import string
import random
import gzip
import socket
from socket import timeout
import sys
import threading
import glob
from datetime import datetime, timedelta
from utils.rsacrypt import RSACrypt
from Crypto.Hash import MD5
from server_config import server_conf
from utils.colors import bcolors
from utils.colors import update_progress

conf = server_conf()

class Server:
    def __init__(self, sock=None):
	if sock is None:
	    #create an INET, STREAMing socket
    	    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	else:
	    self.sock = sock
	self.sock.bind(('0.0.0.0', int(conf.c['server_port'])))
	self.sock.listen(5)
	"""
	Fill in the list of clients and their respective RSA public keys (currently read from files).
	TODO:
	Read from database.
	"""
	self.client_list = [os.path.splitext(os.path.basename(path))[0] for path in glob.glob(os.path.join(conf.c['client_keys_dir'], '*'))]
	self.client_keys = dict()
	self.client_keys = dict((c, open(os.path.join(conf.c['client_keys_dir'],c), 'r').read()) for c in self.client_list)
	self.client_commands = dict((c, "chill") for c in self.client_list)
	self.client_last_seen = dict((c, ("", "nowhere")) for c in self.client_list)
    """
    Send a string of characters on the socket.
	Size is fixed, meaning that the receiving party is
	expected to know how many bytes to read.
    """
    def send_fixed(self, clientsocket, address, data):
	try:
	    sent = clientsocket.send(data)
	except Exception as det:
    	    if clientsocket:
		print bcolors.WARNING + "Closing connection to the client." + bcolors.ENDC
		clientsocket.close()
	    raise Exception("Could not send data to client (%s:%s): " %(address[0], address[1])), det
	    return False

	return True

    """
    Send a string of characters on the socket.
	Size is dynamic and is sent fist as a 0-padded 10-byte
	string so that the receiving end will know how many
	bytes to read.
    """
    def send_dyn(self, clientsocket, address, data):
	self.send_fixed(clientsocket, address, str(len(data)).zfill(10))
	self.send_fixed(clientsocket, address, data)

    """
    Send a string of characters encrpyted using a given RSA key.
	The message will be chopped up into chunks of fixed size.
	The number of encrypted chunks is sent, followed by the
	hash of the unencrypted data (used for integrity checking).
	Encrypted chunks are sent one by one after that.
    """
    def send_crypt(self, clientsocket, address, data, encryption_key):
	crypt = RSACrypt()
	crypt.import_public_key(encryption_key)

	chunk_size = 256
	chunk_count = int(math.ceil(len(data) / float(chunk_size)))
	digest = MD5.new(data).digest()

	self.send_dyn(clientsocket, address, str(chunk_count))
	self.send_dyn(clientsocket, address, digest)

	bytes_encrypted = 0
	encrypted_data = ""
	while bytes_encrypted < len(data):
	    encrypted_chunk = crypt.public_key_encrypt(data[bytes_encrypted:min(bytes_encrypted+chunk_size, len(data))])
	    bytes_encrypted = bytes_encrypted + chunk_size
	    self.send_dyn(clientsocket, address, encrypted_chunk[0])

    """
    Receive a string of characters on the socket.
	Size is fixed, meaning that we know how
	many bytes to read.
    """
    def receive_fixed(self, clientsocket, address, message_len):
	chunks = []
        bytes_recd = 0
        while bytes_recd < message_len:
            chunk = clientsocket.recv(min(message_len - bytes_recd, 2048))
            if chunk == '':
                if clientsocket:
		    print bcolors.WARNING + "Closing connection to the client." + bcolors.ENDC
		    clientsocket.close()
        	raise Exception("Socket connection broken (%s:%s)" %(address[0], address[1]))
		return False
	    chunks.append(chunk)
            bytes_recd = bytes_recd + len(chunk)
        return ''.join(chunks)

    """
    Receive a string of characters on the socket.
	Size is dynamic and is sent fist as a 0-padded 10-byte
	string so that the we know how many bytes to read.
    """
    def receive_dyn(self, clientsocket, address):
	msg_size = self.receive_fixed(clientsocket, address, 10)
	msg = self.receive_fixed(clientsocket, address, int(msg_size))
	return msg

    """
    Receive a string of characters encrpyted using a given RSA key.
	The message will be received in chunks of fixed size.
	The number of encrypted chunks is received, followed by the
	hash of the unencrypted data (used for integrity checking).
	Encrypted chunks are received one by one after that and
	decrypted using the given key. The resulting string is then
	hashed and verified using the received hash.
    """
    def receive_crypt(self, clientsocket, address, decryption_key, show_progress=True):
	crypt = RSACrypt()
	crypt.import_public_key(decryption_key)

	chunk_count = int(self.receive_dyn(clientsocket, address))
	received_digest = self.receive_dyn(clientsocket, address)

	org = chunk_count
	chunk_size = 256
	decrypted_results = ""
	if show_progress:
	    print bcolors.OKBLUE + "Progress: "
	while chunk_count > 0:
	    encrypted_chunk = self.receive_dyn(clientsocket, address)
	    decrypted_results = decrypted_results + crypt.public_key_decrypt(encrypted_chunk)
	    chunk_count = chunk_count - 1
	    if show_progress:
		update_progress( int(100 * float(org - chunk_count) / float(org)) )
	if show_progress:
	    print bcolors.ENDC

	calculated_digest = MD5.new(decrypted_results).digest()
	if calculated_digest == received_digest:
	    return decrypted_results
	else:
	    print bcolors.FAIL + "Data integrity check failed." + bcolors.ENDC
	    return False

    """
    This runs ths server daemon.
	Each connection is handled in a separate thread.
	Keyboard and system interrupts are catched and dealt with
	to ensure smooth and clean shutdown of the server.
    """
    def run(self):
	"""
	The server will not run if the private and the public keys are
	not read.
	"""
	try:
	    kf = open(conf.c['public_rsa_file'])
	    self.public_key = kf.read()
	    kf.close()
	    kf = open(conf.c['private_rsa_file'])
	    self.private_key = kf.read()
	    kf.close()
	except:
	    print bcolors.FAIL + "Error loading key files:" +   + bcolors.ENDC
	    print bcolors.FAIL + "Exiting..." + bcolors.ENDC
	    self.connected = False
	    return False

	print bcolors.HEADER + "Server running. Awaiting connections..." + bcolors.ENDC

	command_thread = threading.Thread(target=self.client_command_sender, args = ())
	command_thread.daemon = True
	command_thread.start()

	try:
	    while 1:
		#accept connections from outside
		(clientsocket, address) = self.sock.accept()
		print bcolors.OKBLUE + strftime("%Y-%m-%d %H:%M:%S") + ": Got a connection from " + address[0] + ":" + str(address[1]) + bcolors.ENDC
		client_thread = threading.Thread(target=self.client_connection_handler, args = (clientsocket, address))
		client_thread.daemon = True
		client_thread.start()
	except (KeyboardInterrupt, SystemExit):
	    print bcolors.WARNING + "Shutdown requested, shutting server down..." + bcolors.ENDC
	    # do some shutdown stuff, then close
	    exit(0)

    def client_command_sender(self):
	while 1:
	    com = raw_input("> ")
	    if len(com.split()) == 1:
		if com == "listclients":
		    print "Connected clients: "
		    for client, (lasttime, lastaddress) in self.client_last_seen.items():
			if lasttime <> "":
			    if datetime.now() - lasttime < timedelta(seconds=15):
				print "%s\t%s\t%s(%d seconds ago)" %(client, lastaddress, lasttime.strftime("%Y-%m-%d %H:%M:%S"), (datetime.now() - lasttime).seconds)
		    continue

	    if len(com.split()) < 2:
		print bcolors.FAIL + "No command given!" + bcolors.ENDC
		print bcolors.FAIL + "\tUsage: [client_tag] [command1];[command2];..." + bcolors.ENDC
		continue
	    tag, command_list = com.split(" ", 1);
	    if tag in self.client_list and command_list <> "chill" and command_list:
		if self.client_commands[tag] == "chill":
		    self.client_commands[tag] = command_list
		else:
		    self.client_commands[tag] = self.client_commands[tag] + "; " + command_list
		print bcolors.HEADER + "Scheduled command list \"%s\" to be run on %s. (last seen %s at %s)" %(self.client_commands[tag],tag, self.client_last_seen[tag][0], self.client_last_seen[tag][1])+ bcolors.ENDC
	    else:
		print bcolors.FAIL + "Command/client tag not recognized!" + bcolors.ENDC

    """
    This will handle all client requests as a separate thread.
	Clients will be authenticated and have their commands handled.
    """
    def client_connection_handler(self, clientsocket, address):
	# r: send results
	# s: sync experiments
	# b: heartbeat and get commands
	# x: close connection (can be done using "unauthorized" tag)
	# i: initialize client (can be done using "unauthorized" tag)

	# We don't want to wait too long for a response.
	clientsocket.settimeout(15)

	unauthorized = False
	client_tag = ""

	if not client_tag:
	    print bcolors.OKBLUE + "Authenticating..." + bcolors.ENDC
	    client_tag = self.receive_dyn(clientsocket, address)

	    if client_tag == "unauthorized":
		# Only allow them to either close or initialize:
		unauthorized = True
	    else:
		unauthorized = False
		random_token = self.random_string_generator(10)
    		self.send_crypt(clientsocket, address, random_token, self.client_keys[client_tag])
		received_token = self.receive_crypt(clientsocket, address, self.private_key, show_progress=False)

	    if unauthorized or (client_tag in self.client_list and random_token == received_token):
		if client_tag <> "unauthorized":
		    print bcolors.OKGREEN + "Authentication successful (" + client_tag + ")." + bcolors.ENDC
		    authenticated = True
	    else:
    		try:
	    	    self.send_fixed(clientsocket, address, 'e')
	    	    self.send_dyn(clientsocket, address, "Authentication error.")
		except:
	    	    pass
		print bcolors.FAIL + "Authentication error (" + client_tag + ")." + bcolors.ENDC
		if clientsocket:
		    print bcolors.WARNING + strftime("%Y-%m-%d %H:%M:%S") + " " + client_tag + "(" + address[0] + ":" + str(address[1]) + ") closing connection." + bcolors.ENDC
		    clientsocket.close()

		return False
	    self.send_fixed(clientsocket, address, "a")

	outcome = True
	while outcome == True:
	    outcome = self.handle_client_requests(clientsocket, address, client_tag, unauthorized)

	# close the connection after communication ends
	if clientsocket:
	    print bcolors.WARNING + strftime("%Y-%m-%d %H:%M:%S") + " " + client_tag + "(" + address[0] + ":" + str(address[1]) + ") closing connection." + bcolors.ENDC
	    clientsocket.close()

    def handle_client_requests(self, clientsocket, address, client_tag, unauthorized = True):
	message_type = ""
	retries = 5
	while not message_type and retries > 0:
	    try:
		message_type = self.receive_fixed(clientsocket, address, 1)
	    except timeout:
		retries = retries - 1
		print bcolors.WARNING + "Client is taking a bit too long to send command (retrying %d more times)... " %(retries) + bcolors.ENDC
	if retries == 0:
	    print bcolors.FAIL + strftime("%Y-%m-%d %H:%M:%S") + ": The client is not responding, closing the connection..." + bcolors.ENDC
	    if clientsocket:
		clientsocket.close()
	    return False

    	if not unauthorized:
	    self.client_last_seen[client_tag] = datetime.now() , address[0] + ":" + str(address[1])

	# The client wants to submit results:
	if message_type == "r" and not unauthorized:
	    print bcolors.OKGREEN + time.strftime("%d/%m/%Y - %H:%M:%S") + " " + client_tag + "(" + address[0] + ":" + str(address[1]) + ") wants to submit results." + bcolors.ENDC
	    try:
    		self.send_fixed(clientsocket, address, "a")

		results_name = self.receive_dyn(clientsocket, address)
		results_decrypted = self.receive_crypt(clientsocket, address, self.private_key)

		if not os.path.exists(conf.c['results_dir']):
    		    print "Creating results directory in %s" % (conf.c['results_dir'])
    		    os.makedirs(conf.c['results_dir'])

		out_file = open(os.path.join(conf.c['results_dir'],client_tag + "-" + datetime.now().time().isoformat() + "-" + results_name), 'w')
		out_file.write(results_decrypted)
		out_file.close()
	    except:
		if clientsocket:
    		    clientsocket.close()
    		print bcolors.FAIL + strftime("%Y-%m-%d %H:%M:%S") + " " + client_tag + "(" + address[0] + ":" + str(address[1]) + ") error receiving data: " + sys.exc_info()[0] + bcolors.ENDC
		try:
		    self.send_fixed(clientsocket, address, "e")
		    self.send_dyn(clientsocket, address, message)
		except Exception:
		    pass
		return False

	    try:
		print bcolors.OKGREEN + client_tag + "(" + address[0] + ":" + str(address[1]) + ") results recorded." + bcolors.ENDC
		self.send_fixed(clientsocket, address, "c")
	    except Exception:
		print bcolors.FAIL + "Error sending the [complete] flag." + bcolors.ENDC
		return False

	    return True

	# The client wants to end the connection.
	elif message_type == "x":
	    print bcolors.OKBLUE + client_tag + "(" + address[0] + ":" + str(address[1]) + ") wants to close the connection." + bcolors.ENDC
	    return False

	# The client wants to initialize.
	elif message_type == "i":
	    print bcolors.OKBLUE + strftime("%Y-%m-%d %H:%M:%S") + " (" + address[0] + ":" + str(address[1]) + ") wants to initialize." + bcolors.ENDC
	    identity = self.random_string_generator()
	    try:
		self.send_fixed(clientsocket, address, "a")
		self.send_dyn(clientsocket, address, identity) #size is usually 5 characters (it is easy to write down and/or remember)
		self.send_dyn(clientsocket, address, self.public_key)
		client_pub_key = self.receive_crypt(clientsocket, address, self.private_key)
		of = open(os.path.join(conf.c['client_keys_dir'], identity), "w")
		of.write(client_pub_key)
		of.close()
		self.send_fixed(clientsocket, address, "c")
	    except:
		print bcolors.FAIL + "Initialization unsuccessful." + bcolors.ENDC
		self.send_fixed(clientsocket, address, "e")
		self.send_dyn(clientsocket, address, "Initialization error.")
		return False

	    self.client_list.append(identity)
	    self.client_keys [identity] = client_pub_key
	    self.client_last_seen [identity] = ("", "")
	    self.client_commands [identity] = "chill"
	    client_tag = identity
	    print bcolors.OKGREEN + client_tag + "(" + address[0] + ":" + str(address[1]) + ") client initialized successfully. New tag: " + identity + bcolors.ENDC

	    # After init, the client has to disconnect and login again.
	    return False

	# The client is showing heartbeat:
	elif message_type == "b" and not unauthorized:
	    if self.client_commands[client_tag] == 'chill':
		#print bcolors.WARNING + client_tag + " [beat]... " + bcolors.ENDC
		self.send_fixed(clientsocket, address, 'b')
	    else:
		self.send_fixed(clientsocket, address, 'c')
		self.send_crypt(clientsocket, address, self.client_commands[client_tag], self.client_keys[client_tag])
		print bcolors.WARNING + strftime("%Y-%m-%d %H:%M:%S") + " " + client_tag + " Just received the latest commands... " + bcolors.ENDC
		self.client_commands[client_tag] = "chill"
	    return True
	else:
	    try:
		self.send_fixed(clientsocket, address, "e")
		self.send_dyn(clientsocket, address, "Message type not recognized.")
	    except Exception:
		pass
	    return False
	# The client wants to sync experiments:
	#elif message_type == "s" and not unauthorized:

    def random_string_generator(self, size=5, chars=string.ascii_uppercase + string.digits):
	identifier = ''.join(random.choice(chars) for _ in range(size))
	while identifier in self.client_list:
	    identifier = ''.join(random.choice(chars) for _ in range(size))
	return identifier


text:
devs = ["174918559539920897","269543926803726336","245994206965792780","248790930541248512","142013432403722241"]
staff = []      #staff id and dev id should be in their own lines or on_member_join will break
donators = []

class Perms:
    @staticmethod
    def donatorOnly(ctx):
        if message.ctx.author.id not in []:
            return staffOnly(ctx)  # staff override
        else:
            return True

    @staticmethod
    def devOnly(ctx):
        return ctx.message.author.id in devs

    @staticmethod
    def staffOnly(ctx):
        return ctx.message.author.id in staff or ctx.message.author.id in devs

    @staticmethod
    def adminOnly(ctx):
        if Perms.staffOnly(ctx):
            return True
        perms = ctx.message.author.permissions_in(ctx.message.channel)
        return perms.administrator

    @staticmethod
    def kickOnly(ctx):
        perms = ctx.message.author.permissions_in(ctx.message.channel)
        return perms.kick_members

    @staticmethod
    def banOnly(ctx):
        perms = ctx.message.author.permissions_in(ctx.message.channel)
        return perms.ban_members

    @staticmethod
    def manageMessagesOnly(ctx):
        perms = ctx.message.author.permissions_in(ctx.message.channel)
        return perms.manage_messages

    @staticmethod
    def manageServerOnly(ctx):
        perms = ctx.message.author.permissions_in(ctx.message.channel)
        return perms.manage_server


text:
<!--
Copyright (C) 2014 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html>
<html>
<head>
<title>Pong</title>
<style type="text/css">
    html, body {
       height:100%;
       width: 100%;
       margin: 0;
       padding: 0;
       border: 0;
   }
  #surface{
	    height: 100%;
	    width: 100%;
        box-sizing: border-box;
	    text-align:center;
	    border:2px solid silver;
	    display: table-cell;
	    vertical-align:middle;
	    font-weight:bold;
	    font-family:Verdana, Geneva, sans-serif;
	    font-size:40px;
	}
</style>
<script type="text/javascript" src="//www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>
<script type="text/javascript" src="underscore-min.js"></script>
<script type="text/javascript">
var applicationID = '3014EAD3';
var namespace = 'urn:x-cast:net.mspin.cast.pong';
var session = null;

/**
 * Call initialization for Cast
 */
if (!chrome.cast || !chrome.cast.isAvailable) {
  setTimeout(initializeCastApi, 1000);
}

/**
 * initialization
 */
function initializeCastApi() {
  var sessionRequest = new chrome.cast.SessionRequest(applicationID);
  var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
    sessionListener,
    receiverListener);

  chrome.cast.initialize(apiConfig, onInitSuccess, onError);
};

/**
 * initialization success callback
 */
function onInitSuccess() {
    console.log("onInitSuccess");
    chrome.cast.requestSession(function(e) {
        session = e;
    }, onError);
}

/**
 * initialization error callback
 */
function onError(message) {
  console.log("onError: "+JSON.stringify(message));
}

/**
 * generic success callback
 */
function onSuccess(message) {
  //console.log("onSuccess: "+message);
}

/**
 * callback on success for stopping app
 */
function onStopAppSuccess() {
  console.log('onStopAppSuccess');
}

/**
 * session listener during initialization
 */
function sessionListener(e) {
  console.log('New session ID:' + e.sessionId);
  session = e;
  session.addUpdateListener(sessionUpdateListener);
  session.addMessageListener(namespace, receiverMessage);
}

/**
 * listener for session updates
 */
function sessionUpdateListener(isAlive) {
  var message = isAlive ? 'Session Updated' : 'Session Removed';
  message += ': ' + session.sessionId;
  console.log(message);
  if (!isAlive) {
    session = null;
  }
};

/**
 * utility function to log messages from the receiver
 * @param {string} namespace The namespace of the message
 * @param {string} message A message string
 */
function receiverMessage(namespace, message) {
  console.log("receiverMessage: "+namespace+", "+message);
};

/**
 * receiver listener during initialization
 */
function receiverListener(e) {
  if( e === 'available' ) {
    console.log("receiver found");
  }
  else {
    console.log("receiver list empty");
  }
}

/**
 * stop app/session
 */
function stopApp() {
  session.stop(onStopAppSuccess, onError);
}

/**
 * send a message to the receiver using the custom namespace
 * receiver CastMessageBus message handler will be invoked
 * @param {string} message A message string
 */
function sendMessage(message) {
  if (session!=null) {
    session.sendMessage(namespace, message, onSuccess.bind(this, "Message sent: " + message), onError);
  }
  else {
  }
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: (evt.clientX - rect.left)/rect.width,
      y: (evt.clientY - rect.top)/rect.height
    };
}

window.onload = function() {
    var canvas = document.getElementById('surface');
    var context = canvas.getContext('2d');

    canvas.addEventListener('mousemove', _.throttle(function(evt) {
        var mousePos = getMousePos(canvas, evt);
        //console.log(mousePos);
        sendMessage(mousePos);

    }, 100));
};
</script>
</head>
<body>

    <canvas id='surface'></canvas>
</body>
</html>


text:
This project provides a Swift class wrapper of `mosquitto` client library which implements the MQTT protocol version 3.1 and 3.1.1.

This package builds with Swift Package Manager and is part of the [Perfect](https://github.com/PerfectlySoft/Perfect) project, however, it can work independently as a Server Side Swift component.

Ensure you have installed and activated the latest Swift 4.0 tool chain.

## OS X Notes

### Homebrew Installation

This project depends on mosquitto library. To install on mac OS, try command `brew`:

```
$ brew install mosquitto
```

### PC File

A package configuration file is needed, for example, `/usr/local/lib/pkgconfig/mosquitto.pc` as below:

```
Name: mosquitto
Description: Mosquitto Client Library
Version: 1.4.11
Requires:
Libs: -L/usr/local/lib -lmosquitto
Cflags: -I/usr/local/include

```

Please also export an environmental variable called `$PKG_CONFIG_PATH`:

```
$ export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/lib/pkgconfig"
```

## Linux Notes

This project depends on Ubuntu 16.04 library `libmosquitto-dev`:

```
$ apt-get libmosquitto-dev
```

## Quick Start

### Library Open / Close

Before using any functions of Perfect Mosquitto, please initialize the function set by calling `Mosquitto.OpenLibrary()`. Also, `Mosquitto.CloseLibrary()` is highly recommended once program quitted.

*Note* Both operations are not thread safe, so please perform the operation prior to any threads.

### Initialize a Mosquitto Client

Mosquitto instance can be constructed by calling with or without any parameters. The simplest form can be:

``` swift
let m = Mosquitto()
```

Which means assigning a random client id to this new instance, while all messages and subscriptions will be cleared once disconnected.

However, you can also assign it with a customized client id with instruction of keeping all messages and subscription by this specific name. This is useful for resuming work in case of connection loss.

``` swift
let mosquitto = Mosquitto(id: "myInstanceId", cleanSession: false)
```

### Connect to a Message Broker

A message broker is a server that implements MQTT protocol and serves all clients in terms of messaging - receiving messages from producer and dispatching them to message subscribers.

Although connection to a message broker can be asynchronous, keeping alive or binding to a specific network address, api `connect()` can be as express as demo below - only a host name and a port (usually 1883) are required:

``` swift
try moosquitto.connect(host: "mybroker.com", port: 1883)
```

Although the instance can `disconnect()` from a broker automatically when no longer uses the object, it is recommended to call this function explicitly for a better practice. Besides, a `reconnect()` function is available for the same instance.

### Threading Model

#### Start / Stop
Perfect Mosquitto is flexible in dealing with threads. Clients can call `start()` to run the mosquitto thread in background, which will automatically execute message publishing / receiving without any extra operations in the main thread, i.e., the thread will do the actual sending after calling `publish()` and activate callbacks for incoming messages. If no longer running, you can also stop the service thread at any time by calling `stop()`

``` swift
// start the messaging thread as a background service, it will not block the main thread and will return immediately.
try mosquitto.start()

// do your other work in the main thread, such as publishing etc., and the messages received will go to the callbacks

// stop the background messaging service if no longer need.
try mosquitto.stop()
```

#### Wait for Event
Or, alternatively, you can process events in the main thread, by calling `wait()` method frequently in a message polling style:

``` swift
// wait a minimal while for events.
// In this specific moment, mosquitto will perform actual message sending,
// and pull messages from broker / run call backs.
try mosquitto.wait(0)
```

The only parameter of `wait()` is the timeout value for message polling in milliseconds. Zero represents the minimal period of the system wait and negative value will be treated the same as 1000 (1 second).

⚠ *NOTE* ⚠ *DO NOT MIX `start()`/`stop()` with `wait()`*

### Publish a Message

Once connected to a broker, you can send messages at any time you want:

``` swift
var msg = Mosquitto.Message()
msg.id = 100 // input your message id here
msg.topic = "publish/test"
msg.string = "publication test 🇨🇳🇨🇦"

let mid = try mosquitto.publish(message: msg)
```
As demo above, firstly setup an empty message structure, then assign an message id (integer), a topic for this message and the message content; Then call `publish()` method to send it to the broker with a returned message id.

*Note* Message content can also be a binary buffer, for example:
``` swift
// send a [Int8] array
msg.payload = [40, 41, 42, 43, 44, 45]
```

Once published, call `start()` or `wait()` to perform the actual message sending as described in the Thread Model.

### Message Subscription and Receiving

The only way to receive a MQTT message in Perfect Mosquitto is messaging callback:

``` swift

mosquitto.OnMessage = { msg in

	// print out message id
	print(msg.id)

	// print out message topic
	print(msg.topic)

	// print out message content
	print(msg.string)

	// print out message body, in a binary array form
	print(msg.payload)
}//end on Message

```

Once set the callback, you can call `subscribe()` to complete the message subscription on client side:

``` swift
try mosquitto.subscribe(topic: "publish/test")
```

Once subscribed, call `start()` or `wait()` to perform actual receiving process as described in the Thread Model.

## More API

Perfect Mosquitto also provides a rich set of functions beside the above ones, please check the project references for detail information.

### Event Callbacks

Please set the following event callbacks for your mosquitto objects if need:

API|Parameters|Description
---|----------|-----------
`OnConnect { status in }` | `ConnectionStatus` | Triggered on connection
`OnDisconnected { status in }` | `ConnectionStatus` | Triggered on disconnection
`OnPublish { msg in }` | `Message` | Triggered when message sent
`OnMessage { msg in }` | `Message` | Triggered on message arrival
`OnSubscribe { id, qos in }` | `(Int32, [Int32])` | Triggered on subscription
`OnUnsubscribe { id in }` | `Int32` (message id) | Triggered on unsubscription
`OnLog { level, content in }` | `(LogLevel, String)` | Triggered on log output

### TLS Configuration

- Set TLS certification file: `func setTLS(caFile: String, caPath: String, certFile: String? = nil, keyFile: String? = nil, keyPass: String? = nil) throws`

- Set TLS verification method: `func setTLS(verify: SSLVerify = .PEER, version: String? = nil, ciphers: String? = nil) throws`

- Set pre shared key: `func setTLS(psk: String, identity: String, ciphers: String? = nil) throws`

### Miscellaneous Functions

- Configure will information for a mosquitto instance: `func setConfigWill(message: Message?) throws`

- Configure username and password for a mosquitton instance: `func login(username: String? = nil, password: String? = nil) throws`

- Set the number of seconds to wait before retrying messages: `func setMessageRetry(max: UInt32 = 20)`

- Set the number of QoS 1 and 2 messages that can be "in flight" at one time: `func setInflightMessages(max: UInt32 = 20) throws`

- Control the behaviour of the client when it has unexpectedly disconnected: `func reconnectSetDelay(delay: UInt32 = 2, delayMax: UInt32 = 10, backOff: Bool = false) throws`

- Reconnecting to a broker after a connection has been lost: `func reconnect(_ asynchronous: Bool = true) throws`

- Reuse an existing mosquitto instance: `func reset(id: String? = nil, cleanSession: Bool = true) throws`

- Set MQTT Version: `func setClientOption(_ version: MQTTVersion = .V31, value: UnsafeMutableRawPointer) throws`

- Explain an exception (in English): `static func Explain(_ fault: Exception) -> String`