1 //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef ChunkSet_h__
7 #define ChunkSet_h__
8 
9 #include "Entries.h"
10 #include "nsString.h"
11 #include "nsTArray.h"
12 
13 namespace mozilla {
14 namespace safebrowsing {
15 
16 /**
17  * Store the chunk numbers as an array of ranges of uint32_t.
18  * We need chunk numbers in order to ask for incremental updates from the
19  * server.
20  */
21 class ChunkSet {
22 public:
23   nsresult Serialize(nsACString& aStr);
24   nsresult Set(uint32_t aChunk);
25   bool Has(uint32_t chunk) const;
26   nsresult Merge(const ChunkSet& aOther);
27   uint32_t Length() const;
28   nsresult Remove(const ChunkSet& aOther);
29   void Clear();
30 
31   nsresult Write(nsIOutputStream* aOut);
32   nsresult Read(nsIInputStream* aIn, uint32_t aNumElements);
33 
34 private:
35   class Range {
36   public:
37     Range(uint32_t aBegin, uint32_t aEnd) : mBegin(aBegin), mEnd(aEnd) {}
38 
39     uint32_t Length() const;
40     nsresult Remove(const Range& aRange, ChunkSet& aRemainderSet) const;
41     bool FoldLeft(const Range& aRange);
42 
43     bool operator==(const Range& rhs) const {
44       return mBegin == rhs.mBegin;
45     }
46     bool operator<(const Range& rhs) const {
47       return mBegin < rhs.mBegin;
48     }
49 
50     uint32_t Begin() const {
51       return mBegin;
52     }
53     void Begin(const uint32_t aBegin) {
54       mBegin = aBegin;
55     }
56     uint32_t End() const {
57       return mEnd;
58     }
59     void End(const uint32_t aEnd) {
60       mEnd = aEnd;
61     }
62 
63     bool Contains(const Range& aRange) const {
64       return mBegin <= aRange.mBegin && aRange.mEnd <= mEnd;
65     }
66     bool Precedes(const Range& aRange) const {
67       return mEnd + 1 == aRange.mBegin;
68     }
69 
70     struct IntersectionComparator {
71       int operator()(const Range& aRange) const {
72         if (aRange.mBegin > mTarget.mEnd) {
73           return -1;
74         }
75         if (mTarget.mBegin > aRange.mEnd) {
76           return 1;
77         }
78         return 0;
79       }
80 
81       explicit IntersectionComparator(const Range& aTarget) : mTarget(aTarget){}
82       const Range& mTarget;
83     };
84 
85   private:
86     uint32_t mBegin;
87     uint32_t mEnd;
88   };
89 
90   static const size_t IO_BUFFER_SIZE = 1024;
91   FallibleTArray<Range> mRanges;
92 
93   bool HasSubrange(const Range& aSubrange) const;
94 };
95 
96 } // namespace safebrowsing
97 } // namespace mozilla
98 
99 #endif
100