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