text:
/****************************************************************************
*   PROJECT: Squeak port for Win32 (NT / Win95)
*   FILE:    sqWin32MIDI.c
*   CONTENT: Minimal MIDI interface
*
*   AUTHOR:  Andreas Raab (ar)
*   ADDRESS: University of Magdeburg, Germany
*   EMAIL:   raab@isg.cs.uni-magdeburg.de
*
*   NOTES:
*     1) For MIDI output the MIDI mapper is reported as first device
*        (e.g., portNum = 0) making it the default device.
*     2) The VM level scheduler uses a heap as output buffer.
*
*****************************************************************************/
#include <windows.h>
#include <mmsystem.h>
#include "sq.h"
#include "MIDIPlugin.h"

#ifndef NO_MIDI

#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
# define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
#endif

/*** MIDI Parameters (used with sqMIDIParameter function) ***/

#define sqMIDIInstalled				1
/* Read-only. Return 1 if a MIDI driver is installed, 0 if not.
   On OMS-based MIDI drivers, this returns 1 only if the OMS
   system is properly installed and configured. */

#define sqMIDIVersion				2
/* Read-only. Return the integer version number of this MIDI driver.
   The version numbering sequence is relative to a particular driver.
   That is, version 3 of the Macintosh MIDI driver is not necessarily
   related to version 3 of the Win95 MIDI driver. */

#define sqMIDIHasBuffer				3
/* Read-only. Return 1 if this MIDI driver has a time-stamped output
   buffer, 0 otherwise. Such a buffer allows the client to schedule
   MIDI output packets to be sent later. This can allow more precise
   timing, since the driver uses timer interrupts to send the data
   at the right time even if the processor is in the midst of a
   long-running Squeak primitive or is running some other application
   or system task. */

#define sqMIDIHasDurs				4
/* Read-only. Return 1 if this MIDI driver supports an extended
   primitive for note-playing that includes the note duration and
   schedules both the note-on and the note-off messages in the
   driver. Otherwise, return 0. */

#define sqMIDICanSetClock			5
/* Read-only. Return 1 if this MIDI driver''s clock can be set
   via an extended primitive, 0 if not.*/

#define sqMIDICanUseSemaphore		6
/* Read-only. Return 1 if this MIDI driver can signal a semaphore
   when MIDI input arrives. Otherwise, return 0. If this driver
   supports controller caching and it is enabled, then incoming
   controller messages will not signal the semaphore. */

#define sqMIDIEchoOn				7
/* Read-write. If this flag is set to a non-zero value, and if
   the driver supports echoing, then incoming MIDI events will
   be echoed immediately. If this driver does not support echoing,
   then queries of this parameter will always return 0 and
   attempts to change its value will do nothing. */

#define sqMIDIUseControllerCache	8
/* Read-write. If this flag is set to a non-zero value, and if
   the driver supports a controller cache, then the driver will
   maintain a cache of the latest value seen for each MIDI controller,
   and control update messages will be filtered out of the incoming
   MIDI stream. An extended MIDI primitive allows the client to
   poll the driver for the current value of each controller. If
   this driver does not support a controller cache, then queries
   of this parameter will always return 0 and attempts to change
   its value will do nothing. */

#define sqMIDIEventsAvailable		9
/* Read-only. Return the number of MIDI packets in the input queue. */

#define sqMIDIFlushDriver			10
/* Write-only. Setting this parameter to any value forces the driver
   to flush its I/0 buffer, discarding all unprocessed data. Reading
   this parameter returns 0. Setting this parameter will do nothing
   if the driver does not support buffer flushing. */

#define sqMIDIClockTicksPerSec		11
/* Read-only. Return the MIDI clock rate in ticks per second. */

#define sqMIDIHasInputClock			12
/* Read-only. Return 1 if this MIDI driver timestamps incoming
   MIDI data with the current value of the MIDI clock, 0 otherwise.
   If the driver does not support such timestamping, then the
   client must read input data frequently and provide its own
   timestamping. */

/***************************************************************************
 Driver internals
 ***************************************************************************/

#define NoteOnCmd		0x90
#define NoteOffCmd		0x80
#define PgmChngCmd		0xC0
#define ControlCmd		0xB0
#define PolyPressCmd	0xA0
#define ChanPressCmd	0xD0
#define PchWheelCmd		0xE0
#define SysExCmd		0xF0

/* The length of meta events for easier processing */
static int midiMetaEventLengths[16] = {
 -1, /* 0xF0: System Exclusive -> read until (including) next status byte */
  2, /* 0xF1: MTC Quarter Frame; 2 bytes */
  3, /* 0xF2: Song Position Pointer; 3 bytes */
  2, /* 0xF3: Song Select; 2 bytes */
  0, /* 0xF4: Unassigned -> read up to next status byte */
  0, /* 0xF5: Unassigned -> read up to next status byte */
  1, /* 0xF6: Tune Request; 1 byte */
  1, /* 0xF7: End of System Exclusive; should not happen */
  1, /* 0xF8: MIDI Clock; 1 byte */
  0, /* 0xF9: Unassigned -> read up to next status byte */
  1, /* 0xFA: MIDI Start; 1 byte */
  1, /* 0xFB: MIDI Continue; 1 byte */
  1, /* 0xFC: MIDI Stop; 1 byte */
  0, /* 0xFD: Unassigned -> read up to next status byte */
  1, /* 0xFE: Active Sense; 1 byte */
  1  /* 0xFF: Reset; 1 byte */
};

/***************************************************************
 * Global state variabless
 */
static int isControllerCaching = 0;
static int isEchoEnabled = 0;

/***************************************************************
 * Controller value caches -- This is the minimum complement
 * A "larger" driver would cache 128*16 controllers and 128*16 key pressures
 */
typedef struct sqControllerCache {
  unsigned char sqControllers[128];  /* Controller value table */
  unsigned char sqKeyPressures[128]; /* Polyphonic key pressure table */
  unsigned char sqChanPressures[16]; /* Channel pressure value table */
  int sqPitchBend[16];               /* The value of the pitch wheel */
} sqControllerCache;

/***************************************************************
 Global definitions
 ***************************************************************/

/* MAX_MIDI_BUFFER defines the maximum number of midi packets we handle.*/
#define MAX_MIDI_BUFFER 1024
#define MAX_SYSEX_BUFFER 512

/* Maximum number of devices supported */
#define MAX_DEVICES 32

/* Flags for midi port */
#define MIDI_IN_DEVICE 1
#define MIDI_OUT_DEVICE 2
#define PENDING_SYSEX 4

/***************************************************************
 The MIDI port structure
 ***************************************************************/
typedef struct sqMidiOutEvent {
  DWORD data;
  DWORD stamp;
} sqMidiOutEvent;

typedef struct sqMidiInEvent {
  DWORD data;
  DWORD stamp;
} sqMidiInEvent;

typedef struct sqMidiPort {
  HANDLE handle;    /* The actual MIDI in/out handle */
  DWORD flags;      /* Flags (including direction and stats) */
  TCHAR name[MAXPNAMELEN+1]; /* This port's name */

  /*************************************/
  /* output stuff                      */
  /*************************************/

  /* buffer for pending short messages */
  unsigned char  pendingCommand[4];
  DWORD pendingLength;    /* current length of the pending command */
  DWORD pendingSize;      /* Remaining data of the pending command */
  DWORD pendingStamp;     /* Stamp of the pending command */

  /* events used during output */
  HANDLE outBufferMutex;  /* we better synchronize access to the output buffer */
  HANDLE outBufferData;   /* signaled whenever the first event changes */
  HANDLE schedulerThread; /* The thread for scheduling MIDI messages */

  /* output buffer */
  sqMidiOutEvent *outBuffer;  /* output buffer */
  DWORD nOutEvents;           /* items in buffer */

  /* sysex buffer */
  unsigned char *sysExBuffer; /* sysex buffer */
  DWORD sysExLength;          /* length of sysex buffer */

  /*************************************/
  /* input stuff                       */
  /*************************************/

  /* buffer for pending input */
  DWORD pendingInputStamp;    /* The stamp of the pending input */
  DWORD pendingInputData;     /* pending input data */

  /* input buffer */
  int   semaphore;  /* The Smalltalk semaphore to signal on input */
  sqMidiInEvent *inBuffer;    /* input buffer */
  DWORD inBufferStart;        /* read start   */
  DWORD inBufferEnd;          /* read end     */

  /* controller cache */
  sqControllerCache cache;
} sqMidiPort;

/* The number of MIDI devices for input and output */
static int midiOutNumDevices = 0;
static int midiInNumDevices = 0;

/* The MIDI ports */
static sqMidiPort *(midiPorts[MAX_DEVICES]);

/* Input event and thread */
static HANDLE midiInputEvent  = (HANDLE) 0;
static HANDLE midiInputThread = (HANDLE) 0;

/* a list of MIDIHDRs which might be recycled when sending SysEx messages */
static MIDIHDR *midiHeaderList = NULL;

#ifndef NDEBUG
#define DBGPRINTF warnPrintf
#else
#define DBGPRINTF
#endif

/*************************************************************************************
 Heap functions:
   For VM level scheduling we use a heap structure. The idea is that events
   coming in may not be ordered (since they will scheduled by the VM) and
   that completely sorting the output buffer takes longer than the incremental
   update. Note that the actual implementation below relies on one-based arrays
   (yes -- I've taken this code from my Smalltalk class Heap ;-)) AR
 *************************************************************************************/

/* adjust the heap after adding an element */
static void midiOutHeapUpFrom(sqMidiPort *port,int index)
{ sqMidiOutEvent *buf, event, temp;
  int j, k, size;

  buf = port->outBuffer;
  size = port->nOutEvents;
  /* HACK! Start from one-based indexes */
  buf--;
  /* Start checking the heap */
  if(index < 1) return;
  k = index;
  event = buf[index];
  while(k > 1)
    {
      j = k / 2;
      temp = buf[j];
      if(event.stamp >= temp.stamp) break; /* heap ok */
      buf[k] = temp;
      k = j;
    }
  buf[k] = event;
}

/* Remove the first element from the heap and adjust it. */
static void midiOutHeapRemoveFirst(sqMidiPort *port)
{ sqMidiOutEvent *buf, event;
  int j,k,n, size;

  buf = port->outBuffer;
  size = --port->nOutEvents;
  /* HACK! Start from one-based indexes */
  buf--;
  /* replace top item in heap with last one */
  event = buf[size+1];
  /* adjust heap */
  n = size / 2;
  k = 1;
  while(k <= n) {
    j = 2*k;
    if(j < size && (buf[j+1].stamp < buf[j].stamp)) j++;
    buf[k] = buf[j];
    k = j;
  };
  buf[k] = event;
  midiOutHeapUpFrom(port,k);
}

/**************************************************************************************
   midiInNotifyThread: This function runs an endless loop and whenever
                       midiInputEvent is signaled it forwards the change in state
                       to the associated Squeak semaphore
  *************************************************************************************/
static DWORD WINAPI midiNotifyThread(DWORD ignored)
{ int i;
  sqMidiPort *port;

  while(1)
    {
      WaitForSingleObject(midiInputEvent, INFINITE);
      for(i=0;i<MAX_DEVICES;i++)
        {
          port = midiPorts[i];
          if(port)
            if( (port->inBufferStart != port->inBufferEnd) && port->semaphore)
              synchronizedSignalSemaphoreWithIndex(port->semaphore);
        }
    }
  /* not reached */
  return 0;
}

/**************************************************************************************
   midiInCallback: The callback function called whenever a midi message is received.
                   This function is called from a different (real-time) thread and thus
                   must be *very* cautious of what function it calls. We do only call
                   two of the functions allowed from within MIDI callbacks, e.g.,
                   midiOutShortMsg and SetEvent
  *************************************************************************************/
static void CALLBACK midiInCallback(HMIDIIN  hMidiIn,UINT  uMsg, DWORD_PTR  dwUser,
                             DWORD  dwParam1, DWORD  dwParam2)
{ int cmd, cmdLen;
  sqMidiInEvent *dst;
  int channel, value, value2;
  DWORD data;
  sqMidiPort *port = (sqMidiPort*)dwUser;

  /* SysEx messages are ignored (sent with uMsg == MIM_LONG_DATA) */
  if(uMsg != MIM_DATA) return;
  /* Short Message:
          dwParam1: DWORD packed command with first byte of the message in the low-order byte.
          dwParam2: msecs since midiInStart() has been called
     MIDI messages received from a MIDI input port have running status disabled;
     each message is expanded to include the MIDI status byte.
     This message is not sent when a MIDI system-exclusive message is received. */
  cmd = dwParam1 & 0xF0;
#if 0
  /* Echoing should go here but we don't have it yet */
  if(isEchoEnabled)
    for(i=0;i<MAX_DEVICES;i++)
      if(midiPorts[i])
        if(midiPorts[i]->flags & MIDI_OUT_DEVICE)
          midiOutShortMsg((HMIDIOUT)(midiPorts[i]->handle), dwParam1);
#endif
  if (isControllerCaching)
    { /* Cache controller values in the driver */
      switch(cmd) {
        case ControlCmd: /* Read a control command */
          channel = (dwParam1 >> 8) & 0xFF;
          value =  (dwParam1 >> 16) & 0xFF;
          port->cache.sqControllers[channel] = value;
          return;
        case PchWheelCmd: /* Read a pitch wheel change */
          channel = dwParam1 & 0x0F;
          value = (dwParam1 >> 8) & 0xFF;
          value2 = (dwParam2 >> 16) & 0xFF;
          port->cache.sqPitchBend[channel] = (value2 << 7) + value;
          return;
        case PolyPressCmd: /* Read polyphonic key pressure */
          channel = (dwParam1 >> 8) & 0xFF;
          value =  (dwParam1 >> 16) & 0xFF;
          port->cache.sqKeyPressures[channel] = value;
          return;
        case ChanPressCmd: /* Read channel key pressure */
          channel = dwParam1 & 0x0F;
          value = (dwParam1 >> 8) & 0xFF;
          port->cache.sqKeyPressures[channel] = value;
          return;
        default: /* do nothing */
          break;
      };
    }
  if(cmd == SysExCmd)
    cmdLen = midiMetaEventLengths[dwParam1 & 0x0F];
  else if(cmd == PgmChngCmd || cmd == ChanPressCmd)
    /* all but program change and channel pressure have two data bytes */
    cmdLen = 2;
  else
    cmdLen = 3;
  /* compute data word; at most 3 bytes plus 1 byte for length */
  data = dwParam1 | (cmdLen << 24);
  /* store data and stamp in the buffer */
  dst = port->inBuffer + port->inBufferEnd;
  dst->data = data;
  dst->stamp = dwParam2;
  port->inBufferEnd++;
  if(port->inBufferEnd == MAX_MIDI_BUFFER)
    port->inBufferEnd = 0; /* wrap around */
  /* Notify another thread that something has changed.
     We do *not* call synchronousSignalSemaphoreWithIndex
     because this may suspend the current thread.
     Even more, SetEvent is one of the few functions which
     can be called from the MIDI callback function without
     worrying for timing problems. */
  if(cmdLen && port->semaphore)
    SetEvent(midiInputEvent);
}

/*************************************************************************************
 midiScheduler: This function simulates a VM-level scheduler for MIDI messages.
                It is run at a high priority so we better not waste a lot of time
                in here.
 *************************************************************************************/
static DWORD WINAPI midiScheduler(sqMidiPort *port)
{ sqMidiOutEvent *evt;
  int delay;

  /* we always read the first event */
  evt = &(port->outBuffer[0]);
  while(1) {
    /* Wait until we have access to the out buffer */
    WaitForSingleObject(port->outBufferMutex, INFINITE);
    /* check if there are any events at all */
    if(port->nOutEvents)
      delay = port->outBuffer[0].stamp - timeGetTime();
    else
      delay = 0x7FFFFFFF;
    ReleaseMutex(port->outBufferMutex);

    /* Wait until the next event gets scheduled or until
       an event gets to the start of the queue */
    if(delay > 0)
      WaitForSingleObject(port->outBufferData, delay);

    /* Schedule all events currently in range. */
    WaitForSingleObject(port->outBufferMutex, INFINITE);
    while(port->nOutEvents) {
      /* check if event is in range */
      delay = evt->stamp - timeGetTime();
      if(delay > 0) break; /* not in range */
      /* send the command */
      midiOutShortMsg((HMIDIOUT)(port->handle), evt->data);
      /* and adjust the heap */
      midiOutHeapRemoveFirst(port);
    }
    ReleaseMutex(port->outBufferMutex);
    /* All events have been sent */
  }
}

/*************************************************************************************
 scheduleShortMessage: Schedule a short messgage in the appropriate MIDI port
 *************************************************************************************/
int scheduleShortMessage(sqMidiPort *port, DWORD data, DWORD stamp)
{ int doSignal = 0;

  if((int)(stamp - timeGetTime()) <= 0)
    return midiOutShortMsg((HMIDIOUT) port->handle, data);

  if(port->nOutEvents == MAX_MIDI_BUFFER)
    return 0; /* not scheduled */
  if(WaitForSingleObject(port->outBufferMutex, 5000) == WAIT_TIMEOUT)
    {
#ifndef NO_WARNINGS
      warnPrintf(TEXT("MIDI: Output busy for more than 5 seconds.\n"));
#endif
      return 0;
    }
  /* signal if there were no events before or if the new command comes first */
  if(port->nOutEvents == 0 || (port->outBuffer[0].stamp > stamp))
    doSignal = 1;
  /* add the data */
  port->outBuffer[port->nOutEvents].data = data;
  port->outBuffer[port->nOutEvents].stamp = stamp;
  port->nOutEvents++;
  /* adjust the heap
     NOTE: We're using 1-based indexes here! */
  midiOutHeapUpFrom(port, port->nOutEvents);
  ReleaseMutex(port->outBufferMutex);
  if(doSignal)
    SetEvent(port->outBufferData);
  return 1;
}

/*************************************************************************************
 sendLongMidiData: Send a MIDI command not fitting into 4 bytes. (e.g. a SysEx message)
 *************************************************************************************/
static void sendLongMidiData(HMIDIOUT midiOutPort, char *data, int numBytes)
{ MIDIHDR *header = NULL;

  /* recycle headers if possible */
  if(midiHeaderList)
    {
      header = midiHeaderList;
      while(header)
        if(header->dwFlags & MHDR_DONE)
          break;
        else
          header = (MIDIHDR*)header->dwUser;
    }
   if(!header)
     { /* allocate new header */
       header = GlobalLock(GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, sizeof(MIDIHDR)));
       header->dwUser = (DWORD_PTR)midiHeaderList;
       midiHeaderList = header;
     }
   if(header->lpData)
     { /* old data in header */
       GlobalUnlock(GlobalHandle(header->lpData));
       GlobalFree(GlobalHandle(header->lpData));
     }
   /* copy data */
   header->lpData = GlobalLock(GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, numBytes));
   header->dwBufferLength = numBytes;
   header->dwFlags &= ~MHDR_DONE;
   MoveMemory(header->lpData, data, numBytes);
   /* and send data to the driver */
   midiOutPrepareHeader(midiOutPort, header, sizeof(MIDIHDR));
   midiOutLongMsg(midiOutPort, header, sizeof(MIDIHDR));
}

/*************************************************************************************
 startSysExCommand: Try to read a complete SysEx message from the (smalltalk) source.
                    Return the number of bytes actually read or -1 on error.
                    The function may set the PENDING_SYSEX flag in the port if
                    there is not enough data to complete the SysEx.
 *************************************************************************************/
int startSysExCommand(sqMidiPort *port, unsigned char *srcPtr, int count)
{ /* Start a variable length Sysex command */
  unsigned char *sxBuf = port->sysExBuffer;
  int n = 0;
  /* clamp count to an appropriate range */
  if(count > MAX_SYSEX_BUFFER) count = MAX_SYSEX_BUFFER;
  /* copy the first (status) byte */
  sxBuf[n++] = *srcPtr++;
  /* copy bytes until either the end of sysex is reached
     or there is no more data in the input buffer */
  while(n < count)
    if( *srcPtr & 0x80) break; /* end of sysex */
    else sxBuf[n++] = *srcPtr++;
  port->sysExLength = n;
  if(port->sysExLength >= MAX_SYSEX_BUFFER)
    { /* fail if not enough sysex space */
      success(false);
      return -1;
    }
  if( (n >= count) || (srcPtr[n] & 0x80) != 0x80)
    port->flags |= PENDING_SYSEX; /* not enough data buffered */
  else
    {
      /* copy the last (status) byte */
      if(*srcPtr == 0xF7) sxBuf[n++] = *srcPtr++;
      sendLongMidiData(port->handle, sxBuf, n);
      port->sysExLength = 0; /* data has been sent */
    }
  return n;
}

/*************************************************************************************
 finishSysExCommand: Finish a previously started SysEx message. This function is
                     only called if the PENDING_SYSEX flag has been set.
                     Return the number of bytes processed or -1 on error.
 *************************************************************************************/
int finishSysExCommand(sqMidiPort *port, char *bufferPtr, int count)
{ /* Still in a system exclusive message */
  unsigned char *buf = port->sysExBuffer;
  unsigned char *srcPtr = bufferPtr;

  /* copy unless status byte found */
  while(count && ((*srcPtr) & 0x80) == 0)
    if(port->sysExLength < MAX_SYSEX_BUFFER)
      {
        buf[port->sysExLength++] = *srcPtr++;
        count--;
      }
  /* Fail if we don't have enough space in the sysex buffer */
  if(port->sysExLength >= MAX_SYSEX_BUFFER)
    {
      port->flags &= ~PENDING_SYSEX;
      success(false);
      return -1;
    }
  /* return if the sysex message has not been finished */
  if(!count) return (usqIntptr_t) srcPtr - (usqIntptr_t)bufferPtr;
  /* copy the last (status) byte */
  if(*srcPtr == 0xF7) buf[port->sysExLength++] = *srcPtr++;
  sendLongMidiData(port->handle, buf, port->sysExLength);
  port->sysExLength = 0; /* data has been sent */
  return (usqIntptr_t) srcPtr - (usqIntptr_t)bufferPtr;
}

/***************************************************************
 Helpers
 ***************************************************************/

/* Return the port with the given number or NULL */
static sqMidiPort* GetPort(int portNum)
{
  if(portNum > MAX_DEVICES || portNum < 0)
    {
      success(false);
      return NULL;
    }
  else
    return midiPorts[portNum];
}

/* Free an allocated port */
static void FreePort(int portNum)
{ sqMidiPort *port = GetPort(portNum);

  if(!port) return;
  /* output cleanup */
  if(port->schedulerThread) TerminateThread(port->schedulerThread,0);
  if(port->outBufferData) CloseHandle(port->outBufferData);
  if(port->outBufferMutex) CloseHandle(port->outBufferMutex);
  if(port->outBuffer) free(port->outBuffer);
  if(port->sysExBuffer) free(port->sysExBuffer);
  /* input cleanup */
  if(port->inBuffer) free(port->inBuffer);
  /* generic cleanup */
  free(port);
  midiPorts[portNum] = NULL;
}

/* Allocate a new port and setup buffers for input or output */
static sqMidiPort *AllocatePort(int outFlag)
{ sqMidiPort *port;
  DWORD id;

  port = (sqMidiPort*)calloc(1,sizeof(sqMidiPort));
  if(!port) return NULL;
  if(outFlag)
    {
      port->outBuffer = (sqMidiOutEvent*)calloc(MAX_MIDI_BUFFER+1, sizeof(sqMidiOutEvent));
      port->sysExBuffer = (char*)calloc(1,MAX_SYSEX_BUFFER+1);
      port->outBufferData = CreateEvent(NULL, 0, 0, NULL);
      port->outBufferMutex = CreateMutex(NULL, 0, NULL);
      port->schedulerThread =
        CreateThread(NULL,                    /* No security descriptor */
                     128*1024,                /* max stack size     */
                     (LPTHREAD_START_ROUTINE) &midiScheduler, /* what to do */
                     port,                    /* parameter for thread   */
                     CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
                     &id);                    /* return value for thread id */
      if(!port->schedulerThread)
        printLastError(TEXT("CreateThread() failed"));
      if(!SetThreadPriority(port->schedulerThread, THREAD_PRIORITY_TIME_CRITICAL))
        printLastError(TEXT("SetThreadPriority() failed"));
      if(!ResumeThread(port->schedulerThread))
        printLastError(TEXT("ResumeThread() failed"));
    }
  else
    {
      port->inBuffer = (sqMidiInEvent*) calloc(MAX_MIDI_BUFFER+1, sizeof(sqMidiInEvent));
    }
  return port;
}

/***************************************************************************
 Exported functions
 ***************************************************************************/

/* Close the given MIDI port. Do nothing if the port is not open.
   Fail if there is no port of the given number.*/
int sqMIDIClosePort(int portNum)
{  sqMidiPort *port;

  port = GetPort(portNum);
  if(!port) return 0; /* already closed or invalid port number */
  if(port->flags & MIDI_OUT_DEVICE)
    { /* out port */
      midiOutReset((HMIDIOUT)port->handle);
      midiOutClose((HMIDIOUT)port->handle);
    }
  else
    { /* in port */
      midiInStop((HMIDIIN)port->handle);
      midiInReset((HMIDIIN)port->handle);
      midiInClose((HMIDIIN)port->handle);
    }
  FreePort(portNum);
  return 1;
}

/* Return the current value of the clock used to schedule MIDI events.
   The MIDI clock is assumed to wrap at or before half the maximum
   positive SmallInteger value. This allows events to be scheduled
   into the future without overflowing into LargePositiveIntegers.
   This implementation does not support event scheduling, so it
   just returns the value of the Squeak millisecond clock. */
int sqMIDIGetClock(void) {
	return timeGetTime() & 0x0FFFFFFF;
}

/* Return the number of available MIDI interfaces, including both
   hardware ports and software entities that act like ports. Ports
   are numbered from 0 to N-1, where N is the number returned by this
   primitive. */
int sqMIDIGetPortCount(void) {
	return midiInNumDevices + midiOutNumDevices;
}

/* Return an integer indicating the directionality of the given
   port where: 1 = input, 2 = output, 3 = bidirectional. Fail if
   there is no port of the given number. */
int sqMIDIGetPortDirectionality(int portNum) {
  if(portNum < 0 || portNum >= midiInNumDevices+midiOutNumDevices)
    return success(false);
  return portNum < midiOutNumDevices ? MIDI_OUT_DEVICE : MIDI_IN_DEVICE;
}

/* Copy the name of the given MIDI port into the string at the given
   address. Copy at most length characters, and return the number of
   characters copied. Fail if there is no port of the given number.*/
int sqMIDIGetPortName(int portNum, char * namePtr, int length) {
  TCHAR *portName;
	int count, i;
  MIDIOUTCAPS outCaps;
  MIDIINCAPS inCaps;

  if(portNum < 0 || portNum >= midiInNumDevices+midiOutNumDevices)
    return success(false);
  if(portNum < midiOutNumDevices)
    {
      midiOutGetDevCaps(portNum-1, &outCaps, sizeof(outCaps));
      portName = outCaps.szPname;
    }
  else
    {
      midiInGetDevCaps(portNum - midiOutNumDevices, &inCaps, sizeof(inCaps));
      portName = inCaps.szPname;
    }
	count = lstrlen(portName);
	if (count > length) count = length;
  for(i=0;i<count;i++)
    namePtr[i] = (char) portName[i];
	return count;
}

/* Open the given port, if possible. If non-zero, readSemaphoreIndex
   specifies the index in the external objects array of a semaphore
   to be signalled when incoming MIDI data is available. Note that
   not all implementations support read semaphores (this one does);
   see sqMIDICanUseSemaphore. The interfaceClockRate parameter
   specifies the clock speed for an external MIDI interface
   adaptor on platforms that use such adaptors (e.g., Macintosh)
   and is ignored with Win32.
   Fail if there is no port of the given number.*/
int sqMIDIOpenPort(int portNum, int readSemaIndex, int interfaceClockRate) {
  DWORD err;
  sqMidiPort *port = GetPort(portNum);

  if(port) return 1; /* already open */
  if(portNum >= midiInNumDevices+midiOutNumDevices)
    return success(false);
  if(portNum < midiOutNumDevices)
    { /* output port */
      MIDIOUTCAPS caps;
      HMIDIOUT handle;

      midiOutGetDevCaps(portNum-1, &caps, sizeof(caps));
      port = AllocatePort(1); /* Allocate the output port */
      if(!port) { success(false);  return 0;}
      port->flags = MIDI_OUT_DEVICE;
      midiPorts[portNum] = port;
      MoveMemory(port->name, caps.szPname, MAXPNAMELEN * sizeof(TCHAR));
      port->name[MAXPNAMELEN] = 0;
      DBGPRINTF(TEXT("Opening output interface %s\n"), caps.szPname);
      err = midiOutOpen(&handle, portNum-1, 0, 0, 0);
      if(err)
        { /* fail if we can't open a particular output device */
#ifndef NO_WARNINGS
          TCHAR errorText[256];
          midiOutGetErrorText(err,errorText,255);
          warnPrintf(TEXT("Failed to open MIDI output device %s:\n%s\n"),
                  caps.szPname, errorText);
#endif
          FreePort(portNum);
          success(false);
          return 0;
        }
      port->handle = handle;
    }
  else
    { /* input port */
      MIDIINCAPS caps;
      HMIDIIN handle;

      midiInGetDevCaps(portNum - midiOutNumDevices, &caps, sizeof(caps));
      port = AllocatePort(0); /* Allocate the input port */
      if(!port) { success(false);  return 0;}
      port->flags = MIDI_IN_DEVICE;
      port->semaphore = readSemaIndex;
      midiPorts[portNum] = port;
      MoveMemory(port->name, caps.szPname, MAXPNAMELEN * sizeof(TCHAR));
      port->name[MAXPNAMELEN] = 0;
      DBGPRINTF(TEXT("Opening input interface %s\n"), caps.szPname);
      err = midiInOpen(&handle, portNum - midiOutNumDevices,
                       (DWORD_PTR)midiInCallback, (DWORD_PTR)port, CALLBACK_FUNCTION);
      if(err)
        { /* fail if we can't open a particular input device */
#ifndef NO_WARNINGS
          TCHAR errorText[256];
          midiInGetErrorText(err,errorText,255);
          warnPrintf(TEXT("Failed to open MIDI input device %s:\n%s\n"),
                  caps.szPname, errorText);
#endif
          FreePort(portNum);
          success(false);
          return 0;
        }
      port->handle = handle;
      midiInStart(handle);
    }
  return 1;
}

/* Read or write the given MIDI driver parameter. If modify is 0,
   then newValue is ignored and the current value of the specified
   parameter is returned. If modify is non-zero, then the specified
   parameter is set to newValue. Note that many MIDI driver parameters
   are read-only; attempting to set one of these parameters fails.
   For boolean parameters, true = 1, false = 0. */
int sqMIDIParameter(int whichParameter, int modify, int newValue) {
  int i;
  sqMidiPort *port;

	if (modify == 0) {
		switch(whichParameter) {
		case sqMIDIInstalled:          return 1;
		case sqMIDIVersion:            return 100;
		case sqMIDIHasBuffer:          return 1;
		case sqMIDIHasDurs:            return 0;
		case sqMIDICanSetClock:        return 0;
		case sqMIDICanUseSemaphore:    return 1;
		case sqMIDIEchoOn:             return 0 /* isEchoEnabled */;
		case sqMIDIUseControllerCache: return isControllerCaching;
		case sqMIDIEventsAvailable:
      for(i=0;i<MAX_DEVICES;i++)
        if(midiPorts[i])
          if(midiPorts[i]->inBufferStart != midiPorts[i]->inBufferEnd)
		        return 1;
      return 0;
		case sqMIDIFlushDriver:        return 0;
		case sqMIDIClockTicksPerSec:   return 1000;
		case sqMIDIHasInputClock:      return 1;
		default:
			return success(false);
		}
	} else {
		switch(whichParameter) {
		case sqMIDIInstalled:
		case sqMIDIVersion:
		case sqMIDIHasBuffer:
		case sqMIDIHasDurs:
		case sqMIDICanSetClock:
		case sqMIDICanUseSemaphore:
			return success(false);
			break;
		case sqMIDIEchoOn:
      isEchoEnabled = newValue != 0;
			break;
		case sqMIDIUseControllerCache:
      isControllerCaching = newValue != 0;
			break;
		case sqMIDIEventsAvailable:
			return success(false);
			break;
		case sqMIDIFlushDriver:
      for(i=0;i<MAX_DEVICES;i++)
        {
          port = midiPorts[i];
          if(port) {
            if(port->flags & MIDI_OUT_DEVICE)
              {
                /* reset output device */
                WaitForSingleObject(port->outBufferMutex, INFINITE);
                port->nOutEvents = 0;
                ReleaseMutex(port->outBufferMutex);
                midiOutReset((HMIDIOUT) (midiPorts[i]->handle));
              }
            else
              {
                /* reset input device */
                midiInStop((HMIDIIN) (port->handle));
                midiInReset((HMIDIIN) (port->handle));
                midiInStart((HMIDIIN) (port->handle));
                port->inBufferStart = port->inBufferEnd = 0;
              }
		  }
        }
			break;
		case sqMIDIClockTicksPerSec:
			return success(false);
			break;
		default:
			return success(false);
		}
	}
	return 1;
}

int sqMIDIParameterSet(int whichParameter, int newValue)
{
	return sqMIDIParameter(whichParameter, 1, newValue);
}

int sqMIDIParameterGet(int whichParameter)
{
	return sqMIDIParameter(whichParameter, 0, 0);
}

/* bufferPtr is the address of the first byte of a Smalltalk
   ByteArray of the given length. Copy up to (length - 4) bytes
   of incoming MIDI data into that buffer, preceded by a 4-byte
   timestamp in the units of the MIDI clock, most significant byte
   first. Implementations that do not support timestamping of
   incoming data as it arrives (see sqMIDIHasInputClock) simply
   set the timestamp to the value of the MIDI clock when this
   function is called. Return the total number of bytes read,
   including the timestamp bytes. Return zero if no data is
   available. Fail if the buffer is shorter than five bytes,
   since there must be enough room for the timestamp plus at
   least one data byte. */
int sqMIDIPortReadInto(int portNum, int count, char * bufferPtr) {
	int bytesRead, stamped;
  DWORD index, i, data, len, stamp;
  unsigned char *dstPtr;
  sqMidiPort *port;

  /* require at least 1 byte for midi data */
	if (count < 5) return success(false);
  port = GetPort(portNum);
  if(!port) return success(false);

  if(port->inBufferStart == port->inBufferEnd)
		return 0; /* no data */

  /* get data */
  index = port->inBufferStart;
  stamped = 0; /* We don't have a time stamp yet */
  /* leave room for stamp */
  dstPtr = (char*)(bufferPtr+4);
  count -= 4;
  /* as long as there is data and space left */
  while( (port->pendingInputData || index != port->inBufferEnd) && count)
    {
      if(port->pendingInputData)
        {
          data = port->pendingInputData;
          stamp = port->pendingInputStamp;
        }
      else
        {
          data = port->inBuffer[index].data;
          stamp = port->inBuffer[index].stamp;
          /* adjust input */
          if(index == port->inBufferStart)
            port->inBufferStart++;
          index++;
          /* wrap around if necessary */
          if(index == MAX_MIDI_BUFFER)
            index = 0;
          if(port->inBufferStart == MAX_MIDI_BUFFER)
            port->inBufferStart = 0;
        }
      len = data >> 24;
      if(!stamped)
        {
          *(int*)bufferPtr = stamp;
          stamped = 1;
        }
      /* copy data */
      for(i=0;i<len && count;i++,count--)
        {
          *dstPtr++ = (unsigned char) (data & 0xFF);
          data = data >> 8;
        }
      if(i < len)
        {
          /* There was not enough space left in the buffer;
             Store data back but adjust the byte length.
             NOTE: data has already been shifted so the bytes are correct */
          data &= 0x00FFFFFF; /* eventually clear header bits */
          data += (len-i) << 24;
          port->pendingInputData = data;
          port->pendingInputStamp = stamp;
        }
    }
  /* compute the number of bytes actually transmitted */
  bytesRead = (usqIntptr_t)dstPtr - (usqIntptr_t)bufferPtr;
  /* return zero if only the stamp is in the buffer */
	return bytesRead == 4 ? 0 : bytesRead;
}

/* bufferPtr is the address of the first byte of a Smalltalk
   ByteArray of the given length. Send its contents to the given
   port when the MIDI clock reaches the given time. If time equals
   zero, then send the data immediately. Implementations that do
   not support a timestamped output queue, such as this one, always
   send the data immediately; see sqMIDIHasBuffer. */
int sqMIDIPortWriteFromAt(int portNum, int count, char * bufferPtr, int time) {
  unsigned char *srcPtr = (char*) bufferPtr;
  unsigned char cmd;
  sqMidiPort *port;
  DWORD timeStamp;
  int nBytes, cmdLen;

  /* fetch scheduling time first so it will be accurate */
  timeStamp = timeGetTime() + (DWORD) time;
  /* fetch port */
  port = GetPort(portNum);
  if(!port) return success(false);
  if(0 == (port->flags & MIDI_OUT_DEVICE))
    return success(false); /* read-only ports fail on write */

  /* Check if we're still in a MIDI SysEx message from last time */
  if(port->flags & PENDING_SYSEX)
    { /* Still in a system exclusive message */
      nBytes = finishSysExCommand(port, srcPtr, count);
      if(nBytes < 0) return 0; /* error */
      count -= nBytes;
      srcPtr += nBytes;
    }
  /* Check if we're still in a short message from last time */
  if(port->pendingSize)
    { /* Yes; finish up the last command */
      while(count && port->pendingSize)
        {
          port->pendingCommand[port->pendingLength++] = *srcPtr++;
          count--; port->pendingSize--;
        }
      if(!port->pendingSize)
        scheduleShortMessage(port, *(DWORD*)&(port->pendingCommand[0]), port->pendingStamp);
    }

  /* Process midi data */
  while(count)
    {
      cmd = *srcPtr;
      if(cmd >= 0xF0)
        { /* Meta or Sysex command */
          cmdLen = midiMetaEventLengths[cmd & 0x0F];
          if(cmdLen <= 0)
            { /* variable length; find next status byte */
              nBytes = startSysExCommand(port, srcPtr, count);
              if(nBytes < 0) return 0; /* error */
              count -= nBytes;
              srcPtr += nBytes;
              continue;
            }
        }
      else
        { /* Channel message */
          cmdLen = 1;
          if(cmd >= 0x80) cmdLen++; /* new command */
          /* else use running status */
          if( ((cmd & 0xF0) != 0xC0) && ((cmd & 0xF0) != 0xD0))
            cmdLen++; /* all but program change and channel pressure have two data bytes */
        }
      /* check if enough data is in the buffer */
      if(cmdLen > count && port->nOutEvents < MAX_MIDI_BUFFER)
        break;/* no */

      /* have enough data; send it */
      scheduleShortMessage(port, *(DWORD*)srcPtr, timeStamp);
      srcPtr += cmdLen;
      count -= cmdLen;
    }
  if(count && count < cmdLen)
    { /* if there is remaining data we have a short command left */
      *(DWORD*) &(port->pendingCommand[0]) = *(DWORD*)srcPtr;
      port->pendingStamp = timeStamp;
      port->pendingLength = count;
      port->pendingSize = cmdLen - count;
      srcPtr += count;
    }
	return (usqIntptr_t) srcPtr - (usqIntptr_t) bufferPtr;
}

/*************************************************************************************
 SetupMIDI: Setup any MIDI related stuff.
 *************************************************************************************/
int midiInit(void)
{ int i;
  int maxDevs = MAX_DEVICES / 2;
  DWORD id;

  /* reset MIDI handles */
  for(i=0;i<MAX_DEVICES;i++)
    {
      midiPorts[i] = NULL;
    }
  /* determine midi devices */
  midiInNumDevices = midiInGetNumDevs();
  midiOutNumDevices = midiOutGetNumDevs();
  /* If we have MIDI out devices, then we can use the mapper */
  if(midiOutNumDevices) midiOutNumDevices++;
  /* clamp to max devices (even though it's unlikely to exceed it) */
  if(midiOutNumDevices > maxDevs) midiOutNumDevices = maxDevs;
  if(midiInNumDevices > maxDevs) midiInNumDevices = maxDevs;

  /* Create the input event and associated notification thread */
  midiInputEvent = CreateEvent(NULL, 1, 0, NULL);
  midiInputThread =
        CreateThread(NULL,                    /* No security descriptor */
                     128*1024,                /* max stack size     */
                     (LPTHREAD_START_ROUTINE) &midiNotifyThread, /* what to do */
                     NULL,                    /* parameter for thread   */
                     STACK_SIZE_PARAM_IS_A_RESERVATION,  /* create running */
                     &id);                    /* return value for thread id */
  return midiInputEvent && midiInputThread;
}

int midiShutdown(void)
{
	int i;
	/* Close all open ports */
	for(i=0; i<MAX_DEVICES; i++) sqMIDIClosePort(i);
	TerminateThread(midiInputThread, 0);
	CloseHandle(midiInputEvent);
	midiInputThread = NULL;
	midiInputEvent = NULL;
	return 1;
}

#endif /* NO_MIDI */


text:
-- NOTICE:
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- read COPYRIGHT.md for more informations.

local impl = {}
local ffi = require("ffi")
local C = ffi.C

if (jit.arch=="x64") then
	ffi.cdef[[
		typedef __int64        intptr_t;
	]]
elseif (jit.arch=="x86") then
	ffi.cdef[[
		typedef int            intptr_t;
	]]
else
	error("Unsupported architecture"..jit.arch)
end

ffi.cdef[[
    void* malloc(size_t size);
    void free(void* data);
    char* _getcwd(char* buffer, int maxlen);

	typedef unsigned int _dev_t;        /* device code */
	typedef unsigned short _ino_t;      /* i-node number (not used on DOS) */
	typedef __int64 __time64_t;     /* 64-bit time value */

    typedef struct {
        _dev_t     st_dev;
        _ino_t     st_ino;
        unsigned short st_mode;
        short      st_nlink;
        short      st_uid;
        short      st_gid;
        _dev_t     st_rdev;
        __int64    st_size;
        __time64_t st_atime;
        __time64_t st_mtime;
        __time64_t st_ctime;
    } _stat64info;

	int __cdecl _stat64(const char * _Name, _stat64info * _Stat);

	extern int * __cdecl _errno(void);

	typedef struct  {
        unsigned    attrib;
        __time64_t  time_create;    /* -1 for FAT file systems */
        __time64_t  time_access;    /* -1 for FAT file systems */
        __time64_t  time_write;
        __int64     size;
        char        name[260];
	} __finddata64_t;

	intptr_t __cdecl _findfirst64(const char * _Filename, __finddata64_t * _FindData);
	int __cdecl _findnext64(intptr_t _FindHandle, __finddata64_t * _FindData);

	int __cdecl _mkdir(const char * _Path);
]]

function impl.current()
    local buff = C.malloc(256)
    local ret = ffi.string(C._getcwd(buff, 256))
    C.free(buff)
    return ret
end

local function errno()
	return C._errno()[0]
end

function impl.stat(fn)
	local ret = ffi.new("_stat64info[1]")
	local iret = C._stat64(fn, ret);
	if (iret == 0) then
		return ret[0]
	end

	return nil, errno()
end
local stat = impl.stat

function impl.isdir(fn)
	local st = stat(fn)
	return st and (bit.band(st.st_mode, 0x4000) ~= 0)
end

function impl.exists(fn)
	return stat(fn) and true or false
end

local function listFile(dir, filter)
	local pattern = require("path").normjoin(dir, "*")
	local ret = {}

	local c_file = ffi.new("__finddata64_t[1]")

	local handle = C._findfirst64(pattern, c_file);
	if (handle == -1) then
		return ret;
	end

	while true do
		if (filter(c_file)) then
			table.insert(ret, ffi.string(c_file[0].name))
		end

		if (C._findnext64(handle, c_file) ~= 0) then
			return ret
		end
	end
end

function impl.listAll(dir)
	return listFile(dir, function()
		return true
	end)
end

function impl.listFiles(dir)
	return listFile(dir, function(cf)
		return bit.band(cf[0].attrib, 0x10) == 0
	end)
end

function impl.listSubdirs(dir)
	return listFile(dir, function(cf)
		return bit.band(cf[0].attrib, 0x10) ~= 0
	end)
end

function impl.mkdir(path)
	return C._mkdir(path) == 0
end

return impl

redpajama_set_name: RedPajamaGithub


text:
[![Dependency Status](https://david-dm.org/tellnes/bunyan-middleware.png)](https://david-dm.org/tellnes/bunyan-middleware)
[![devDependency Status](https://david-dm.org/tellnes/bunyan-middleware/dev-status.png)](https://david-dm.org/tellnes/bunyan-middleware#info=devDependencies)

Request, response logger middleware for [bunyan](https://github.com/trentm/node-bunyan):
- log request as `req`
- log response as `res`
- log response close events as warnings
- log request<>response duration in milliseconds as `duration`
- creates, use and forward to response the `x-request-id` request header: get it if present, create it otherwise ([uuid.v1()](https://www.npmjs.com/package/uuid#uuidv1options--buffer--offset))
- log request id as `req_id` and exposes it as `req.reqId`
- provides `req.log` and `res.log` as an id-specialized logger for you to track your request in your entire application, every time you access the `request` or `response` object
- compatible with pure [http server](http://nodejs.org/api/http.html#http_http_createserver_requestlistener), [express](https://github.com/strongloop/express), [connect](https://github.com/senchalabs/connect) and any http middleware system
- uses serializers for `req` and `res` based on [bunyan serializers](https://github.com/trentm/node-bunyan#serializers) if you do not already have a serializer defined.
- obscure headers containing sensitive information in log outputs (configurable with `obscureHeaders`)
- TypeScript support

## Install

```shell
yarn add bunyan-middleware
```

or

```shell
npm install bunyan-middleware --save
```

## Usage

```js
const bunyan = require('bunyan')
const bunyanMiddleware = require('bunyan-middleware')
const express = require('express')

const app = express()
const logger = bunyan.createLogger({ name: 'My App' })

app.use(bunyanMiddleware(
    { headerName: 'X-Request-Id'
    , propertyName: 'reqId'
    , logName: 'req_id'
    , obscureHeaders: []
    , logger: logger
    , additionalRequestFinishData: function(req, res) {
        return { example: true }
      }
    }
  )

app.get('/', function (req, res) {
  // now use `req.log` as your request-specialized bunyan logger
  req.log.info('YO DAWG!')
  res.send('ok')
})
```

### Import using TypeScript

```ts
import bunyanMiddleware = require('bunyan-middleware')
```

## `X-Request-Id`

Will use and forward `X-Request-Id` (case insensitive) header when present.

Otherwise it will generate a
[uuid.v1()](https://www.npmjs.com/package/uuid#uuidv1options--buffer--offset)
and add it to the response headers.

The request id is also available as `req.reqId`.

## Express and mounted apps

If you are using this with express and mounted app which rewrites `req.url` and
you are using `bunyan.serializers.req`, then the url in the log output will be
the rewritten url. To fix that bunyan-middleware is using its own request
serializer instead of the default one which is using `req.originalUrl` instead.

## Options

**`logger`** REQUIRED

- The bunyan logger instance.

**`headerName`** Default: `'X-Request-Id'`

- The name of the HTTP header for the request id.

**`propertyName`** Default: `'reqId'`

- The name for the property on the request object to set the request id.

**`additionalRequestFinishData`** Default: `undefined`

- A function receiving `req` and `res` as arguments returning an object. The elements in the returned object will be added to the fields in the `request finish` message.

**`filter`** Default: `undefined`

- A function receiving `req` and `res` as arguments returning a boolean.
  If this functions return value is truthy it will skip all logging for
  this request/response.

**`logName`** Default: `'req_id'`

- The name for the request id in the log output.

**`level`** Default: `'info'`

- At which log level `request start` and `request finish` should be logged.

**`obscureHeaders`** Default: `null`

- Set to an array with header names to hide header values from log output.
  The output will still show header names, with value set to `null`.

- Eg: `[ 'Authorization' ]`

**`excludeHeaders`** Default: `null`

- Set to an array with header names to remove them from log output.

- Eg: `[ 'Authorization' ]`

**`requestStart`** Default: `false`

- Log the start of the request.

**`verbose`** Default: `false`

- Log `req` and `res` for `request start` and `request finish`.

## License

MIT. See the `LICENCE` file.

## See Also

- [bunyan-request](https://github.com/vvo/bunyan-request) - a fork by [vvo](https://github.com/vvo).

- [express-bunyan-logger](https://github.com/villadora/express-bunyan-logger)


text:
var Promise     = require('bluebird');
var request     = require('request');
var bankInfo    = require('../data/urlmappings.json');
var fs          = require('fs');
var https       = require('https');
var path        = require('path');
var async       = require('async');
var dbManager        = require('../utilities/dbManager');

async.forEachSeries(Object.keys(bankInfo), function(item,callback) {
    var resultWrapper = {};
    var filePath = path.resolve(__dirname, item.toString() + '.json')
    var tasks = [
        readWrapper.bind(null, filePath, resultWrapper),
        batchInserter.bind(null, resultWrapper)
    ];
    async.series(tasks, function (error) {
        if (error) {
            return callback(error);
        }
        console.log('all insertions done')
        return callback(null);
    })
}, function(error) {
    if(error){
        console.log('Something went wrong . Please try again later.');
        return;
    }
    console.log('All the insertions have been done');

});
function readWrapper(filePath , resultWrapper, callback){
    fs.readFile(filePath, 'utf8',function(err,data){
        if(err){
            return callback(err);
        }
	console.log(typeof data);
//        console.log(data.toString());
        resultWrapper.data = JSON.parse(data);
        console.log(resultWrapper.data.length);
        return callback(null);
    });
}
function batchInserter(wrapper, cb){
    async.forEach(wrapper.data,function(item ,callback){
        inserter(item).then(() => {
            return callback(null);
        }, (error) => {
            return callback(error);
        });
    }, function(error){
        return cb(error);
    });
}

function inserter(data){
    delete data.bank_code;
    return new Promise( (resolve,reject) => {
        var stmt = " INSERT INTO tb_bank_details SET ?" ;

        var queryObj = {
            stmt: stmt,
            args: [data]
        };
        dbManager.runQuery(queryObj).then((result) => {

            resolve(null);
        }, (error) => {
            resolve(null);
        });
    });
}


text:
package org.jetbrains.bsp
package protocol

import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.{Project, ProjectManager, ProjectManagerListener, ProjectUtil}
import com.intellij.openapi.util.Disposer
import com.intellij.util.concurrency.AppExecutorUtil
import org.jetbrains.bsp.settings.BspProjectSettings.BspServerConfig
import org.jetbrains.plugins.scala.util.ScalaShutDownTracker

import java.io.File
import java.net.URI
import java.nio.file._
import java.util.concurrent.TimeUnit
import scala.collection.mutable
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try

class BspCommunicationService extends Disposable {

  import BspCommunicationService.{projectPath, updateWidget}

  { // init
    ScalaShutDownTracker.registerShutdownTask(() => this.dispose())

    val bus = ApplicationManager.getApplication.getMessageBus.connect(this)
    bus.subscribe(ProjectManager.TOPIC, MyProjectListener)
  }

  private val timeout = 10.minutes
  private val cleanerPause = 10.seconds

  private val comms = mutable.Map[(URI, BspServerConfig), BspCommunication]()

  private val executorService = AppExecutorUtil.getAppScheduledExecutorService

  private val commCleaner = executorService
    .scheduleWithFixedDelay(() => closeIdleSessions(), cleanerPause.toMillis, cleanerPause.toMillis, TimeUnit.MILLISECONDS)

  private def closeIdleSessions(): Unit = {
    val now = System.currentTimeMillis()
    comms.values.foreach { comm =>
      if (comm.isIdle(now, timeout))
        comm.closeSession()
    }
    updateWidget()
  }

  private[protocol] def communicate(base: File, config: BspServerConfig): BspCommunication =
    comms.getOrElseUpdate(
      (base.getCanonicalFile.toURI, config),
      {
        val comm = new BspCommunication(base, config)
        Disposer.register(this, comm)
        updateWidget()
        comm
      }
    )

  def listOpenComms: Iterable[(URI, BspServerConfig)] = comms.keys

  def isAlive(base: URI, config: BspServerConfig): Boolean =
    comms.get((base,config)).exists(_.alive)

  /** Close BSP connection if there is an open one associated with `base`. */
  def closeCommunication(base: URI, config: BspServerConfig): Future[Unit] = {
    val tryComm = comms.get(base, config)
      .toRight(new NoSuchElementException)
      .toTry

    Future.fromTry(tryComm)
      .flatMap(_.closeSession())(ExecutionContext.global)
      .map(_ => updateWidget())(ExecutionContext.global)
  }

  def exitCommands(base: URI, config: BspServerConfig): Try[List[List[String]]] = {
    comms.get(base, config)
      .toRight(new NoSuchElementException)
      .toTry
      .map(_.exitCommands)
  }

  def closeAll: Future[Unit] = {
    import ExecutionContext.Implicits.global
    Future.traverse(comms.values)(_.closeSession()).map(_ => updateWidget())
  }

  override def dispose(): Unit = {
    comms.values.foreach(_.closeSession())
    commCleaner.cancel(true)
    updateWidget()
  }

  private object MyProjectListener extends ProjectManagerListener {
    override def projectClosed(project: Project): Unit = for {
      path <- projectPath(project)
      uri = Paths.get(path).toUri
      session <- comms.view.filterKeys(_._1 == uri).values
    } session.closeSession().map(_ => updateWidget())(ExecutionContext.global)
  }
}

object BspCommunicationService {

  def getInstance: BspCommunicationService =
    ApplicationManager.getApplication.getService(classOf[BspCommunicationService])

  private def projectPath(implicit project: Project): Option[String] =
    Option(ProjectUtil.guessProjectDir(project))
      .map(_.getCanonicalPath)

  private def updateWidget(): Unit =
    ApplicationManager.getApplication.getMessageBus.syncPublisher(BspServerWidgetProvider.Topic).updateWidget()
}


text:
"""Tests for SSGANs."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from absl import flags
from absl.testing import parameterized
from compare_gan import datasets
from compare_gan import test_utils
from compare_gan.gans import consts as c
from compare_gan.gans import loss_lib
from compare_gan.gans import penalty_lib
from compare_gan.gans.ssgan import SSGAN
import gin
import tensorflow as tf

FLAGS = flags.FLAGS
TEST_ARCHITECTURES = [c.RESNET_CIFAR_ARCH, c.SNDCGAN_ARCH, c.RESNET5_ARCH]
TEST_LOSSES = [loss_lib.non_saturating, loss_lib.hinge]
TEST_PENALTIES = [penalty_lib.no_penalty, penalty_lib.wgangp_penalty]

class SSGANTest(parameterized.TestCase, test_utils.CompareGanTestCase):

  def _runSingleTrainingStep(self, architecture, loss_fn, penalty_fn):
    parameters = {
        "architecture": architecture,
        "lambda": 1,
        "z_dim": 128,
    }
    with gin.unlock_config():
      gin.bind_parameter("penalty.fn", penalty_fn)
      gin.bind_parameter("loss.fn", loss_fn)
    model_dir = self._get_empty_model_dir()
    run_config = tf.contrib.tpu.RunConfig(
        model_dir=model_dir,
        tpu_config=tf.contrib.tpu.TPUConfig(iterations_per_loop=1))
    dataset = datasets.get_dataset("cifar10")
    gan = SSGAN(
        dataset=dataset,
        parameters=parameters,
        model_dir=model_dir,
        g_optimizer_fn=tf.train.AdamOptimizer,
        g_lr=0.0002,
        rotated_batch_size=4)
    estimator = gan.as_estimator(run_config, batch_size=2, use_tpu=False)
    estimator.train(gan.input_fn, steps=1)

  @parameterized.parameters(TEST_ARCHITECTURES)
  def testSingleTrainingStepArchitectures(self, architecture):
    self._runSingleTrainingStep(architecture, loss_lib.hinge,
                                penalty_lib.no_penalty)

  @parameterized.parameters(TEST_LOSSES)
  def testSingleTrainingStepLosses(self, loss_fn):
    self._runSingleTrainingStep(c.RESNET_CIFAR_ARCH, loss_fn,
                                penalty_lib.no_penalty)

  @parameterized.parameters(TEST_PENALTIES)
  def testSingleTrainingStepPenalties(self, penalty_fn):
    self._runSingleTrainingStep(c.RESNET_CIFAR_ARCH, loss_lib.hinge, penalty_fn)

if __name__ == "__main__":
  tf.test.main()


text:
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/stub_resolver_config_reader.h"

#include <string>

#include "base/enterprise_util.h"
#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/secure_dns_config.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/browser_test.h"
#include "net/dns/public/secure_dns_mode.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#endif

// TODO(ericorth@chromium.org): Consider validating that the expected
// configuration makes it all the way to the net::HostResolverManager in the
// network service, rather than just testing StubResolverConfigReader output.

namespace {

class StubResolverConfigReaderBrowsertest
    : public InProcessBrowserTest,
      public testing::WithParamInterface<bool> {
 public:
  StubResolverConfigReaderBrowsertest() {
    scoped_feature_list_.InitWithFeatureState(features::kAsyncDns, GetParam());
  }
  ~StubResolverConfigReaderBrowsertest() override = default;

  void SetUpInProcessBrowserTestFixture() override {
    // Normal boilerplate to setup a MockConfigurationPolicyProvider.
    policy_provider_.SetDefaultReturns(
        /*is_initialization_complete_return=*/true,
        /*is_first_policy_load_complete_return=*/true);
    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
        &policy_provider_);
  }

  void SetUpOnMainThread() override {
    // Set the mocked policy provider to act as if no policies are in use by
    // updating to the initial still-empty `policy_map_`.
    ASSERT_TRUE(policy_map_.empty());
    policy_provider_.UpdateChromePolicy(policy_map_);

    config_reader_ = SystemNetworkContextManager::GetStubResolverConfigReader();

    // Only affects future parental controls checks, but that is all that
    // matters here because these tests only deal with checking fresh config
    // reads, not what has been sent to Network Service.
    //
    // TODO(ericorth@chromium.org): If validation of network service state is
    // ever added, need to ensure the result of this override gets sent first.
    config_reader_->OverrideParentalControlsForTesting(
        /*parental_controls_override=*/false);
  }

 protected:
  void SetSecureDnsModePolicy(std::string mode_str) {
    policy_map_.Set(
        policy::key::kDnsOverHttpsMode, policy::POLICY_LEVEL_MANDATORY,
        policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_PLATFORM,
        base::Value(std::move(mode_str)),
        /*external_data_fetcher=*/nullptr);
    policy_provider_.UpdateChromePolicy(policy_map_);
  }

  void SetDohTemplatesPolicy(std::string teplates_str) {
    policy_map_.Set(
        policy::key::kDnsOverHttpsTemplates, policy::POLICY_LEVEL_MANDATORY,
        policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_PLATFORM,
        base::Value(std::move(teplates_str)),
        /*external_data_fetcher=*/nullptr);
    policy_provider_.UpdateChromePolicy(policy_map_);
  }

  policy::PolicyMap policy_map_;
  testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_;

  raw_ptr<StubResolverConfigReader> config_reader_;

  base::test::ScopedFeatureList scoped_feature_list_;
};

// Set various DoH modes and DoH template strings and make sure the settings are
// respected.
IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest, ConfigFromPrefs) {
  bool async_dns_feature_enabled = GetParam();

  // Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  // TODO(crbug.com/1339062): What is the correct function to use here?
  EXPECT_FALSE(base::win::IsEnrolledToDomain());
#endif

  std::string good_post_template = "https://foo.test/";
  std::string good_get_template = "https://bar.test/dns-query{?dns}";
  std::string bad_template = "dns-query{?dns}";
  std::string good_then_bad_template = good_get_template + " " + bad_template;
  std::string bad_then_good_template = bad_template + " " + good_get_template;
  std::string multiple_good_templates =
      "  " + good_get_template + "   " + good_post_template + "  ";

  PrefService* local_state = g_browser_process->local_state();
  local_state->SetString(prefs::kDnsOverHttpsMode,
                         SecureDnsConfig::kModeSecure);
  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template);
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kSecure, secure_dns_config.mode());
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());

  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_post_template);
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kSecure, secure_dns_config.mode());
  EXPECT_EQ(*net::DnsOverHttpsConfig::FromString(good_post_template),
            secure_dns_config.doh_servers());

  local_state->SetString(prefs::kDnsOverHttpsMode,
                         SecureDnsConfig::kModeAutomatic);
  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template);
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());

  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_then_bad_template);
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
  EXPECT_EQ(*net::DnsOverHttpsConfig::FromString(good_get_template),
            secure_dns_config.doh_servers());

  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_then_good_template);
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
  EXPECT_EQ(*net::DnsOverHttpsConfig::FromString(good_get_template),
            secure_dns_config.doh_servers());

  local_state->SetString(prefs::kDnsOverHttpsTemplates,
                         multiple_good_templates);
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
  EXPECT_EQ(*net::DnsOverHttpsConfig::FromString(multiple_good_templates),
            secure_dns_config.doh_servers());

  local_state->SetString(prefs::kDnsOverHttpsMode, SecureDnsConfig::kModeOff);
  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_get_template);
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());

  local_state->SetString(prefs::kDnsOverHttpsMode, "no_match");
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());

  // Test case with policy BuiltInDnsClientEnabled enabled. The DoH fields
  // should be unaffected.
  local_state->Set(prefs::kBuiltInDnsClientEnabled,
                   base::Value(!async_dns_feature_enabled));
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      false /* force_check_parental_controls_for_automatic_mode */);
  EXPECT_EQ(!async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
}

IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest,
                       DefaultNonSetPolicies) {
  bool async_dns_feature_enabled = GetParam();
// Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  EXPECT_FALSE(base::IsEnterpriseDevice());
#endif

  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/false);
  EXPECT_EQ(async_dns_feature_enabled,
            config_reader_->GetInsecureStubResolverEnabled());
  if (base::FeatureList::IsEnabled(features::kDnsOverHttps)) {
    EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kAutomatic);
  } else {
    EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kOff);
  }
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
}

// ChromeOS includes its own special functionality to set default policies if
// any policies are set.  This function is not declared and cannot be invoked
// in non-CrOS builds. Expect these enterprise user defaults to disable DoH.
#if BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest, SpecialPolicies) {
  // Applies the special ChromeOS defaults to `policy_map_`.
  policy::SetEnterpriseUsersDefaults(&policy_map_);
  // Send the PolicyMap to the mock policy provider.
  policy_provider_.UpdateChromePolicy(policy_map_);
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/false);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kOff);
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest,
                       DisableDohByPolicy) {
// Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  EXPECT_FALSE(base::IsEnterpriseDevice());
#endif

  SetSecureDnsModePolicy("off");
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/false);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kOff);
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
}

IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest,
                       AutomaticModeByPolicy) {
// Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  EXPECT_FALSE(base::IsEnterpriseDevice());
#endif

  SetSecureDnsModePolicy("automatic");
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/false);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kAutomatic);
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
}

IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest,
                       SecureModeByPolicy) {
// Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  EXPECT_FALSE(base::IsEnterpriseDevice());
#endif

  SetSecureDnsModePolicy("secure");
  SetDohTemplatesPolicy("https://doh.test/");
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/false);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kSecure);
  EXPECT_EQ(*net::DnsOverHttpsConfig::FromString("https://doh.test/"),
            secure_dns_config.doh_servers());
}

IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest,
                       InvalidTemplatePolicy) {
// Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  EXPECT_FALSE(base::IsEnterpriseDevice());
#endif

  SetSecureDnsModePolicy("secure");
  SetDohTemplatesPolicy("invalid template");
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/false);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kSecure);
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
  // Deterministic regression test for flaky failures seen in
  // https://crbug.com/1326526. This induces a DNS resolution while in secure
  // mode with zero DoH server templates to use.
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("foo.example", "/")));
}

IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest, InvalidModePolicy) {
// Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  EXPECT_FALSE(base::IsEnterpriseDevice());
#endif

  SetSecureDnsModePolicy("invalid");
  SetDohTemplatesPolicy("https://doh.test/");
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/false);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kOff);
  // Expect empty templates if mode policy is invalid.
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
}

// Test that parental controls detection interacts correctly with prefs and
// policies.
IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest,
                       ConfigFromParentalControls) {
// Mark as not enterprise managed.
#if BUILDFLAG(IS_WIN)
  base::win::ScopedDomainStateForTesting scoped_domain(false);
  EXPECT_FALSE(base::IsEnterpriseDevice());
#endif

  config_reader_->OverrideParentalControlsForTesting(
      /*parental_controls_override=*/true);

  // Parental controls takes precedence over regular prefs.
  PrefService* local_state = g_browser_process->local_state();
  local_state->SetString(prefs::kDnsOverHttpsMode,
                         SecureDnsConfig::kModeAutomatic);
  SecureDnsConfig secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/true);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kOff);
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());

  // Policy takes precedence over parental controls.
  SetSecureDnsModePolicy("automatic");
  SetDohTemplatesPolicy("");
  secure_dns_config = config_reader_->GetSecureDnsConfiguration(
      /*force_check_parental_controls_for_automatic_mode=*/true);
  EXPECT_EQ(secure_dns_config.mode(), net::SecureDnsMode::kAutomatic);
  EXPECT_THAT(secure_dns_config.doh_servers().servers(), testing::IsEmpty());
}

INSTANTIATE_TEST_SUITE_P(All,
                         StubResolverConfigReaderBrowsertest,
                         ::testing::Bool());

}  // namespace


text:
'use strict';

module.exports = {
    getTopFiveProducts: function () {
        return this.dispatch('UPDATE_TOP_FIVE_PRODUCTS', [
            {id: 123, title: 'sample 123'},
            {id: 456, title: 'sample 456'},
            {id: 789, title: 'sample 789'},
            {id: 135, title: 'sample 135'},
            {id: 246, title: 'sample 246'}
        ]);
    },
    getProductById: function (id) {
        var self = this;
        return new Promise(function (resolve, reject) {
            if (id) {
                // simulate api call here...
                setTimeout(function () {
                    self.dispatch('UPDATE_PRODUCT', {
                        title: 'this is sample title (' + id + ')',
                        description: 'this is sample description (id=' + id + ')',
                        price: 100 * id,
                        time: (new Date()).getTime(),
                        serial: Math.random()
                    });
                    resolve();
                });
            } else {
                reject(new Error('no product id!'));
            }
        });
    }
};


text:
using System.Text.Json.Serialization;

namespace Marten.Testing.Documents
{
    public class StringDoc
    {
        [JsonInclude] // this is needed to make System.Text.Json happy
        public string Id;
        public string Size { get; set; }
    }
}


text:
"""
    flask.ext.social.views
    ~~~~~~~~~~~~~~~~~~~~~~

    This module contains the Flask-Social views

    :copyright: (c) 2012 by Matt Wright.
    :license: MIT, see LICENSE for more details.
"""
from importlib import import_module

from flask import (Blueprint, current_app, redirect, request, session,
                   after_this_request, abort, url_for)
from flask.ext.security import current_user, login_required
from flask.ext.security.utils import (get_post_login_redirect, login_user,
                                      logout_user, get_url, do_flash)
from flask.ext.security.decorators import anonymous_user_required
from werkzeug.local import LocalProxy

from .signals import (connection_removed, connection_created,
                      connection_failed, login_completed, login_failed)
from .utils import (config_value, get_provider_or_404, get_authorize_callback,
                    get_connection_values_from_oauth_response,
                    get_token_pair_from_oauth_response)

# Used to detect when oauth exceptions happen; this is a dependency
# listed in the setup.py file, so should be no issue to use it here
from flask_oauthlib.client import OAuthException

# Convenient references
_security = LocalProxy(lambda: current_app.extensions['security'])

_social = LocalProxy(lambda: current_app.extensions['social'])

_datastore = LocalProxy(lambda: _social.datastore)

_logger = LocalProxy(lambda: current_app.logger)

def _commit(response=None):
    _datastore.commit()
    return response

@anonymous_user_required
def login(provider_id):
    """Starts the provider login OAuth flow"""
    provider = get_provider_or_404(provider_id)
    callback_url = get_authorize_callback('login', provider_id)
    post_login = request.form.get('next', get_post_login_redirect())
    session[config_value('POST_OAUTH_LOGIN_SESSION_KEY')] = post_login
    return provider.authorize(callback_url)

@login_required
def connect(provider_id):
    """Starts the provider connection OAuth flow"""
    provider = get_provider_or_404(provider_id)
    callback_url = get_authorize_callback('connect', provider_id)
    allow_view = get_url(config_value('CONNECT_ALLOW_VIEW'))
    pc = request.form.get('next', allow_view)
    session[config_value('POST_OAUTH_CONNECT_SESSION_KEY')] = pc
    return provider.authorize(callback_url)

@login_required
def reconnect(provider_id):
    """Tokens automatically refresh with login.
    Logs user out and starts provider login OAuth flow
    """
    logout_user()
    return login(provider_id)

@login_required
def remove_all_connections(provider_id):
    """Remove all connections for the authenticated user to the
    specified provider
    """
    provider = get_provider_or_404(provider_id)

    ctx = dict(provider=provider.name, user=current_user)

    deleted = _datastore.delete_connections(user_id=current_user.get_id(),
                                            provider_id=provider_id)
    if deleted:
        after_this_request(_commit)
        msg = ('All connections to %s removed' % provider.name, 'info')
        connection_removed.send(current_app._get_current_object(),
                                user=current_user._get_current_object(),
                                provider_id=provider_id)
    else:
        msg = ('Unable to remove connection to %(provider)s' % ctx, 'error')

    do_flash(*msg)
    return redirect(request.referrer)

@login_required
def remove_connection(provider_id, provider_user_id):
    """Remove a specific connection for the authenticated user to the
    specified provider
    """
    provider = get_provider_or_404(provider_id)

    ctx = dict(provider=provider.name, user=current_user,
               provider_user_id=provider_user_id)

    deleted = _datastore.delete_connection(user_id=current_user.get_id(),
                                           provider_id=provider_id,
                                           provider_user_id=provider_user_id)

    if deleted:
        after_this_request(_commit)
        msg = ('Connection to %(provider)s removed' % ctx, 'info')
        connection_removed.send(current_app._get_current_object(),
                                user=current_user._get_current_object(),
                                provider_id=provider_id)
    else:
        msg = ('Unabled to remove connection to %(provider)s' % ctx, 'error')

    do_flash(*msg)
    return redirect(request.referrer or get_post_login_redirect())

def connect_handler(cv, provider):
    """Shared method to handle the connection process

    :param connection_values: A dictionary containing the connection values
    :param provider_id: The provider ID the connection shoudl be made to
    """
    cv.setdefault('user_id', current_user.get_id())
    connection = _datastore.find_connection(
        provider_id=cv['provider_id'], provider_user_id=cv['provider_user_id'])

    if connection is None:
        after_this_request(_commit)
        connection = _datastore.create_connection(**cv)
        msg = ('Connection established to %s' % provider.name, 'success')
        connection_created.send(current_app._get_current_object(),
                                user=current_user._get_current_object(),
                                connection=connection)
    else:
        msg = ('A connection is already established with %s '
               'to your account' % provider.name, 'notice')
        connection_failed.send(current_app._get_current_object(),
                               user=current_user._get_current_object())

    redirect_url = session.pop(config_value('POST_OAUTH_CONNECT_SESSION_KEY'),
                               get_url(config_value('CONNECT_ALLOW_VIEW')))

    do_flash(*msg)
    return redirect(redirect_url)

def connect_callback(provider_id):
    provider = get_provider_or_404(provider_id)

    def connect(response):
        cv = get_connection_values_from_oauth_response(provider, response)
        return cv

    cv = provider.authorized_handler(connect)()
    if cv is None:
        do_flash('Access was denied by %s' % provider.name, 'error')
        return redirect(get_url(config_value('CONNECT_DENY_VIEW')))

    return connect_handler(cv, provider)

@anonymous_user_required
def login_handler(response, provider, query):
    """Shared method to handle the signin process"""

    connection = _datastore.find_connection(**query)

    if connection:
        after_this_request(_commit)
        token_pair = get_token_pair_from_oauth_response(provider, response)
        if (token_pair['access_token'] != connection.access_token or
            token_pair['secret'] != connection.secret):
            connection.access_token = token_pair['access_token']
            connection.secret = token_pair['secret']
            _datastore.put(connection)
        user = connection.user
        login_user(user)
        key = _social.post_oauth_login_session_key
        redirect_url = session.pop(key, get_post_login_redirect())

        login_completed.send(current_app._get_current_object(),
                             provider=provider, user=user)

        return redirect(redirect_url)

    login_failed.send(current_app._get_current_object(),
                      provider=provider,
                      oauth_response=response)

    next = get_url(_security.login_manager.login_view)
    msg = '%s account not associated with an existing user' % provider.name
    do_flash(msg, 'error')
    return redirect(next)

def login_callback(provider_id):
    try:
        provider = _social.providers[provider_id]
        module = import_module(provider.module)
    except KeyError:
        abort(404)

    def login(response):
        _logger.debug('Received login response from '
                      '%s: %s' % (provider.name, response))

        # On any oauth exception, raise it to the flask app
        if type(response) == OAuthException:
            raise response

        # If no response, then unauthorized
        if response is None:
            do_flash('Access was denied to your %s '
                     'account' % provider.name, 'error')
            return _security.login_manager.unauthorized(), None

        query = dict(provider_user_id=module.get_provider_user_id(response),
                     provider_id=provider_id)

        return response, query

    response, query = provider.authorized_handler(login)()
    if query is None:
        return response
    return login_handler(response, provider, query)

def create_blueprint(state, import_name):
    bp = Blueprint(state.blueprint_name, import_name,
                   url_prefix=state.url_prefix,
                   template_folder='templates')

    bp.route('/login/<provider_id>')(login_callback)

    bp.route('/login/<provider_id>',
             methods=['POST'])(login)

    bp.route('/connect/<provider_id>')(connect_callback)

    bp.route('/connect/<provider_id>',
             methods=['POST'])(connect)

    bp.route('/connect/<provider_id>',
             methods=['DELETE'])(remove_all_connections)

    bp.route('/connect/<provider_id>/<provider_user_id>',
             methods=['DELETE'])(remove_connection)

    bp.route('/reconnect/<provider_id>',
             methods=['POST'])(reconnect)

    return bp


text:
<?php
/**
 * Created by PhpStorm.
 * User: kostya
 * Date: 2/10/15
 * Time: 5:28 PM
 */

namespace AdLabs\SalesAdminBundle\Form\Handler;

use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Persistence\ObjectManager;
use AdLabs\SalesAdminBundle\Entity\Items;

/**
 * Class ItemsHandler
 *
 * @package AdLabs\SalesAdminBundle\Form\Handler
 */
class ItemsHandler
{
    /**
     * Form service interface
     *
     * @var FormInterface
     */
    protected $form;

    /**
     * Request object service
     *
     * @var Request
     */
    protected $request;

    /**
     * Object manager
     *
     * @var ObjectManager
     */
    protected $manager;

    /**
     * Create object manager
     *
     * @param FormInterface $form
     * @param Request       $request
     * @param ObjectManager $objectManager
     */
    public function __construct(FormInterface $form, Request $request, ObjectManager $objectManager)
    {
        $this->form = $form;
        $this->request = $request;
        $this->manager = $objectManager;
    }

    /**
     * Process
     *
     * @param Items $item
     *
     * @return bool
     */
    public function process(Items $item)
    {
        $this->form->setData($item);

        if (!in_array($this->request->getMethod(), array('POST', 'PUT'))) return false;

        $this->form->submit($this->request);

        if (!$this->form->isValid()) return false;

        $this->onSuccess($item);

        return true;
    }

    /**
     * On Success
     *
     * @param Items $item
     */
    protected function onSuccess(Items $item)
    {
        $this->manager->persist($item);
        $this->manager->flush();
    }
}


text:
module Megam
  class MarketPlaceCollection
    include Enumerable

    attr_reader :iterator
    def initialize
      @apps = Array.new
      @apps_by_name = Hash.new
      @insert_after_idx = nil
    end

    def all_apps
      @apps
    end

    def [](index)
      @apps[index]
    end

    def []=(index, arg)
      is_megam_app(arg)
      @apps[index] = arg
      @apps_by_name[arg.name] = index
    end

    def <<(*args)
      args.flatten.each do |a|
        is_megam_app(a)
        @apps << a
        @apps_by_name[a.name] = @apps.length - 1
      end
      self
    end

    # 'push' is an alias method to <<
    alias_method :push, :<<

    def insert(app)
      is_megam_app(app)
      if @insert_after_idx
        # in the middle of executing a run, so any nodes inserted now should
        # be placed after the most recent addition done by the currently executing
        # node
        @apps.insert(@insert_after_idx + 1, app)
        # update name -> location mappings and register new node
        @apps_by_name.each_key do |key|
        @apps_by_name[key] += 1 if @apps_by_name[key] > @insert_after_idx
        end
        @apps_by_name[app.name] = @insert_after_idx + 1
        @insert_after_idx += 1
      else
      @apps << app
      @apps_by_name[app.name] = @apps.length - 1
      end
    end

    def each
      @apps.each do |app|
        yield app
      end
    end

    def each_index
      @apps.each_index do |i|
        yield i
      end
    end

    def empty?
      @apps.empty?
    end

    def lookup(app)
      lookup_by = nil
      if app.kind_of?(Megam::MarketPlace)
      lookup_by = app.name
      elsif app.kind_of?(String)
      lookup_by = app
      else
        raise ArgumentError, "Must pass a Megam::MarketPlace or String to lookup"
      end
      res = @apps_by_name[lookup_by]
      unless res
        raise ArgumentError, "Cannot find a app matching #{lookup_by} (did you define it first?)"
      end
      @apps[res]
    end

     # Transform the ruby obj ->  to a Hash
    def to_hash
      index_hash = Hash.new
      self.each do |app|
        index_hash[app.name] = app.to_s
      end
      index_hash
    end

    # Serialize this object as a hash: called from JsonCompat.
    # Verify if this called from JsonCompat during testing.
    def to_json(*a)
      for_json.to_json(*a)
    end

    def self.json_create(o)
      collection = self.new()
      o["results"].each do |apps_list|
        apps_array = apps_list.kind_of?(Array) ? apps_list : [ apps_list ]
        apps_array.each do |app|
          collection.insert(app)
        end
      end
      collection
    end

    private

    def is_megam_app(arg)
      unless arg.kind_of?(Megam::MarketPlace)
        raise ArgumentError, "Members must be Megam::MarketPlace's"
      end
      true
    end

    def to_s
      Megam::Stuff.styled_hash(to_hash)
    end

  end
end


text:
import Route from "@ember/routing/route";

export default Route.extend({
	beforeModel( transition ) {
		// access to this route is restricted
		// but don't block the initial transition
		if ( transition.sequence > 0 ) {
			transition.abort();
		}
	}
});


text:
package dials.filter;

import dials.messages.DataFilterApplicationMessage;

/**
 * Dynamic data can be considered the data provided at runtime by the client application.
 * If a given filter is a DynamicDataFilter, it is expected to require a set of runtime data to properly execute.
 * <p/>
 * An example of this is the SeededPercentageFeatureFilter which allows the client to provide an arbitrary object as
 * a seed to the randomness of the filter. When provided, it will give a deterministic answer for a given seed, allowing for consistency.
 */
public interface DynamicDataFilter {

    /**
     * Apply runtime data from the client against the filter to allow for proper execution.
     */
    void applyDynamicData(DataFilterApplicationMessage message);
}


text:
/**
 * Http Cache - Caching sub-system for http requests. In nutshell, HTTP responses for the configured patterns of URIs
 * are cached on first request and served from cache for subsequent requests. This caching layer shall be availed for
 * requests for which responses are expensive to compute and can be cached.
 */
@org.osgi.annotation.versioning.Version("1.0.0")
package com.adobe.acs.commons.httpcache;


text:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Tuuto.Common.Helpers;
using Tuuto.Common.Selectors;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace Tuuto.Common.Controls
{
    public sealed partial class VersionSplitter : ContentPresenter
    {
        public DataTemplate AfterTemplate
        {
            get { return (DataTemplate)GetValue(AfterTemplateProperty); }
            set { SetValue(AfterTemplateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AfterTemplate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AfterTemplateProperty =
            DependencyProperty.Register(nameof(AfterTemplate), typeof(DataTemplate), typeof(VersionSplitter), new PropertyMetadata(null, OnAfterTemplateChanged));

        private static void OnAfterTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as VersionSplitter).InitSelector();
        }

        public DataTemplate BeforeTemplate
        {
            get { return (DataTemplate)GetValue(BeforeTemplateProperty); }
            set { SetValue(BeforeTemplateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BeforeTemplate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BeforeTemplateProperty =
            DependencyProperty.Register(nameof(BeforeTemplate), typeof(DataTemplate), typeof(VersionSplitter), new PropertyMetadata(null, OnBeforeTemplateChanged));

        private static void OnBeforeTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as VersionSplitter).InitSelector();
        }

        public WindowsVersions Version
        {
            get { return (WindowsVersions)GetValue(VersionProperty); }
            set { SetValue(VersionProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Version.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VersionProperty =
            DependencyProperty.Register(nameof(Version), typeof(WindowsVersions), typeof(VersionSplitter), new PropertyMetadata(WindowsVersions.RTM, OnVersionChanged));

        private static void OnVersionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as VersionSplitter).InitSelector();
        }

        public VersionSplitter()
        {
            this.InitializeComponent();
        }

        private void InitSelector()
        {
            if (BeforeTemplate == null || AfterTemplate == null || Version == 0)
                return;
            ContentTemplateSelector = new DataTemplateByVersionSelector
            {
                Before = BeforeTemplate,
                After = AfterTemplate,
                Version = Version
            };
        }

    }
}


text:
const events = {
    events: {},
    on: function (eventName, fn) {
        this.events[eventName] = this.events[eventName] || [];
        this.events[eventName].push(fn);
    },
    off: function (eventName, fn) {
        if (this.events[eventName]) {
            for (let i = 0; i < this.events[eventName].length; i++) {
                if (this.events[eventName][i] === fn) {
                    this.events[eventName].splice(i, 1);
                    break;
                }
            }
        }
    },
    trigger: function (eventName, data, ...rest) {
        if (this.events[eventName]) {
            this.events[eventName].forEach(function (fn) {
                fn(data, rest);
            });
        }
    }
};


text:
require 'rubygems'
require 'bundler/setup'
require 'uvrb'

start = Time.now

loop = UV.default_loop

timer = UV.allocate_handle_timer
# timer = FFI::MemoryPointer.new(UV::Timer, UV::Timer.size, 1)
count = 0
UV.timer_init(loop, timer)
$stdout << "\r\n"

close_cb = proc {|ptr| UV.free(ptr); $stdout << "\n"; }

timer_cb = Proc.new do |ptr, status|
  $stdout << "#{count}\r"
  if count >= 10000
    UV.close(ptr, close_cb)
  end
  count += 1
end

UV.timer_start(timer, timer_cb, 1, 1)
UV.run(loop)
UV.loop_delete(loop)

puts Time.now - start