Line data Source code
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 : }
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 : void* operator new(size_t sz) CPP_THROW_NEW { return nullptr; }
89 : };
90 :
91 : #endif
|