예제 #1
0
/*
 * Returns the hash entry at position pos
 *         Null is pos is invalid or there is no entry at this position
 */
hash_entry Moca_EntryAtPos(hash_map map, unsigned int pos)
{
    if(!map || pos >= map->tableSize ||
            tableElt(map,pos)->next==MOCA_HASHMAP_UNUSED)
        return NULL;
    return tableElt(map,pos);
}
예제 #2
0
/*
 * Returns -1 if key is not in map
 *         the position of key in the map if it is present
 */
int Moca_PosInMap(hash_map map,hash_entry e)
{
    unsigned long h;
    int ind=0;
    if(!map)
        return -1;
    h=hash_ptr(e->key, map->hash_bits);
    ind=map->hashs[h];
    while(ind>=0 && map->comp(tableElt(map,ind),e)!=0 )
        ind=tableElt(map,ind)->next;
    return ind;
}
예제 #3
0
// Clear map, after this call, map is still usable
void Moca_ClearMap(hash_map map)
{
    unsigned int i;
    unsigned long h;
    if(!map)
        return;
    for(i=0;i<map->nbentry;++i)
    {
        h=hash_ptr(tableElt(map,i)->key, map->hash_bits);
        map->hashs[h]=MOCA_HASHMAP_END;
        tableElt(map,i)->next=MOCA_HASHMAP_UNUSED;
    }
}
예제 #4
0
/*
 * Find the first available entry from pos
 * Returns the entry on success
 *         NULL if there is no more entry
 * After the call to Memmap_NextEntryPos, pos is the position of the returned
 * entry +1
 * This function can be used as an iterator
 */
hash_entry Moca_NextEntryPos(hash_map map, unsigned int *pos)
{
    unsigned int i=*pos;
    MOCA_DEBUG_PRINT("Moca Searching element in map %p after %d /%d\n",
            map, i, Moca_NbElementInMap(map));
    while(i< map->tableSize && tableElt(map,i)->next==MOCA_HASHMAP_UNUSED)
        ++i;
    *pos=i+1;
    MOCA_DEBUG_PRINT("Moca found  %p at %d\n",
            i>=map->tableSize?NULL:tableElt(map,i),i);
    if(i >=map->tableSize)
        return NULL;
    return tableElt(map,i);
}
예제 #5
0
/*
 * Return the hash entry corresponding to key,
 *        NULL if key is not in the map
 */
hash_entry Moca_EntryFromKey(hash_map map, hash_entry e)
{
    unsigned long h;
    int ind=0;
    if(!map || !e)
        return NULL;
    h=hash_ptr(e->key, map->hash_bits);
    ind=map->hashs[h];
    while(ind>=0 && map->comp(tableElt(map,ind),e)!=0 )
        ind=tableElt(map,ind)->next;
    if(ind >=0)
        return tableElt(map,ind);
    return NULL;
}
예제 #6
0
hash_map Moca_InitHashMap(unsigned long hash_bits, int nb_elt,
        size_t elt_size, comp_fct_t comp)
{
    unsigned int i;
    hash_map map=kmalloc(sizeof(struct _hash_map), GFP_ATOMIC);
    if(!map)
        return NULL;
    map->hash_bits=hash_bits;
    map->size=1<<hash_bits;
    map->tableSize=nb_elt;
    map->nbentry=0;
    map->elt_size=elt_size;
    if(comp)
        map->comp=comp;
    else
        map->comp=&Moca_DefaultHashMapComp;

    MOCA_DEBUG_PRINT("Moca allocationg hash size %lu\n", map->size);
    if(!(map->hashs=kmalloc(sizeof(int)*map->size,GFP_ATOMIC)))
    {
        kfree(map);
        return NULL;
    }
    for(i=0;i<map->size;++i)
        map->hashs[i]=MOCA_HASHMAP_END;
    if(!(map->table=kcalloc(map->tableSize,elt_size,GFP_ATOMIC)))
    {
        kfree(map->hashs);
        kfree(map);
        return NULL;
    }
    for(i=0;i<map->tableSize;++i)
        tableElt(map,i)->next=MOCA_HASHMAP_UNUSED;
    return map;
}
예제 #7
0
unsigned int Moca_FindNextAvailPosMap(hash_map map)
{
    unsigned int i=0;
    while(i< map->tableSize && tableElt(map,i)->next!=MOCA_HASHMAP_UNUSED)
        ++i;
    return i;
}
예제 #8
0
hash_entry Moca_RemoveFromMap(hash_map map,hash_entry e)
{
    unsigned long h;
    int ind, ind_prev=MOCA_HASHMAP_END;
    if(!map)
        return NULL;
    MOCA_DEBUG_PRINT("Moca removing %p from %p\n", e->key, map);
    h=hash_ptr(e->key, map->hash_bits);
    ind=map->hashs[h];
    while(ind>=0 && map->comp(tableElt(map,ind),e)!=0 )
    {
        ind_prev=ind;
        ind=tableElt(map,ind)->next;
    }
    MOCA_DEBUG_PRINT("Moca removing %p from %p ind %d prev %d\n", e->key, map,
            ind, ind_prev);
    //key wasn't in map
    if(ind<0 )
        return NULL;
    //Remove from list
    if(ind_prev>=0)
    {
        tableElt(map,ind_prev)->next=tableElt(map,ind)->next;
    }
    else
    {
        map->hashs[h]=tableElt(map,ind)->next;
    }
    tableElt(map,ind)->next=MOCA_HASHMAP_UNUSED;
    --map->nbentry;
    MOCA_DEBUG_PRINT("Moca removing %p from %p ind %d ok\n", e->key, map, ind);
    return tableElt(map,ind);
}
예제 #9
0
PRBool
nsHTMLTableAccessible::HasDescendant(const nsAString& aTagName,
                                     PRBool aAllowEmpty)
{
  nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));
  NS_ENSURE_TRUE(tableElt, PR_FALSE);

  nsCOMPtr<nsIDOMNodeList> nodeList;
  tableElt->GetElementsByTagName(aTagName, getter_AddRefs(nodeList));
  NS_ENSURE_TRUE(nodeList, PR_FALSE);

  nsCOMPtr<nsIDOMNode> foundItem;
  nodeList->Item(0, getter_AddRefs(foundItem));
  if (!foundItem)
    return PR_FALSE;

  if (aAllowEmpty)
    return PR_TRUE;

  // Make sure that the item we found has contents and either has multiple
  // children or the found item is not a whitespace-only text node.
  nsCOMPtr<nsIContent> foundItemContent = do_QueryInterface(foundItem);
  if (foundItemContent->GetChildCount() > 1)
    return PR_TRUE; // Treat multiple child nodes as non-empty

  nsIContent *innerItemContent = foundItemContent->GetChildAt(0);
  if (innerItemContent && !innerItemContent->TextIsOnlyWhitespace())
    return PR_TRUE;

  // If we found more than one node then return true not depending on
  // aAllowEmpty flag.
  // XXX it might be dummy but bug 501375 where we changed this addresses
  // performance problems only. Note, currently 'aAllowEmpty' flag is used for
  // caption element only. On another hand we create accessible object for
  // the first entry of caption element (see
  // nsHTMLTableAccessible::CacheChildren).
  nodeList->Item(1, getter_AddRefs(foundItem));
  return !!foundItem;
}
예제 #10
0
/*
 * Insert key in map
 * Returns A pointer to the hash_entry corresponding to key
 *         Null in case of error
 * status is set to:
 *         The position of hash_entry in case of success
 *         One of the following in case of errors:
 *          MOCA_HASHMAP_ALREADY_IN_MAP
 *          MOCA_HASHMAP_FULL
 *          MOCA_HASHMAP_ERROR
 */
hash_entry Moca_AddToMap(hash_map map, hash_entry e, int *status)
{
    unsigned long h;
    int ind=0;
    unsigned int nextPos;
    if(!map)
    {
        *status=MOCA_HASHMAP_ERROR;
        return NULL;
    }
    if(map->nbentry==map->tableSize)
    {
        *status=MOCA_HASHMAP_FULL;
        return NULL;
    }
    //Do the insertion
    nextPos=Moca_FindNextAvailPosMap(map);
    MOCA_DEBUG_PRINT("Moca inserting %p ind %d/%lu total %d\n",
            e->key,nextPos,map->tableSize, map->nbentry);
    if(nextPos >= map->tableSize)
    {
        *status=MOCA_HASHMAP_ERROR;
        Moca_Panic("Moca hashmap BUG in AddToMap");
        return NULL;
    }
    //Update the link
    h=hash_ptr(e->key, map->hash_bits);
    ind=map->hashs[h];
    //TODO refactor here
    if(ind<0)
    {
        memcpy(tableElt(map,nextPos),e,map->elt_size);
        tableElt(map,nextPos)->next=MOCA_HASHMAP_END;
        map->hashs[h]=nextPos;
    }
    else
    {
        while(map->comp(tableElt(map,ind),e)!=0 &&
                tableElt(map,ind)->next>=0)
            ind=tableElt(map,ind)->next;
        if(map->comp(tableElt(map,ind),e)==0)
        {
            MOCA_DEBUG_PRINT("Moca %p already in map %p\n", e->key, map);
            *status=MOCA_HASHMAP_ALREADY_IN_MAP;
            //This seems useless
            tableElt(map,nextPos)->key=NULL;
            return tableElt(map,ind);
        }
        MOCA_DEBUG_PRINT("Moca collision in map %p key %p\n", map, e->key);
        //TODO: Use Memcpy
        memcpy(tableElt(map,nextPos),e,map->elt_size);
        tableElt(map,nextPos)->next=MOCA_HASHMAP_END;
        tableElt(map,ind)->next=nextPos;
    }
    ++map->nbentry;
    MOCA_DEBUG_PRINT("Moca Inserted %p in map %p\n", e->key, map);
    *status=nextPos;
    return tableElt(map,nextPos);
}
예제 #11
0
NS_IMETHODIMP
nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
{
  // Implement a heuristic to determine if table is most likely used for layout
  // XXX do we want to look for rowspan or colspan, especialy that span all but a couple cells
  // at the beginning or end of a row/col, and especially when they occur at the edge of a table?
  // XXX expose this info via object attributes to AT-SPI

  // XXX For now debugging descriptions are always on via SHOW_LAYOUT_HEURISTIC
  // This will allow release trunk builds to be used by testers to refine the algorithm
  // Change to |#define SHOW_LAYOUT_HEURISTIC DEBUG| before final release
#ifdef SHOW_LAYOUT_HEURISTIC
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) \
  { *aIsProbablyForLayout = isLayout; \
    mLayoutHeuristic = isLayout ? NS_LITERAL_STRING("layout table: ") : NS_LITERAL_STRING("data table: "); \
    mLayoutHeuristic += NS_LITERAL_STRING(heuristic); return NS_OK; }
#else
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) { *aIsProbablyForLayout = isLayout; return NS_OK; }
#endif

  *aIsProbablyForLayout = PR_FALSE;

  if (IsDefunct())
    return NS_ERROR_FAILURE;

  nsDocAccessible *docAccessible = GetDocAccessible();
  if (docAccessible) {
    PRUint32 state, extState;
    docAccessible->GetState(&state, &extState);
    if (extState & nsIAccessibleStates::EXT_STATE_EDITABLE) {  // Need to see all elements while document is being edited
      RETURN_LAYOUT_ANSWER(PR_FALSE, "In editable document");
    }
  }

  // Check to see if an ARIA role overrides the role from native markup,
  // but for which we still expose table semantics (treegrid, for example).
  PRBool hasNonTableRole =
    (nsAccUtils::Role(this) != nsIAccessibleRole::ROLE_TABLE);
  if (hasNonTableRole) {
    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has role attribute");
  }

  if (mContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
    // Role attribute is present, but overridden roles have already been dealt with.
    // Only landmarks and other roles that don't override the role from native
    // markup are left to deal with here.
    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has role attribute, weak role, and role is table");
  }
  
  // Check for legitimate data table elements or attributes
  nsAutoString summary;
  if ((mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::summary, summary) &&
       !summary.IsEmpty()) || 
      HasDescendant(NS_LITERAL_STRING("caption"), PR_FALSE) ||
      HasDescendant(NS_LITERAL_STRING("th")) ||
      HasDescendant(NS_LITERAL_STRING("thead")) ||
      HasDescendant(NS_LITERAL_STRING("tfoot")) ||
      HasDescendant(NS_LITERAL_STRING("colgroup"))) {
    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has caption, summary, th, thead, tfoot or colgroup -- legitimate table structures");
  }
  if (HasDescendant(NS_LITERAL_STRING("table"))) {
    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has a nested table within it");
  }
  
  // If only 1 column or only 1 row, it's for layout
  PRInt32 columns, rows;
  GetColumnCount(&columns);
  if (columns <=1) {
    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has only 1 column");
  }
  GetRowCount(&rows);
  if (rows <=1) {
    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has only 1 row");
  }

  // Check for many columns
  if (columns >= 5) {
    RETURN_LAYOUT_ANSWER(PR_FALSE, ">=5 columns");
  }
  
  // Now we know there are 2-4 columns and 2 or more rows
  // Check to see if there are visible borders on the cells
  // XXX currently, we just check the first cell -- do we really need to do more?
  nsCOMPtr<nsIDOMElement> cellElement;
  nsresult rv = GetCellAt(0, 0, *getter_AddRefs(cellElement));
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
  NS_ENSURE_TRUE(cellContent, NS_ERROR_FAILURE);
  nsIFrame *cellFrame = cellContent->GetPrimaryFrame();
  if (!cellFrame) {
    return NS_OK;
  }
  nsMargin border;
  cellFrame->GetBorder(border);
  if (border.top && border.bottom && border.left && border.right) {
    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has nonzero border-width on table cell");
  }

  /**
   * Rules for non-bordered tables with 2-4 columns and 2+ rows from here on forward
   */

  // Check for styled background color across the row
  // Alternating background color is a common way 
  nsCOMPtr<nsIDOMNodeList> nodeList;
  nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));    
  tableElt->GetElementsByTagName(NS_LITERAL_STRING("tr"), getter_AddRefs(nodeList));
  NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
  PRUint32 length;
  nodeList->GetLength(&length);
  nsAutoString color, lastRowColor;
  for (PRUint32 rowCount = 0; rowCount < length; rowCount ++) {
    nsCOMPtr<nsIDOMNode> rowNode;
    nodeList->Item(rowCount, getter_AddRefs(rowNode));
    nsCOMPtr<nsIContent> rowContent(do_QueryInterface(rowNode));

    nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
      nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), rowContent);
    NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);

    lastRowColor = color;
    styleDecl->GetPropertyValue(NS_LITERAL_STRING("background-color"), color);
    if (rowCount > 0 && PR_FALSE == lastRowColor.Equals(color)) {
      RETURN_LAYOUT_ANSWER(PR_FALSE, "2 styles of row background color, non-bordered");
    }
  }

  // Check for many rows
  const PRInt32 kMaxLayoutRows = 20;
  if (rows > kMaxLayoutRows) { // A ton of rows, this is probably for data
    RETURN_LAYOUT_ANSWER(PR_FALSE, ">= kMaxLayoutRows (20) and non-bordered");
  }

  // Check for very wide table
  nsAutoString styledWidth;
  GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("width"), styledWidth);
  if (styledWidth.EqualsLiteral("100%")) {
    RETURN_LAYOUT_ANSWER(PR_TRUE, "<=4 columns and 100% width");
  }
  if (styledWidth.Find(NS_LITERAL_STRING("px"))) { // Hardcoded in pixels
    nsIFrame *tableFrame = GetFrame();
    NS_ENSURE_TRUE(tableFrame , NS_ERROR_FAILURE);
    nsSize tableSize  = tableFrame->GetSize();

    nsDocAccessible *docAccessible = GetDocAccessible();
    NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE);
    nsIFrame *docFrame = docAccessible->GetFrame();
    NS_ENSURE_TRUE(docFrame , NS_ERROR_FAILURE);

    nsSize docSize = docFrame->GetSize();
    if (docSize.width > 0) {
      PRInt32 percentageOfDocWidth = (100 * tableSize.width) / docSize.width;
      if (percentageOfDocWidth > 95) {
        // 3-4 columns, no borders, not a lot of rows, and 95% of the doc's width
        // Probably for layout
        RETURN_LAYOUT_ANSWER(PR_TRUE, "<=4 columns, width hardcoded in pixels and 95% of document width");
      }
    }
  }

  // Two column rules
  if (rows * columns <= 10) {
    RETURN_LAYOUT_ANSWER(PR_TRUE, "2-4 columns, 10 cells or less, non-bordered");
  }

  if (HasDescendant(NS_LITERAL_STRING("embed")) ||
      HasDescendant(NS_LITERAL_STRING("object")) ||
      HasDescendant(NS_LITERAL_STRING("applet")) ||
      HasDescendant(NS_LITERAL_STRING("iframe"))) {
    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has no borders, and has iframe, object, applet or iframe, typical of advertisements");
  }

  RETURN_LAYOUT_ANSWER(PR_FALSE, "no layout factor strong enough, so will guess data");
}