LCOV - code coverage report
Current view: directory - layout/tables - SpanningCellSorter.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 86 0 0.0 %
Date: 2012-06-02 Functions: 8 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : // vim:cindent:ts=4:et:sw=4:
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla's table layout code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is the Mozilla Foundation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2006
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   L. David Baron <dbaron@dbaron.org> (original author)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : /*
      40                 :  * Code to sort cells by their colspan, used by BasicTableLayoutStrategy.
      41                 :  */
      42                 : 
      43                 : #include "SpanningCellSorter.h"
      44                 : #include "nsQuickSort.h"
      45                 : #include "nsIPresShell.h"
      46                 : 
      47                 : //#define DEBUG_SPANNING_CELL_SORTER
      48                 : 
      49               0 : SpanningCellSorter::SpanningCellSorter(nsIPresShell *aPresShell)
      50                 :   : mPresShell(aPresShell)
      51                 :   , mState(ADDING)
      52               0 :   , mSortedHashTable(nsnull)
      53                 : {
      54               0 :     memset(mArray, 0, sizeof(mArray));
      55               0 :     mHashTable.entryCount = 0;
      56               0 :     mPresShell->PushStackMemory();
      57               0 : }
      58                 : 
      59               0 : SpanningCellSorter::~SpanningCellSorter()
      60                 : {
      61               0 :     if (mHashTable.entryCount) {
      62               0 :         PL_DHashTableFinish(&mHashTable);
      63               0 :         mHashTable.entryCount = 0;
      64                 :     }
      65               0 :     delete [] mSortedHashTable;
      66               0 :     mPresShell->PopStackMemory();
      67               0 : }
      68                 : 
      69                 : /* static */ PLDHashTableOps
      70                 : SpanningCellSorter::HashTableOps = {
      71                 :     PL_DHashAllocTable,
      72                 :     PL_DHashFreeTable,
      73                 :     HashTableHashKey,
      74                 :     HashTableMatchEntry,
      75                 :     PL_DHashMoveEntryStub,
      76                 :     PL_DHashClearEntryStub,
      77                 :     PL_DHashFinalizeStub,
      78                 :     nsnull
      79                 : };
      80                 : 
      81                 : /* static */ PLDHashNumber
      82               0 : SpanningCellSorter::HashTableHashKey(PLDHashTable *table, const void *key)
      83                 : {
      84               0 :     return NS_PTR_TO_INT32(key);
      85                 : }
      86                 : 
      87                 : /* static */ bool
      88               0 : SpanningCellSorter::HashTableMatchEntry(PLDHashTable *table,
      89                 :                                         const PLDHashEntryHdr *hdr,
      90                 :                                         const void *key)
      91                 : {
      92               0 :     const HashTableEntry *entry = static_cast<const HashTableEntry*>(hdr);
      93               0 :     return NS_PTR_TO_INT32(key) == entry->mColSpan;
      94                 : }
      95                 : 
      96                 : bool
      97               0 : SpanningCellSorter::AddCell(PRInt32 aColSpan, PRInt32 aRow, PRInt32 aCol)
      98                 : {
      99               0 :     NS_ASSERTION(mState == ADDING, "cannot call AddCell after GetNext");
     100               0 :     NS_ASSERTION(aColSpan >= ARRAY_BASE, "cannot add cells with colspan<2");
     101                 : 
     102               0 :     Item *i = (Item*) mPresShell->AllocateStackMemory(sizeof(Item));
     103               0 :     NS_ENSURE_TRUE(i != nsnull, false);
     104                 : 
     105               0 :     i->row = aRow;
     106               0 :     i->col = aCol;
     107                 : 
     108               0 :     if (UseArrayForSpan(aColSpan)) {
     109               0 :         PRInt32 index = SpanToIndex(aColSpan);
     110               0 :         i->next = mArray[index];
     111               0 :         mArray[index] = i;
     112                 :     } else {
     113               0 :         if (!mHashTable.entryCount &&
     114                 :             !PL_DHashTableInit(&mHashTable, &HashTableOps, nsnull,
     115               0 :                                sizeof(HashTableEntry), PL_DHASH_MIN_SIZE)) {
     116               0 :             NS_NOTREACHED("table init failed");
     117               0 :             mHashTable.entryCount = 0;
     118               0 :             return false;
     119                 :         }
     120                 :         HashTableEntry *entry = static_cast<HashTableEntry*>
     121                 :                                            (PL_DHashTableOperate(&mHashTable, NS_INT32_TO_PTR(aColSpan),
     122               0 :                                  PL_DHASH_ADD));
     123               0 :         NS_ENSURE_TRUE(entry, false);
     124                 : 
     125               0 :         NS_ASSERTION(entry->mColSpan == 0 || entry->mColSpan == aColSpan,
     126                 :                      "wrong entry");
     127               0 :         NS_ASSERTION((entry->mColSpan == 0) == (entry->mItems == nsnull),
     128                 :                      "entry should be either new or properly initialized");
     129               0 :         entry->mColSpan = aColSpan;
     130                 : 
     131               0 :         i->next = entry->mItems;
     132               0 :         entry->mItems = i;
     133                 :     }
     134                 : 
     135               0 :     return true;
     136                 : }
     137                 : 
     138                 : /* static */ PLDHashOperator
     139               0 : SpanningCellSorter::FillSortedArray(PLDHashTable *table, PLDHashEntryHdr *hdr,
     140                 :                                     PRUint32 number, void *arg)
     141                 : {
     142               0 :     HashTableEntry *entry = static_cast<HashTableEntry*>(hdr);
     143               0 :     HashTableEntry **sh = static_cast<HashTableEntry**>(arg);
     144                 : 
     145               0 :     sh[number] = entry;
     146                 : 
     147               0 :     return PL_DHASH_NEXT;
     148                 : }
     149                 : 
     150                 : /* static */ int
     151               0 : SpanningCellSorter::SortArray(const void *a, const void *b, void *closure)
     152                 : {
     153               0 :     PRInt32 spanA = (*static_cast<HashTableEntry*const*>(a))->mColSpan;
     154               0 :     PRInt32 spanB = (*static_cast<HashTableEntry*const*>(b))->mColSpan;
     155                 : 
     156               0 :     if (spanA < spanB)
     157               0 :         return -1;
     158               0 :     if (spanA == spanB)
     159               0 :         return 0;
     160               0 :     return 1;
     161                 : }
     162                 : 
     163                 : SpanningCellSorter::Item*
     164               0 : SpanningCellSorter::GetNext(PRInt32 *aColSpan)
     165                 : {
     166               0 :     NS_ASSERTION(mState != DONE, "done enumerating, stop calling");
     167                 : 
     168               0 :     switch (mState) {
     169                 :         case ADDING:
     170                 :             /* prepare to enumerate the array */
     171               0 :             mState = ENUMERATING_ARRAY;
     172               0 :             mEnumerationIndex = 0;
     173                 :             /* fall through */
     174                 :         case ENUMERATING_ARRAY:
     175               0 :             while (mEnumerationIndex < ARRAY_SIZE && !mArray[mEnumerationIndex])
     176               0 :                 ++mEnumerationIndex;
     177               0 :             if (mEnumerationIndex < ARRAY_SIZE) {
     178               0 :                 Item *result = mArray[mEnumerationIndex];
     179               0 :                 *aColSpan = IndexToSpan(mEnumerationIndex);
     180               0 :                 NS_ASSERTION(result, "logic error");
     181                 : #ifdef DEBUG_SPANNING_CELL_SORTER
     182                 :                 printf("SpanningCellSorter[%p]:"
     183                 :                        " returning list for colspan=%d from array\n",
     184                 :                        static_cast<void*>(this), *aColSpan);
     185                 : #endif
     186               0 :                 ++mEnumerationIndex;
     187               0 :                 return result;
     188                 :             }
     189                 :             /* prepare to enumerate the hash */
     190               0 :             mState = ENUMERATING_HASH;
     191               0 :             mEnumerationIndex = 0;
     192               0 :             if (mHashTable.entryCount) {
     193                 :                 HashTableEntry **sh =
     194               0 :                     new HashTableEntry*[mHashTable.entryCount];
     195               0 :                 if (!sh) {
     196                 :                     // give up
     197               0 :                     mState = DONE;
     198               0 :                     return nsnull;
     199                 :                 }
     200               0 :                 PL_DHashTableEnumerate(&mHashTable, FillSortedArray, sh);
     201                 :                 NS_QuickSort(sh, mHashTable.entryCount, sizeof(sh[0]),
     202               0 :                              SortArray, nsnull);
     203               0 :                 mSortedHashTable = sh;
     204                 :             }
     205                 :             /* fall through */
     206                 :         case ENUMERATING_HASH:
     207               0 :             if (mEnumerationIndex < mHashTable.entryCount) {
     208               0 :                 Item *result = mSortedHashTable[mEnumerationIndex]->mItems;
     209               0 :                 *aColSpan = mSortedHashTable[mEnumerationIndex]->mColSpan;
     210               0 :                 NS_ASSERTION(result, "holes in hash table");
     211                 : #ifdef DEBUG_SPANNING_CELL_SORTER
     212                 :                 printf("SpanningCellSorter[%p]:"
     213                 :                        " returning list for colspan=%d from hash\n",
     214                 :                        static_cast<void*>(this), *aColSpan);
     215                 : #endif
     216               0 :                 ++mEnumerationIndex;
     217               0 :                 return result;
     218                 :             }
     219               0 :             mState = DONE;
     220                 :             /* fall through */
     221                 :         case DONE:
     222                 :             ;
     223                 :     }
     224               0 :     return nsnull;
     225                 : }

Generated by: LCOV version 1.7