SpanningCellSorter.h (2890B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "StackArena.h" 16 #include "nsDebug.h" 17 #include "nsTArray.h" 18 19 /** 20 * The SpanningCellSorter is responsible for accumulating lists of cells 21 * with colspans so that those cells can later be enumerated, sorted 22 * from lowest number of columns spanned to highest. It does not use a 23 * stable sort (in fact, it currently reverses). 24 */ 25 class MOZ_STACK_CLASS SpanningCellSorter { 26 public: 27 SpanningCellSorter(); 28 ~SpanningCellSorter(); 29 30 struct Item { 31 int32_t row, col; 32 Item* next; 33 }; 34 35 /** 36 * Add a cell to the sorter. Returns false on out of memory. 37 * aColSpan is the number of columns spanned, and aRow/aCol are the 38 * position of the cell in the table (for GetCellInfoAt). 39 */ 40 bool AddCell(int32_t aColSpan, int32_t aRow, int32_t aCol); 41 42 /** 43 * Get the next *list* of cells. Each list contains all the cells 44 * for a colspan value, and the lists are given in order from lowest 45 * to highest colspan. The colspan value is filled in to *aColSpan. 46 */ 47 Item* GetNext(int32_t* aColSpan); 48 49 private: 50 enum State { ADDING, ENUMERATING_ARRAY, ENUMERATING_HASH, DONE }; 51 State mState; 52 53 // store small colspans in an array for fast sorting and 54 // enumeration, and large colspans in a hash table 55 56 enum { ARRAY_BASE = 2 }; 57 enum { ARRAY_SIZE = 8 }; 58 Item* mArray[ARRAY_SIZE]; 59 int32_t SpanToIndex(int32_t aSpan) { return aSpan - ARRAY_BASE; } 60 int32_t IndexToSpan(int32_t aIndex) { return aIndex + ARRAY_BASE; } 61 bool UseArrayForSpan(int32_t aSpan) { 62 NS_ASSERTION(SpanToIndex(aSpan) >= 0, "cell without colspan"); 63 return SpanToIndex(aSpan) < ARRAY_SIZE; 64 } 65 66 PLDHashTable mHashTable; 67 struct HashTableEntry : public PLDHashEntryHdr { 68 int32_t mColSpan; 69 Item* mItems; 70 }; 71 72 static const PLDHashTableOps HashTableOps; 73 74 static PLDHashNumber HashTableHashKey(const void* key); 75 static bool HashTableMatchEntry(const PLDHashEntryHdr* hdr, const void* key); 76 77 static int CompareHashTableEntry(HashTableEntry* a, HashTableEntry* b); 78 79 /* state used only during enumeration */ 80 uint32_t mEnumerationIndex; // into mArray or mSortedHashTable 81 nsTArray<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) noexcept(true) { return nullptr; } 89 }; 90 91 #endif