int AudioDataMixerCallback(uint busIndex, int totalNbOfFrameToWrite,  AudioBufferList* data)
 {
     char* outPtr = (char*)data->mBuffers[0].mData;
     
     int remainingFramesToWrite = totalNbOfFrameToWrite;
     while (remainingFramesToWrite > 0)
     {
         int nbOfFrameToWrite = std::min(remainingFramesToWrite, (ShouldBeLooped() ? LoopEndPoint : TotalNumberOfFrames) - CurrentFrame);
             
         CopyDataToBuffer(outPtr, nbOfFrameToWrite, NumberOfChannels);
         
         remainingFramesToWrite -= nbOfFrameToWrite;
             
         // Check if the track have to be re-looped
         if (ShouldBeLooped() && CurrentFrame >= LoopEndPoint)
         {
             --NumberOfLoops;
             CurrentFrame = LoopStartPoint;
         }
         
         // Check if we reached the end of the track.
         if (CurrentFrame >= TotalNumberOfFrames)
         {
             AudioUnitSetParameter((AudioUnit)HandleChannelMixer, kMultiChannelMixerParam_Enable, kAudioUnitScope_Input, busIndex, 0, 0);
             AudioUnitSetParameter((AudioUnit)Handle3DMixer, k3DMixerParam_Enable, kAudioUnitScope_Input, busIndex, 0, 0);
         
             IsEnabled2D = false;
             IsEnabled3D = false;
         
             PlaybackEnded = true;
         
             // Fill the rest of the buffer with blank
             int sizeToBlank = sizeof(short) * NumberOfChannels * remainingFramesToWrite;
             memset(outPtr, 0, sizeToBlank);
         
             return 0;
         }
     }
     
     return 0;
 }
nsresult
nsJARInputStream::ReadDirectory(char* aBuffer, uint32_t aCount, uint32_t *aBytesRead)
{
    // No need to check the args, ::Read did that, but assert them at least
    NS_ASSERTION(aBuffer,"aBuffer parameter must not be null");
    NS_ASSERTION(aBytesRead,"aBytesRead parameter must not be null");

    // If the buffer contains data, copy what's there up to the desired amount
    uint32_t numRead = CopyDataToBuffer(aBuffer, aCount);

    if (aCount > 0) {
        // empty the buffer and start writing directory entry lines to it
        mBuffer.Truncate();
        mCurPos = 0;
        const uint32_t arrayLen = mArray.Length();

        for ( ;aCount > mBuffer.Length(); mArrPos++) {
            // have we consumed all the directory contents?
            if (arrayLen <= mArrPos)
                break;

            const char * entryName = mArray[mArrPos].get();
            uint32_t entryNameLen = mArray[mArrPos].Length();
            nsZipItem* ze = mJar->mZip->GetItem(entryName);
            NS_ENSURE_TRUE(ze, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);

            // Last Modified Time
            PRExplodedTime tm;
            PR_ExplodeTime(ze->LastModTime(), PR_GMTParameters, &tm);
            char itemLastModTime[65];
            PR_FormatTimeUSEnglish(itemLastModTime,
                                   sizeof(itemLastModTime),
                                   " %a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ",
                                   &tm);

            // write a 201: line to the buffer for this item
            // 200: filename content-length last-modified file-type
            mBuffer.AppendLiteral("201: ");

            // Names must be escaped and relative, so use the pre-calculated length
            // of the directory name as the offset into the string
            // NS_EscapeURL adds the escaped URL to the give string buffer
            NS_EscapeURL(entryName + mNameLen,
                         entryNameLen - mNameLen, 
                         esc_Minimal | esc_AlwaysCopy,
                         mBuffer);

            mBuffer.Append(' ');
            mBuffer.AppendInt(ze->RealSize(), 10);
            mBuffer.Append(itemLastModTime); // starts/ends with ' '
            if (ze->IsDirectory()) 
                mBuffer.AppendLiteral("DIRECTORY\n");
            else
                mBuffer.AppendLiteral("FILE\n");
        }

        // Copy up to the desired amount of data to buffer
        numRead += CopyDataToBuffer(aBuffer, aCount);
    }

    *aBytesRead = numRead;
    return NS_OK;
}