tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SimpleBuffer.cpp (2285B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "SimpleBuffer.h"
      8 #include "mozilla/fallible.h"
      9 #include <algorithm>
     10 
     11 namespace mozilla {
     12 namespace net {
     13 
     14 nsresult SimpleBuffer::Write(char* src, size_t len) {
     15  NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
     16  if (NS_FAILED(mStatus)) {
     17    return mStatus;
     18  }
     19 
     20  while (len > 0) {
     21    SimpleBufferPage* p = mBufferList.getLast();
     22    if (p && (p->mWriteOffset == SimpleBufferPage::kSimpleBufferPageSize)) {
     23      // no room.. make a new page
     24      p = nullptr;
     25    }
     26    if (!p) {
     27      p = new (fallible) SimpleBufferPage();
     28      if (!p) {
     29        mStatus = NS_ERROR_OUT_OF_MEMORY;
     30        return mStatus;
     31      }
     32      mBufferList.insertBack(p);
     33    }
     34    size_t roomOnPage =
     35        SimpleBufferPage::kSimpleBufferPageSize - p->mWriteOffset;
     36    size_t toWrite = std::min(roomOnPage, len);
     37    memcpy(p->mBuffer + p->mWriteOffset, src, toWrite);
     38    src += toWrite;
     39    len -= toWrite;
     40    p->mWriteOffset += toWrite;
     41    mAvailable += toWrite;
     42  }
     43  return NS_OK;
     44 }
     45 
     46 size_t SimpleBuffer::Read(char* dest, size_t maxLen) {
     47  NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
     48  if (NS_FAILED(mStatus)) {
     49    return 0;
     50  }
     51 
     52  size_t rv = 0;
     53  for (SimpleBufferPage* p = mBufferList.getFirst(); p && (rv < maxLen);
     54       p = mBufferList.getFirst()) {
     55    size_t avail = p->mWriteOffset - p->mReadOffset;
     56    size_t toRead = std::min(avail, (maxLen - rv));
     57    memcpy(dest + rv, p->mBuffer + p->mReadOffset, toRead);
     58    rv += toRead;
     59    p->mReadOffset += toRead;
     60    if (p->mReadOffset == p->mWriteOffset) {
     61      p->remove();
     62      delete p;
     63    }
     64  }
     65 
     66  MOZ_ASSERT(mAvailable >= rv);
     67  mAvailable -= rv;
     68  return rv;
     69 }
     70 
     71 size_t SimpleBuffer::Available() {
     72  NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
     73  return NS_SUCCEEDED(mStatus) ? mAvailable : 0;
     74 }
     75 
     76 void SimpleBuffer::Clear() {
     77  NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
     78  SimpleBufferPage* p;
     79  while ((p = mBufferList.popFirst())) {
     80    delete p;
     81  }
     82  mAvailable = 0;
     83 }
     84 
     85 }  // namespace net
     86 }  // namespace mozilla