Line data Source code
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 <algorithm>
9 :
10 : namespace mozilla {
11 : namespace net {
12 :
13 0 : SimpleBuffer::SimpleBuffer()
14 : : mStatus(NS_OK)
15 0 : , mAvailable(0)
16 : {
17 0 : }
18 :
19 0 : nsresult SimpleBuffer::Write(char *src, size_t len)
20 : {
21 0 : NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
22 0 : if (NS_FAILED(mStatus)) {
23 0 : return mStatus;
24 : }
25 :
26 0 : while (len > 0) {
27 0 : SimpleBufferPage *p = mBufferList.getLast();
28 0 : if (p && (p->mWriteOffset == SimpleBufferPage::kSimpleBufferPageSize)) {
29 : // no room.. make a new page
30 0 : p = nullptr;
31 : }
32 0 : if (!p) {
33 0 : p = new (fallible) SimpleBufferPage();
34 0 : if (!p) {
35 0 : mStatus = NS_ERROR_OUT_OF_MEMORY;
36 0 : return mStatus;
37 : }
38 0 : mBufferList.insertBack(p);
39 : }
40 0 : size_t roomOnPage = SimpleBufferPage::kSimpleBufferPageSize - p->mWriteOffset;
41 0 : size_t toWrite = std::min(roomOnPage, len);
42 0 : memcpy(p->mBuffer + p->mWriteOffset, src, toWrite);
43 0 : src += toWrite;
44 0 : len -= toWrite;
45 0 : p->mWriteOffset += toWrite;
46 0 : mAvailable += toWrite;
47 : }
48 0 : return NS_OK;
49 : }
50 :
51 0 : size_t SimpleBuffer::Read(char *dest, size_t maxLen)
52 : {
53 0 : NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
54 0 : if (NS_FAILED(mStatus)) {
55 0 : return 0;
56 : }
57 :
58 0 : size_t rv = 0;
59 0 : for (SimpleBufferPage *p = mBufferList.getFirst();
60 0 : p && (rv < maxLen); p = mBufferList.getFirst()) {
61 0 : size_t avail = p->mWriteOffset - p->mReadOffset;
62 0 : size_t toRead = std::min(avail, (maxLen - rv));
63 0 : memcpy(dest + rv, p->mBuffer + p->mReadOffset, toRead);
64 0 : rv += toRead;
65 0 : p->mReadOffset += toRead;
66 0 : if (p->mReadOffset == p->mWriteOffset) {
67 0 : p->remove();
68 0 : delete p;
69 : }
70 : }
71 :
72 0 : MOZ_ASSERT(mAvailable >= rv);
73 0 : mAvailable -= rv;
74 0 : return rv;
75 : }
76 :
77 0 : size_t SimpleBuffer::Available()
78 : {
79 0 : NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
80 0 : return NS_SUCCEEDED(mStatus) ? mAvailable : 0;
81 : }
82 :
83 0 : void SimpleBuffer::Clear()
84 : {
85 0 : NS_ASSERT_OWNINGTHREAD(SimpleBuffer);
86 : SimpleBufferPage *p;
87 0 : while ((p = mBufferList.popFirst())) {
88 0 : delete p;
89 : }
90 0 : mAvailable = 0;
91 0 : }
92 :
93 : } // namespace net
94 : } // namespace mozilla
|