示例#1
0
bool
MP4Sample::Replace(const uint8_t* aData, size_t aSize)
{
  // If the existing MediaBuffer has enough space then we just recycle it. If
  // not then we copy to a new buffer.
  uint8_t* newData = mMediaBuffer && aSize <= mMediaBuffer->size()
                       ? data
                       : new ((fallible_t())) uint8_t[aSize];
  if (!newData) {
    return false;
  }

  memcpy(newData, aData, aSize);
  size = aSize;

  if (newData != data) {
    extra_buffer = data = newData;
    if (mMediaBuffer) {
      mMediaBuffer->release();
      mMediaBuffer = nullptr;
    }
  }

  return true;
}
示例#2
0
NS_IMETHODIMP
AsyncFaviconDataReady::OnFaviconDataAvailable(nsIURI *aFaviconURI, 
                                              PRUint32 aDataLen,
                                              const PRUint8 *aData, 
                                              const nsACString &aMimeType)
{
  if (!aDataLen || !aData) {
    return NS_OK;
  }

  nsCOMPtr<nsIFile> icoFile;
  nsresult rv = JumpListShortcut::GetOutputIconPath(mNewURI, icoFile);
  NS_ENSURE_SUCCESS(rv, rv);
  nsAutoString path;
  rv = icoFile->GetPath(path);
  NS_ENSURE_SUCCESS(rv, rv);

  // Allocate a new buffer that we own and can use out of line in 
  // another thread.  Copy the favicon raw data into it.
  const fallible_t fallible = fallible_t();
  PRUint8 *data = new (fallible) PRUint8[aDataLen];
  if (!data) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  memcpy(data, aData, aDataLen);

  //AsyncWriteIconToDisk takes ownership of the heap allocated buffer.
  nsCOMPtr<nsIRunnable> event = new AsyncWriteIconToDisk(path, aMimeType, 
                                                         data, 
                                                         aDataLen);
  mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);

  return NS_OK;
}
示例#3
0
bool
MP4Sample::Pad(size_t aPaddingBytes)
{
  size_t newSize = size + aPaddingBytes;

  // If the existing MediaBuffer has enough space then we just recycle it. If
  // not then we copy to a new buffer.
  uint8_t* newData = mMediaBuffer && newSize <= mMediaBuffer->size()
                       ? data
                       : new ((fallible_t())) uint8_t[newSize];
  if (!newData) {
    return false;
  }

  memset(newData + size, 0, aPaddingBytes);

  if (newData != data) {
    memcpy(newData, data, size);
    extra_buffer = data = newData;
    if (mMediaBuffer) {
      mMediaBuffer->release();
      mMediaBuffer = nullptr;
    }
  }

  return true;
}
bool
nsTSubstring_CharT::Assign( const substring_tuple_type& tuple, const fallible_t& )
  {
    if (tuple.IsDependentOn(mData, mData + mLength))
      {
        // take advantage of sharing here...
        return Assign(string_type(tuple), fallible_t());
      }

    size_type length = tuple.Length();

    // don't use ReplacePrep here because it changes the length
    char_type* oldData;
    uint32_t oldFlags;
    if (!MutatePrep(length, &oldData, &oldFlags))
      return false;

    if (oldData)
      ::ReleaseData(oldData, oldFlags);

    tuple.WriteTo(mData, length);
    mData[length] = 0;
    mLength = length;
    return true;
  }
bool
nsTSubstring_CharT::SetLength( size_type length, const fallible_t& )
  {
    if (!SetCapacity(length, fallible_t()))
      return false;

    mLength = length;
    return true;
  }
示例#6
0
void
TextEncoder::Encode(JSContext* aCx,
                    JS::Handle<JSObject*> aObj,
                    const nsAString& aString,
                    const bool aStream,
		    JS::MutableHandle<JSObject*> aRetval,
                    ErrorResult& aRv)
{
  // Run the steps of the encoding algorithm.
  int32_t srcLen = aString.Length();
  int32_t maxLen;
  const char16_t* data = PromiseFlatString(aString).get();
  nsresult rv = mEncoder->GetMaxLength(data, srcLen, &maxLen);
  if (NS_FAILED(rv)) {
    aRv.Throw(rv);
    return;
  }
  // Need a fallible allocator because the caller may be a content
  // and the content can specify the length of the string.
  static const fallible_t fallible = fallible_t();
  nsAutoArrayPtr<char> buf(new (fallible) char[maxLen + 1]);
  if (!buf) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  int32_t dstLen = maxLen;
  rv = mEncoder->Convert(data, &srcLen, buf, &dstLen);

  // If the internal streaming flag is not set, then reset
  // the encoding algorithm state to the default values for encoding.
  if (!aStream) {
    int32_t finishLen = maxLen - dstLen;
    rv = mEncoder->Finish(buf + dstLen, &finishLen);
    if (NS_SUCCEEDED(rv)) {
      dstLen += finishLen;
    }
  }

  JSObject* outView = nullptr;
  if (NS_SUCCEEDED(rv)) {
    buf[dstLen] = '\0';
    JSAutoCompartment ac(aCx, aObj);
    outView = Uint8Array::Create(aCx, dstLen,
                                 reinterpret_cast<uint8_t*>(buf.get()));
    if (!outView) {
      aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
      return;
    }
  }

  if (NS_FAILED(rv)) {
    aRv.Throw(rv);
  }
  aRetval.set(outView);
}
示例#7
0
bool
MemoryTextureClient::Allocate(uint32_t aSize)
{
  MOZ_ASSERT(!mBuffer);
  static const fallible_t fallible = fallible_t();
  mBuffer = new(fallible) uint8_t[aSize];
  if (!mBuffer) {
    NS_WARNING("Failed to allocate buffer");
    return false;
  }
  mBufSize = aSize;
  return true;
}
bool
nsTSubstring_CharT::EnsureMutable( size_type newLen )
  {
    if (newLen == size_type(-1) || newLen == mLength)
      {
        if (mFlags & (F_FIXED | F_OWNED))
          return true;
        if ((mFlags & F_SHARED) && !nsStringBuffer::FromData(mData)->IsReadonly())
          return true;

        newLen = mLength;
      }
    return SetLength(newLen, fallible_t());
  }
示例#9
0
void
TextDecoder::Decode(const char* aInput, const int32_t aLength,
                    const bool aStream, nsAString& aOutDecodedString,
                    ErrorResult& aRv)
{
  aOutDecodedString.Truncate();

  // Run or resume the decoder algorithm of the decoder object's encoder.
  int32_t outLen;
  nsresult rv = mDecoder->GetMaxLength(aInput, aLength, &outLen);
  if (NS_FAILED(rv)) {
    aRv.Throw(rv);
    return;
  }
  // Need a fallible allocator because the caller may be a content
  // and the content can specify the length of the string.
  static const fallible_t fallible = fallible_t();
  nsAutoArrayPtr<char16_t> buf(new (fallible) char16_t[outLen + 1]);
  if (!buf) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  int32_t length = aLength;
  rv = mDecoder->Convert(aInput, &length, buf, &outLen);
  MOZ_ASSERT(mFatal || rv != NS_ERROR_ILLEGAL_INPUT);
  buf[outLen] = 0;
  aOutDecodedString.Append(buf, outLen);

  // If the internal streaming flag of the decoder object is not set,
  // then reset the encoding algorithm state to the default values
  if (!aStream) {
    mDecoder->Reset();
    if (rv == NS_OK_UDEC_MOREINPUT) {
      if (mFatal) {
        aRv.Throw(NS_ERROR_DOM_ENCODING_DECODE_ERR);
      } else {
        // Need to emit a decode error manually
        // to simulate the EOF handling of the Encoding spec.
        aOutDecodedString.Append(kReplacementChar);
      }
    }
  }

  if (NS_FAILED(rv)) {
    aRv.Throw(NS_ERROR_DOM_ENCODING_DECODE_ERR);
  }
}
示例#10
0
bool
nsTSubstring_CharT::AssignASCII( const char* data, size_type length, const fallible_t& )
  {
    // A Unicode string can't depend on an ASCII string buffer,
    // so this dependence check only applies to CStrings.
#ifdef CharT_is_char
    if (IsDependentOn(data, data + length))
      {
        return Assign(string_type(data, length), fallible_t());
      }
#endif

    if (!ReplacePrep(0, mLength, length))
      return false;

    char_traits::copyASCII(mData, data, length);
    return true;
  }
示例#11
0
MP4Sample*
MP4Sample::Clone() const
{
  nsAutoPtr<MP4Sample> s(new MP4Sample());
  s->decode_timestamp = decode_timestamp;
  s->composition_timestamp = composition_timestamp;
  s->duration = duration;
  s->byte_offset = byte_offset;
  s->is_sync_point = is_sync_point;
  s->size = size;
  s->crypto = crypto;
  s->extra_data = extra_data;
  s->extra_buffer = s->data = new ((fallible_t())) uint8_t[size];
  if (!s->extra_buffer) {
    return nullptr;
  }
  memcpy(s->data, data, size);
  return s.forget();
}
示例#12
0
// We put the atoms in a hash table for speedy lookup.. see ResolveAtom.
nsresult
nsHttp::CreateAtomTable()
{
    MOZ_ASSERT(!sAtomTable.ops, "atom table already initialized");

    if (!sLock) {
        sLock = new Mutex("nsHttp.sLock");
    }

    // The initial length for this table is a value greater than the number of
    // known atoms (NUM_HTTP_ATOMS) because we expect to encounter a few random
    // headers right off the bat.
    if (!PL_DHashTableInit(&sAtomTable, &ops, nullptr,
                           sizeof(PLDHashEntryStub),
                           fallible_t(), NUM_HTTP_ATOMS + 10)) {
        sAtomTable.ops = nullptr;
        return NS_ERROR_OUT_OF_MEMORY;
    }

    // fill the table with our known atoms
    const char *const atoms[] = {
#define HTTP_ATOM(_name, _value) nsHttp::_name._val,
#include "nsHttpAtomList.h"
#undef HTTP_ATOM
        nullptr
    };

    for (int i = 0; atoms[i]; ++i) {
        PLDHashEntryStub *stub = reinterpret_cast<PLDHashEntryStub *>
                                                 (PL_DHashTableOperate(&sAtomTable, atoms[i], PL_DHASH_ADD));
        if (!stub)
            return NS_ERROR_OUT_OF_MEMORY;

        MOZ_ASSERT(!stub->key, "duplicate static atom");
        stub->key = atoms[i];
    }

    return NS_OK;
}
示例#13
0
bool
nsTSubstring_CharT::Assign( const char_type* data, size_type length, const fallible_t& )
  {
    if (!data)
      {
        Truncate();
        return true;
      }

    if (length == size_type(-1))
      length = char_traits::length(data);

    if (IsDependentOn(data, data + length))
      {
        return Assign(string_type(data, length), fallible_t());
      }

    if (!ReplacePrep(0, mLength, length))
      return false;

    char_traits::copy(mData, data, length);
    return true;
  }
示例#14
0
static
nsresult
Base64urlEncode(const PRUint8* aBytes,
                PRUint32 aNumBytes,
                nsCString& _result)
{
  // SetLength does not set aside space for NULL termination.  PL_Base64Encode
  // will not NULL terminate, however, nsCStrings must be NULL terminated.  As a
  // result, we set the capacity to be one greater than what we need, and the
  // length to our desired length.
  PRUint32 length = (aNumBytes + 2) / 3 * 4; // +2 due to integer math.
  NS_ENSURE_TRUE(_result.SetCapacity(length + 1, fallible_t()),
                 NS_ERROR_OUT_OF_MEMORY);
  _result.SetLength(length);
  (void)PL_Base64Encode(reinterpret_cast<const char*>(aBytes), aNumBytes,
                        _result.BeginWriting());

  // base64url encoding is defined in RFC 4648.  It replaces the last two
  // alphabet characters of base64 encoding with '-' and '_' respectively.
  _result.ReplaceChar('+', '-');
  _result.ReplaceChar('/', '_');
  return NS_OK;
}
示例#15
0
bool
nsTSubstring_CharT::Assign( const self_type& str, const fallible_t& )
  {
    // |str| could be sharable.  we need to check its flags to know how to
    // deal with it.

    if (&str == this)
      return true;

    if (!str.mLength)
      {
        Truncate();
        mFlags |= str.mFlags & F_VOIDED;
        return true;
      }

    if (str.mFlags & F_SHARED)
      {
        // nice! we can avoid a string copy :-)

        // |str| should be null-terminated
        NS_ASSERTION(str.mFlags & F_TERMINATED, "shared, but not terminated");

        ::ReleaseData(mData, mFlags);

        mData = str.mData;
        mLength = str.mLength;
        SetDataFlags(F_TERMINATED | F_SHARED);

        // get an owning reference to the mData
        nsStringBuffer::FromData(mData)->AddRef();
        return true;
      }

    // else, treat this like an ordinary assignment.
    return Assign(str.Data(), str.Length(), fallible_t());
  }
void
MediaDecodeTask::Decode()
{
  MOZ_ASSERT(!mThreadPool == NS_IsMainThread(),
             "We should be on the main thread only if we don't have a thread pool");

  mBufferDecoder->BeginDecoding(NS_GetCurrentThread());

  // Tell the decoder reader that we are not going to play the data directly,
  // and that we should not reject files with more channels than the audio
  // bakend support.
  mDecoderReader->SetIgnoreAudioOutputFormat();

  mDecoderReader->OnDecodeThreadStart();

  MediaInfo mediaInfo;
  nsAutoPtr<MetadataTags> tags;
  nsresult rv = mDecoderReader->ReadMetadata(&mediaInfo, getter_Transfers(tags));
  if (NS_FAILED(rv)) {
    ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent);
    return;
  }

  if (!mDecoderReader->HasAudio()) {
    ReportFailureOnMainThread(WebAudioDecodeJob::NoAudio);
    return;
  }

  while (mDecoderReader->DecodeAudioData()) {
    // consume all of the buffer
    continue;
  }

  mDecoderReader->OnDecodeThreadFinish();

  MediaQueue<AudioData>& audioQueue = mDecoderReader->AudioQueue();
  uint32_t frameCount = audioQueue.FrameCount();
  uint32_t channelCount = mediaInfo.mAudio.mChannels;
  uint32_t sampleRate = mediaInfo.mAudio.mRate;

  if (!frameCount || !channelCount || !sampleRate) {
    ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent);
    return;
  }

  const uint32_t destSampleRate = mDecodeJob.mContext->SampleRate();
  AutoResampler resampler;

  uint32_t resampledFrames = frameCount;
  if (sampleRate != destSampleRate) {
    resampledFrames = static_cast<uint32_t>(
        static_cast<uint64_t>(destSampleRate) *
        static_cast<uint64_t>(frameCount) /
        static_cast<uint64_t>(sampleRate)
      );

    resampler = speex_resampler_init(channelCount,
                                     sampleRate,
                                     destSampleRate,
                                     SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr);
    speex_resampler_skip_zeros(resampler);
    resampledFrames += speex_resampler_get_output_latency(resampler);
  }

  // Allocate the channel buffers.  Note that if we end up resampling, we may
  // write fewer bytes than mResampledFrames to the output buffer, in which
  // case mWriteIndex will tell us how many valid samples we have.
  static const fallible_t fallible = fallible_t();
  bool memoryAllocationSuccess = true;
  if (!mDecodeJob.mChannelBuffers.SetLength(channelCount)) {
    memoryAllocationSuccess = false;
  } else {
    for (uint32_t i = 0; i < channelCount; ++i) {
      mDecodeJob.mChannelBuffers[i] = new(fallible) float[resampledFrames];
      if (!mDecodeJob.mChannelBuffers[i]) {
        memoryAllocationSuccess = false;
        break;
      }
    }
  }
  if (!memoryAllocationSuccess) {
    ReportFailureOnMainThread(WebAudioDecodeJob::UnknownError);
    return;
  }

  nsAutoPtr<AudioData> audioData;
  while ((audioData = audioQueue.PopFront())) {
    audioData->EnsureAudioBuffer(); // could lead to a copy :(
    AudioDataValue* bufferData = static_cast<AudioDataValue*>
      (audioData->mAudioBuffer->Data());

    if (sampleRate != destSampleRate) {
      const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex;

      for (uint32_t i = 0; i < audioData->mChannels; ++i) {
        uint32_t inSamples = audioData->mFrames;
        uint32_t outSamples = maxOutSamples;

        WebAudioUtils::SpeexResamplerProcess(
            resampler, i, &bufferData[i * audioData->mFrames], &inSamples,
            mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex,
            &outSamples);

        if (i == audioData->mChannels - 1) {
          mDecodeJob.mWriteIndex += outSamples;
          MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames);
          MOZ_ASSERT(inSamples == audioData->mFrames);
        }
      }
    } else {
      for (uint32_t i = 0; i < audioData->mChannels; ++i) {
        ConvertAudioSamples(&bufferData[i * audioData->mFrames],
                            mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex,
                            audioData->mFrames);

        if (i == audioData->mChannels - 1) {
          mDecodeJob.mWriteIndex += audioData->mFrames;
        }
      }
    }
  }

  if (sampleRate != destSampleRate) {
    uint32_t inputLatency = speex_resampler_get_input_latency(resampler);
    const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex;
    for (uint32_t i = 0; i < channelCount; ++i) {
      uint32_t inSamples = inputLatency;
      uint32_t outSamples = maxOutSamples;

      WebAudioUtils::SpeexResamplerProcess(
          resampler, i, (AudioDataValue*)nullptr, &inSamples,
          mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex,
          &outSamples);

      if (i == channelCount - 1) {
        mDecodeJob.mWriteIndex += outSamples;
        MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames);
        MOZ_ASSERT(inSamples == inputLatency);
      }
    }
  }

  mPhase = PhaseEnum::AllocateBuffer;
  RunNextPhase();
}
示例#17
0
NS_IMETHODIMP
AsyncFaviconDataReady::OnComplete(nsIURI *aFaviconURI,
                                  uint32_t aDataLen,
                                  const uint8_t *aData, 
                                  const nsACString &aMimeType)
{
  if (!aDataLen || !aData) {
    if (mURLShortcut) {
      OnFaviconDataNotAvailable();
    }
    
    return NS_OK;
  }

  nsCOMPtr<nsIFile> icoFile;
  nsresult rv = FaviconHelper::GetOutputIconPath(mNewURI, icoFile, mURLShortcut);
  NS_ENSURE_SUCCESS(rv, rv);
  
  nsAutoString path;
  rv = icoFile->GetPath(path);
  NS_ENSURE_SUCCESS(rv, rv);

  // Convert the obtained favicon data to an input stream
  nsCOMPtr<nsIInputStream> stream;
  rv = NS_NewByteInputStream(getter_AddRefs(stream),
                             reinterpret_cast<const char*>(aData),
                             aDataLen,
                             NS_ASSIGNMENT_DEPEND);
  NS_ENSURE_SUCCESS(rv, rv);

  // Decode the image from the format it was returned to us in (probably PNG)
  nsAutoCString mimeTypeOfInputData;
  mimeTypeOfInputData.AssignLiteral("image/vnd.microsoft.icon");
  nsCOMPtr<imgIContainer> container;
  nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1");
  rv = imgtool->DecodeImageData(stream, aMimeType,
                                getter_AddRefs(container));
  NS_ENSURE_SUCCESS(rv, rv);

  nsRefPtr<gfxASurface> imgFrame =
    container->GetFrame(imgIContainer::FRAME_FIRST, 0);
  NS_ENSURE_TRUE(imgFrame, NS_ERROR_FAILURE);

  nsRefPtr<gfxImageSurface> imageSurface;
  gfxIntSize size;
  if (mURLShortcut) {
    imageSurface =
      new gfxImageSurface(gfxIntSize(48, 48),
                          gfxImageFormat::ARGB32);
    gfxContext context(imageSurface);
    context.SetOperator(gfxContext::OPERATOR_SOURCE);
    context.SetColor(gfxRGBA(1, 1, 1, 1));
    context.Rectangle(gfxRect(0, 0, 48, 48));
    context.Fill();

    context.Translate(gfxPoint(16, 16));
    context.SetOperator(gfxContext::OPERATOR_OVER);
    context.DrawSurface(imgFrame,  gfxSize(16, 16));
    size = imageSurface->GetSize();
  } else {
    imageSurface = imgFrame->GetAsReadableARGB32ImageSurface();
    size.width = GetSystemMetrics(SM_CXSMICON);
    size.height = GetSystemMetrics(SM_CYSMICON);
    if (!size.width || !size.height) {
      size.width = 16;
      size.height = 16;
    }
  }

  // Allocate a new buffer that we own and can use out of line in 
  // another thread.  Copy the favicon raw data into it.
  const fallible_t fallible = fallible_t();
  uint8_t *data = new (fallible) uint8_t[imageSurface->GetDataSize()];
  if (!data) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  memcpy(data, imageSurface->Data(), imageSurface->GetDataSize());

  // AsyncEncodeAndWriteIcon takes ownership of the heap allocated buffer
  nsCOMPtr<nsIRunnable> event = new AsyncEncodeAndWriteIcon(path, data,
                                                            imageSurface->GetDataSize(),
                                                            imageSurface->Stride(),
                                                            size.width,
                                                            size.height,
                                                            mURLShortcut);
  mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);

  return NS_OK;
}
示例#18
0
文件: empty-2.C 项目: AHelper/gcc
// PR c++/45307
// { dg-options "-fdump-tree-gimple -fdump-tree-optimized -O" }

struct fallible_t { };
const fallible_t fallible = fallible_t();

void t(void)
{
}

// { dg-final { scan-tree-dump-not "fallible" "gimple" } }
// Whole constructor should be optimized away.
// { dg-final { scan-tree-dump-not "int" "optimized" } }
// { dg-final { cleanup-tree-dump "gimple" } }
// { dg-final { cleanup-tree-dump "optimized" } }
示例#19
0
void
nsTSubstring_CharT::Assign( const char_type* data )
  {
    if (!Assign(data, size_type(-1), fallible_t()))
      NS_RUNTIMEABORT("OOM");
  }
nsresult
SnappyUncompressInputStream::ParseNextChunk(uint32_t* aBytesReadOut)
{
  // There must not be any uncompressed data already in mUncompressedBuffer.
  MOZ_ASSERT(mUncompressedBytes == 0);
  MOZ_ASSERT(mNextByte == 0);

  nsresult rv;
  *aBytesReadOut = 0;

  // Lazily create our two buffers so we can report OOM during stream
  // operation.  These allocations only happens once.  The buffers are reused
  // until the stream is closed.
  if (!mUncompressedBuffer) {
    mUncompressedBuffer.reset(new ((fallible_t())) char[snappy::kBlockSize]);
    if (NS_WARN_IF(!mUncompressedBuffer)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  if (!mCompressedBuffer) {
    mCompressedBuffer.reset(new ((fallible_t())) char[kCompressedBufferLength]);
    if (NS_WARN_IF(!mCompressedBuffer)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  // We have no decompressed data and we also have not seen the start of stream
  // yet. Read and validate the StreamIdentifier chunk.  Also read the next
  // header to determine the size of the first real data chunk.
  if (mNeedFirstStreamIdentifier) {
    const uint32_t firstReadLength = kHeaderLength +
                                     kStreamIdentifierDataLength +
                                     kHeaderLength;
    MOZ_ASSERT(firstReadLength <= kCompressedBufferLength);

    rv = ReadAll(mCompressedBuffer.get(), firstReadLength, firstReadLength,
                 aBytesReadOut);
    if (NS_WARN_IF(NS_FAILED(rv)) || *aBytesReadOut == 0) { return rv; }

    rv = ParseHeader(mCompressedBuffer.get(), kHeaderLength,
                     &mNextChunkType, &mNextChunkDataLength);
    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
    if (NS_WARN_IF(mNextChunkType != StreamIdentifier ||
                   mNextChunkDataLength != kStreamIdentifierDataLength)) {
      return NS_ERROR_CORRUPTED_CONTENT;
    }
    size_t offset = kHeaderLength;

    mNeedFirstStreamIdentifier = false;

    size_t numRead;
    size_t numWritten;
    rv = ParseData(mUncompressedBuffer.get(), snappy::kBlockSize, mNextChunkType,
                   &mCompressedBuffer[offset],
                   mNextChunkDataLength, &numWritten, &numRead);
    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
    MOZ_ASSERT(numWritten == 0);
    MOZ_ASSERT(numRead == mNextChunkDataLength);
    offset += numRead;

    rv = ParseHeader(&mCompressedBuffer[offset], *aBytesReadOut - offset,
                     &mNextChunkType, &mNextChunkDataLength);
    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }

    return NS_OK;
  }

  // We have no compressed data and we don't know how big the next chunk is.
  // This happens when we get an EOF pause in the middle of a stream and also
  // at the end of the stream.  Simply read the next header and return.  The
  // chunk body will be read on the next entry into this method.
  if (mNextChunkType == Unknown) {
    rv = ReadAll(mCompressedBuffer.get(), kHeaderLength, kHeaderLength,
                 aBytesReadOut);
    if (NS_WARN_IF(NS_FAILED(rv)) || *aBytesReadOut == 0) { return rv; }

    rv = ParseHeader(mCompressedBuffer.get(), kHeaderLength,
                     &mNextChunkType, &mNextChunkDataLength);
    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }

    return NS_OK;
  }

  // We have no decompressed data, but we do know the size of the next chunk.
  // Read at least that much from the base stream.
  uint32_t readLength = mNextChunkDataLength;
  MOZ_ASSERT(readLength <= kCompressedBufferLength);

  // However, if there is enough data in the base stream, also read the next
  // chunk header.  This helps optimize the stream by avoiding many small reads.
  uint64_t avail;
  rv = mBaseStream->Available(&avail);
  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
  if (avail >= (readLength + kHeaderLength)) {
    readLength += kHeaderLength;
    MOZ_ASSERT(readLength <= kCompressedBufferLength);
  }

  rv = ReadAll(mCompressedBuffer.get(), readLength, mNextChunkDataLength,
               aBytesReadOut);
  if (NS_WARN_IF(NS_FAILED(rv)) || *aBytesReadOut == 0) { return rv; }

  size_t numRead;
  size_t numWritten;
  rv = ParseData(mUncompressedBuffer.get(), snappy::kBlockSize, mNextChunkType,
                 mCompressedBuffer.get(), mNextChunkDataLength,
                 &numWritten, &numRead);
  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
  MOZ_ASSERT(numRead == mNextChunkDataLength);

  mUncompressedBytes = numWritten;

  // If we were unable to directly read the next chunk header, then clear
  // our internal state.  We will have to perform a small read to get the
  // header the next time we enter this method.
  if (*aBytesReadOut <= mNextChunkDataLength) {
    mNextChunkType = Unknown;
    mNextChunkDataLength = 0;
    return NS_OK;
  }

  // We got the next chunk header.  Parse it so that we are ready to for the
  // next call into this method.
  rv = ParseHeader(&mCompressedBuffer[numRead], *aBytesReadOut - numRead,
                   &mNextChunkType, &mNextChunkDataLength);
  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }

  return NS_OK;
}
示例#21
0
namespace mozilla {

const fallible_t fallible = fallible_t();

} // namespace mozilla
示例#22
0
void
nsTSubstring_CharT::AssignASCII( const char* data, size_type length )
  {
    if (!AssignASCII(data, length, fallible_t()))
      NS_RUNTIMEABORT("OOM");
  }
示例#23
0
void
nsTSubstring_CharT::SetCapacity( size_type capacity )
  {
    if (!SetCapacity(capacity, fallible_t()))
      NS_RUNTIMEABORT("OOM");
  }
示例#24
0
void
nsTSubstring_CharT::Assign( const self_type& str )
{
  if (!Assign(str, fallible_t()))
    NS_RUNTIMEABORT("OOM");
}
示例#25
0
void
nsTSubstring_CharT::Assign( const substring_tuple_type& tuple )
  {
    if (!Assign(tuple, fallible_t()))
      NS_RUNTIMEABORT("OOM");
  }