Ejemplo n.º 1
0
/*	Create new or find old named anchor
**	-----------------------------------
**
**	Me one is for a reference which is found in a document, and might
**	not be already loaded.
**	Note: You are not guaranteed a new anchor -- you might get an old one,
**	like with fonts.
*/
PUBLIC HTAnchor * HTAnchor_findAddress (const char * address)
{
    char *tag = HTParse (address, "", PARSE_VIEW);	        /* Any tags? */
    
    /* If the address represents a sub-anchor, we recursively load its parent,
       then we create a child anchor within that document. */
    if (*tag) {
	char *addr = HTParse(address, "", PARSE_ACCESS | PARSE_HOST |
			     PARSE_PATH | PARSE_PUNCTUATION);
	HTParentAnchor * parent = (HTParentAnchor*) HTAnchor_findAddress(addr);
	HTChildAnchor * child = HTAnchor_findChild(parent, tag);
	HT_FREE(addr);
	HT_FREE(tag);
	return (HTAnchor *) child;
    } else {		       	     /* Else check whether we have this node */
	int hash;
	const char *p;
	HTList * adults;
	HTList *grownups;
	HTParentAnchor * foundAnchor;
	char *newaddr = NULL;
	StrAllocCopy(newaddr, address);		         /* Get our own copy */
	HT_FREE(tag);
	newaddr = HTSimplify(&newaddr);

	/* Select list from hash table */
	for(p=newaddr, hash=0; *p; p++)
	    hash = (int) ((hash * 3 + (*(unsigned char*)p)) % PARENT_HASH_SIZE);
	if (!adult_table) {
	    if ((adult_table = (HTList* *) HT_CALLOC(PARENT_HASH_SIZE, sizeof(HTList*))) == NULL)
	        HT_OUTOFMEM("HTAnchor_findAddress");
	}
	if (!adult_table[hash]) adult_table[hash] = HTList_new();
	adults = adult_table[hash];

	/* Search list for anchor */
	grownups = adults;
	while ((foundAnchor = (HTParentAnchor *) HTList_nextObject(grownups))){
	    if (!strcmp(foundAnchor->address, newaddr)) {
		HTTRACE(ANCH_TRACE, "Find Parent. %p with address `%s' already exists.\n" _ 
			    (void*) foundAnchor _ newaddr);
		HT_FREE(newaddr);		       /* We already have it */
		return (HTAnchor *) foundAnchor;
	    }
	}
	
	/* Node not found : create new anchor. */
	foundAnchor = HTParentAnchor_new();
	foundAnchor->address = newaddr;			/* Remember our copy */
	HTList_addObject (adults, foundAnchor);
	HTTRACE(ANCH_TRACE, "Find Parent. %p with hash %d and address `%s' created\n" _ (void*)foundAnchor _ hash _ newaddr);
	return (HTAnchor *) foundAnchor;
    }
}
Ejemplo n.º 2
0
HTAnchor * HTAnchor_findAddress
  ARGS1 (CONST char *,address)
{
  char *tag = HTParse (address, "", PARSE_ANCHOR);  /* Anchor tag specified ? */

  /* If the address represents a sub-anchor, we recursively load its parent,
     then we create a child anchor within that document. */
  if (tag && *tag) {
    char *docAddress = HTParse(address, "", PARSE_ACCESS | PARSE_HOST |
			                    PARSE_PATH | PARSE_PUNCTUATION);
    HTParentAnchor * foundParent =
      (HTParentAnchor *) HTAnchor_findAddress (docAddress);
    HTChildAnchor * foundAnchor = HTAnchor_findChild (foundParent, tag);
    free (docAddress);
    free (tag);
    return (HTAnchor *) foundAnchor;
  }
  
  else { /* If the address has no anchor tag, check whether we have this node */
    int hash;
    CONST char *p;
    HTList * adults;
    HTList *grownups;
    HTParentAnchor * foundAnchor;

    if (tag && *tag)
      free (tag);
    
    /* Select list from hash table */
    for(p=address, hash=0; *p; p++) hash = (hash * 3 + *p) % HASH_SIZE;
    if (!adult_table)
        adult_table = (HTList**) calloc(HASH_SIZE, sizeof(HTList*));
    if (!adult_table[hash]) adult_table[hash] = HTList_new();
    adults = adult_table[hash];

    /* Search list for anchor */
    grownups = adults;
    while (foundAnchor = HTList_nextObject (grownups)) {
      if (equivalent(foundAnchor->address, address)) {
	if (TRACE) fprintf(stderr, "Anchor %p with address `%s' already exists.\n",
			  foundAnchor, address);
	return (HTAnchor *) foundAnchor;
      }
    }
    
    /* Node not found : create new anchor */
    foundAnchor = HTParentAnchor_new ();
    if (TRACE) fprintf(stderr, "New anchor %p has hash %d and address `%s'\n",
    	foundAnchor, hash, address);
    StrAllocCopy(foundAnchor->address, address);
    HTList_addObject (adults, foundAnchor);
    return (HTAnchor *) foundAnchor;
  }
}
Ejemplo n.º 3
0
/*	Data access functions
**	---------------------
*/
PUBLIC HTParentAnchor * HTAnchor_parent ARGS1(
	HTAnchor *,	me)
{
    if (!me)
	return NULL;

    if (me->parent->info)
	return me->parent->info;

    /* else: create a new structure */
    return HTParentAnchor_new(me->parent);
}
Ejemplo n.º 4
0
/*  The address has no anchor tag, for sure.
 */
PRIVATE HTParentAnchor0 * HTAnchor_findAddress_in_adult_table ARGS1(
	CONST DocAddress *,	newdoc)
{
    /*
    **  Check whether we have this node.
    */
    int hash;
    HTList * adults;
    HTList *grownups;
    HTParentAnchor0 * foundAnchor;
    BOOL need_extra_info = (newdoc->post_data || newdoc->post_content_type ||
		newdoc->bookmark || newdoc->isHEAD || newdoc->safe);

    /*
     *  We need not free adult_table[] atexit -
     *  it should be perfectly empty after free'ing all HText's.
     *  (There is an error if it is not empty at exit). -LP
     */

    /*
    **  Select list from hash table,
    */
    hash = HASH_FUNCTION(newdoc->address);
    adults = &(adult_table[hash]);

    /*
    **  Search list for anchor.
    */
    grownups = adults;
    while (NULL != (foundAnchor =
		    (HTParentAnchor0 *)HTList_nextObject(grownups))) {
	if (HTSEquivalent(foundAnchor->address, newdoc->address) &&

	    ((!foundAnchor->info && !need_extra_info) ||
	     (foundAnchor->info &&
	      HTBEquivalent(foundAnchor->info->post_data, newdoc->post_data) &&
	      foundAnchor->info->isHEAD == newdoc->isHEAD)))
	{
	    CTRACE((tfp, "Anchor %p with address `%s' already exists.\n",
			(void *)foundAnchor, newdoc->address));
	    return foundAnchor;
	}
    }

    /*
    **  Node not found: create new anchor.
    */
    foundAnchor = HTParentAnchor0_new(newdoc->address, hash);
    CTRACE((tfp, "New anchor %p has hash %d and address `%s'\n",
		(void *)foundAnchor, hash, newdoc->address));

    if (need_extra_info) {
	/* rare case, create a big structure */
	HTParentAnchor *p = HTParentAnchor_new(foundAnchor);

	if (newdoc->post_data)
	    BStrCopy(p->post_data, newdoc->post_data);
	if (newdoc->post_content_type)
	    StrAllocCopy(p->post_content_type,
		     newdoc->post_content_type);
	if (newdoc->bookmark)
	    StrAllocCopy(p->bookmark, newdoc->bookmark);
	p->isHEAD = newdoc->isHEAD;
	p->safe = newdoc->safe;
    }
    HTList_linkObject(adults, foundAnchor, &foundAnchor->_add_adult);

    return foundAnchor;
}