Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/io/nsSegmentedBuffer.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
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
#ifndef nsSegmentedBuffer_h__
8
#define nsSegmentedBuffer_h__
9
10
class nsSegmentedBuffer
11
{
12
public:
13
  nsSegmentedBuffer()
14
    : mSegmentSize(0)
15
    , mMaxSize(0)
16
    , mSegmentArray(nullptr)
17
    , mSegmentArrayCount(0)
18
    , mFirstSegmentIndex(0)
19
    , mLastSegmentIndex(0)
20
0
  {
21
0
  }
22
23
  ~nsSegmentedBuffer()
24
0
  {
25
0
    Empty();
26
0
  }
27
28
29
  nsresult Init(uint32_t aSegmentSize, uint32_t aMaxSize);
30
31
  char* AppendNewSegment();   // pushes at end
32
33
  // returns true if no more segments remain:
34
  bool DeleteFirstSegment();  // pops from beginning
35
36
  // returns true if no more segments remain:
37
  bool DeleteLastSegment();  // pops from beginning
38
39
  // Call Realloc() on last segment.  This is used to reduce memory
40
  // consumption when data is not an exact multiple of segment size.
41
  bool ReallocLastSegment(size_t aNewSize);
42
43
  void Empty();               // frees all segments
44
45
  inline uint32_t GetSegmentCount()
46
0
  {
47
0
    if (mFirstSegmentIndex <= mLastSegmentIndex) {
48
0
      return mLastSegmentIndex - mFirstSegmentIndex;
49
0
    } else {
50
0
      return mSegmentArrayCount + mLastSegmentIndex - mFirstSegmentIndex;
51
0
    }
52
0
  }
53
54
  inline uint32_t GetSegmentSize()
55
0
  {
56
0
    return mSegmentSize;
57
0
  }
58
  inline uint32_t GetMaxSize()
59
0
  {
60
0
    return mMaxSize;
61
0
  }
62
  inline uint32_t GetSize()
63
0
  {
64
0
    return GetSegmentCount() * mSegmentSize;
65
0
  }
66
67
  inline char* GetSegment(uint32_t aIndex)
68
0
  {
69
0
    NS_ASSERTION(aIndex < GetSegmentCount(), "index out of bounds");
70
0
    int32_t i = ModSegArraySize(mFirstSegmentIndex + (int32_t)aIndex);
71
0
    return mSegmentArray[i];
72
0
  }
73
74
protected:
75
  inline int32_t ModSegArraySize(int32_t aIndex)
76
0
  {
77
0
    uint32_t result = aIndex & (mSegmentArrayCount - 1);
78
0
    NS_ASSERTION(result == aIndex % mSegmentArrayCount,
79
0
                 "non-power-of-2 mSegmentArrayCount");
80
0
    return result;
81
0
  }
82
83
  inline bool IsFull()
84
0
  {
85
0
    return ModSegArraySize(mLastSegmentIndex + 1) == mFirstSegmentIndex;
86
0
  }
87
88
protected:
89
  uint32_t            mSegmentSize;
90
  uint32_t            mMaxSize;
91
  char**              mSegmentArray;
92
  uint32_t            mSegmentArrayCount;
93
  int32_t             mFirstSegmentIndex;
94
  int32_t             mLastSegmentIndex;
95
};
96
97
// NS_SEGMENTARRAY_INITIAL_SIZE: This number needs to start out as a
98
// power of 2 given how it gets used. We double the segment array
99
// when we overflow it, and use that fact that it's a power of 2
100
// to compute a fast modulus operation in IsFull.
101
//
102
// 32 segment array entries can accommodate 128k of data if segments
103
// are 4k in size. That seems like a reasonable amount that will avoid
104
// needing to grow the segment array.
105
0
#define NS_SEGMENTARRAY_INITIAL_COUNT 32
106
107
#endif // nsSegmentedBuffer_h__