Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/tables/SpanningCellSorter.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
// vim:cindent:ts=4:et:sw=4:
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 SpanningCellSorter_h
8
#define SpanningCellSorter_h
9
10
/*
11
 * Code to sort cells by their colspan, used by BasicTableLayoutStrategy.
12
 */
13
14
#include "PLDHashTable.h"
15
#include "nsDebug.h"
16
#include "StackArena.h"
17
18
/**
19
 * The SpanningCellSorter is responsible for accumulating lists of cells
20
 * with colspans so that those cells can later be enumerated, sorted
21
 * from lowest number of columns spanned to highest.  It does not use a
22
 * stable sort (in fact, it currently reverses).
23
 */
24
class MOZ_STACK_CLASS SpanningCellSorter {
25
public:
26
    SpanningCellSorter();
27
    ~SpanningCellSorter();
28
29
    struct Item {
30
        int32_t row, col;
31
        Item *next;
32
    };
33
34
    /**
35
     * Add a cell to the sorter.  Returns false on out of memory.
36
     * aColSpan is the number of columns spanned, and aRow/aCol are the
37
     * position of the cell in the table (for GetCellInfoAt).
38
     */
39
    bool AddCell(int32_t aColSpan, int32_t aRow, int32_t aCol);
40
41
    /**
42
     * Get the next *list* of cells.  Each list contains all the cells
43
     * for a colspan value, and the lists are given in order from lowest
44
     * to highest colspan.  The colspan value is filled in to *aColSpan.
45
     */
46
    Item* GetNext(int32_t *aColSpan);
47
private:
48
49
    enum State { ADDING, ENUMERATING_ARRAY, ENUMERATING_HASH, DONE };
50
    State mState;
51
52
    // store small colspans in an array for fast sorting and
53
    // enumeration, and large colspans in a hash table
54
55
    enum { ARRAY_BASE = 2 };
56
    enum { ARRAY_SIZE = 8 };
57
    Item *mArray[ARRAY_SIZE];
58
0
    int32_t SpanToIndex(int32_t aSpan) { return aSpan - ARRAY_BASE; }
59
0
    int32_t IndexToSpan(int32_t aIndex) { return aIndex + ARRAY_BASE; }
60
0
    bool UseArrayForSpan(int32_t aSpan) {
61
0
        NS_ASSERTION(SpanToIndex(aSpan) >= 0, "cell without colspan");
62
0
        return SpanToIndex(aSpan) < ARRAY_SIZE;
63
0
    }
64
65
    PLDHashTable mHashTable;
66
    struct HashTableEntry : public PLDHashEntryHdr {
67
        int32_t mColSpan;
68
        Item *mItems;
69
    };
70
71
    static const PLDHashTableOps HashTableOps;
72
73
    static PLDHashNumber HashTableHashKey(const void *key);
74
    static bool
75
        HashTableMatchEntry(const PLDHashEntryHdr *hdr, const void *key);
76
77
    static int SortArray(const void *a, const void *b, void *closure);
78
79
    /* state used only during enumeration */
80
    uint32_t mEnumerationIndex; // into mArray or mSortedHashTable
81
    HashTableEntry **mSortedHashTable;
82
83
    /*
84
     * operator new is forbidden since we use the pres shell's stack
85
     * memory, which much be pushed and popped at points matching a
86
     * push/pop on the C++ stack.
87
     */
88
0
    void* operator new(size_t sz) CPP_THROW_NEW { return nullptr; }
89
};
90
91
#endif