Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/thebes/gfxSkipChars.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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
#include "gfxSkipChars.h"
7
#include "mozilla/BinarySearch.h"
8
#include "mozilla/gfx/Logging.h"
9
10
struct SkippedRangeStartComparator
11
{
12
    const uint32_t mOffset;
13
0
    explicit SkippedRangeStartComparator(const uint32_t aOffset) : mOffset(aOffset) {}
14
0
    int operator()(const gfxSkipChars::SkippedRange& aRange) const {
15
0
        return (mOffset < aRange.Start()) ? -1 : 1;
16
0
    }
17
};
18
19
void
20
gfxSkipCharsIterator::SetOriginalOffset(int32_t aOffset)
21
0
{
22
0
    aOffset += mOriginalStringToSkipCharsOffset;
23
0
    if (MOZ_UNLIKELY(uint32_t(aOffset) > mSkipChars->mCharCount)) {
24
0
        gfxCriticalError() <<
25
0
            "invalid offset " << aOffset <<
26
0
            " for gfxSkipChars length " << mSkipChars->mCharCount;
27
0
        aOffset = mSkipChars->mCharCount;
28
0
    }
29
0
30
0
    mOriginalStringOffset = aOffset;
31
0
32
0
    const uint32_t rangeCount = mSkipChars->mRanges.Length();
33
0
    if (rangeCount == 0) {
34
0
        mSkippedStringOffset = aOffset;
35
0
        return;
36
0
    }
37
0
38
0
    // at start of string?
39
0
    if (aOffset == 0) {
40
0
        mSkippedStringOffset = 0;
41
0
        mCurrentRangeIndex =
42
0
            rangeCount && mSkipChars->mRanges[0].Start() == 0 ? 0 : -1;
43
0
        return;
44
0
    }
45
0
46
0
    // find the range that includes or precedes aOffset
47
0
    const nsTArray<gfxSkipChars::SkippedRange>& ranges = mSkipChars->mRanges;
48
0
    size_t idx;
49
0
    mozilla::BinarySearchIf(ranges, 0, rangeCount,
50
0
                            SkippedRangeStartComparator(aOffset),
51
0
                            &idx);
52
0
53
0
    if (idx == rangeCount) {
54
0
        mCurrentRangeIndex = rangeCount - 1;
55
0
    } else if (uint32_t(aOffset) < ranges[idx].Start()) {
56
0
        mCurrentRangeIndex = idx - 1;
57
0
        if (mCurrentRangeIndex == -1) {
58
0
            mSkippedStringOffset = aOffset;
59
0
            return;
60
0
        }
61
0
    } else {
62
0
        mCurrentRangeIndex = idx;
63
0
    }
64
0
65
0
    const gfxSkipChars::SkippedRange& r = ranges[mCurrentRangeIndex];
66
0
    if (uint32_t(aOffset) < r.End()) {
67
0
        mSkippedStringOffset = r.SkippedOffset();
68
0
        return;
69
0
    }
70
0
71
0
    mSkippedStringOffset = aOffset - r.NextDelta();
72
0
}
73
74
struct SkippedRangeOffsetComparator
75
{
76
    const uint32_t mOffset;
77
0
    explicit SkippedRangeOffsetComparator(const uint32_t aOffset) : mOffset(aOffset) {}
78
0
    int operator()(const gfxSkipChars::SkippedRange& aRange) const {
79
0
        return (mOffset < aRange.SkippedOffset()) ? -1 : 1;
80
0
    }
81
};
82
83
void
84
gfxSkipCharsIterator::SetSkippedOffset(uint32_t aOffset)
85
0
{
86
0
    NS_ASSERTION((mSkipChars->mRanges.IsEmpty() &&
87
0
                  aOffset <= mSkipChars->mCharCount) ||
88
0
                 (aOffset <= mSkipChars->LastRange().SkippedOffset() +
89
0
                                 mSkipChars->mCharCount -
90
0
                                 mSkipChars->LastRange().End()),
91
0
                 "Invalid skipped offset");
92
0
    mSkippedStringOffset = aOffset;
93
0
94
0
    uint32_t rangeCount = mSkipChars->mRanges.Length();
95
0
    if (rangeCount == 0) {
96
0
        mOriginalStringOffset = aOffset;
97
0
        return;
98
0
    }
99
0
100
0
    const nsTArray<gfxSkipChars::SkippedRange>& ranges = mSkipChars->mRanges;
101
0
    size_t idx;
102
0
    mozilla::BinarySearchIf(ranges, 0, rangeCount,
103
0
                            SkippedRangeOffsetComparator(aOffset),
104
0
                            &idx);
105
0
106
0
    if (idx == rangeCount) {
107
0
        mCurrentRangeIndex = rangeCount - 1;
108
0
    } else if (aOffset < ranges[idx].SkippedOffset()) {
109
0
        mCurrentRangeIndex = idx - 1;
110
0
        if (mCurrentRangeIndex == -1) {
111
0
            mOriginalStringOffset = aOffset;
112
0
            return;
113
0
        }
114
0
    } else {
115
0
        mCurrentRangeIndex = idx;
116
0
    }
117
0
118
0
    const gfxSkipChars::SkippedRange& r = ranges[mCurrentRangeIndex];
119
0
    mOriginalStringOffset = r.End() + aOffset - r.SkippedOffset();
120
0
}
121
122
bool
123
gfxSkipCharsIterator::IsOriginalCharSkipped(int32_t* aRunLength) const
124
0
{
125
0
    if (mCurrentRangeIndex == -1) {
126
0
        // we're before the first skipped range (if any)
127
0
        if (aRunLength) {
128
0
            uint32_t end = mSkipChars->mRanges.IsEmpty() ?
129
0
                mSkipChars->mCharCount : mSkipChars->mRanges[0].Start();
130
0
            *aRunLength = end - mOriginalStringOffset;
131
0
        }
132
0
        return mSkipChars->mCharCount == uint32_t(mOriginalStringOffset);
133
0
    }
134
0
135
0
    const gfxSkipChars::SkippedRange& range =
136
0
        mSkipChars->mRanges[mCurrentRangeIndex];
137
0
138
0
    if (uint32_t(mOriginalStringOffset) < range.End()) {
139
0
        if (aRunLength) {
140
0
            *aRunLength = range.End() - mOriginalStringOffset;
141
0
        }
142
0
        return true;
143
0
    }
144
0
145
0
    if (aRunLength) {
146
0
        uint32_t end =
147
0
            uint32_t(mCurrentRangeIndex) + 1 < mSkipChars->mRanges.Length() ?
148
0
                mSkipChars->mRanges[mCurrentRangeIndex + 1].Start() :
149
0
                mSkipChars->mCharCount;
150
0
        *aRunLength = end - mOriginalStringOffset;
151
0
    }
152
0
153
0
    return mSkipChars->mCharCount == uint32_t(mOriginalStringOffset);
154
0
}