File:  [Public] / libwww / Library / src / HTAnchor.html
Revision 2.34: download - view: text, annotated - select for diffs
Mon Nov 27 03:04:40 1995 UTC (28 years, 6 months ago) by frystyk
Branches: MAIN
CVS tags: v4/0, HEAD
alpha 7

<HTML>
<HEAD>
<TITLE>Anchor object Manager</TITLE>
<!-- Changed by: Henrik Frystyk Nielsen, 26-Nov-1995 -->
</HEAD>
<BODY>

<H1>Hypertext "Anchor" Object</H1>

<PRE>
/*
**	(c) COPYRIGHT MIT 1995.
**	Please first read the full copyright statement in the file COPYRIGH.
*/
</PRE>

An anchor represents a region of a hypertext document which is linked
to another anchor in the same or a different document. As always we
must emulate the fancy features of C++ by hand :-(. In this module you
find:

<UL>
<LI><A HREF="#Generic">Definition of generic anchor class</A>
<LI><A HREF="#parent">Definition of parent anchor class</A>
<LI><A HREF="#child">Definition of child anchor class</A>
<LI><A HREF="#creation">Creation and deletion methods</A>
<LI><A HREF="#links">Manipulation of Links</A>
<LI><A HREF="#access">Access Methods for information</A>
</UL>

This module is implemented by <A HREF="HTAnchor.c">HTAnchor.c</A>, and
it is a part of the <A HREF="http://www.w3.org/pub/WWW/Library/"> W3C
Reference Library</A>.

<H2>History</H2>

<UL>
<LI>Version 0 (TBL) written in Objective-C for the NeXT browser
<LI>Version 1 of 24-Oct-1991 (JFG), written in C, browser-independant
<LI>Version 2 written by Henrik Frystyk
</UL>

<PRE>
#ifndef HTANCHOR_H
#define HTANCHOR_H

#include "HTList.h"
#include "HTAtom.h"
#include "HTMethod.h"
</PRE>

<A NAME="td"><H2>Types for Atoms</H2></A>

This is a set of videly used type definitions used through out the
Library:

<PRE>
typedef HTAtom * HTFormat;
typedef HTAtom * HTLevel;		       /* Used to specify HTML level */
typedef HTAtom * HTEncoding;				 /* Content Encoding */
typedef HTAtom * HTCte;				/* Content transfer encoding */
typedef HTAtom * HTCharset;
typedef HTAtom * HTLanguage;
</PRE>

<A NAME="anchor"><H2>Anchor data structures</H2></A>

We have to do this in order to make forward references.

<PRE>
typedef struct _HyperDoc HyperDoc;  /* Ready for forward references */
typedef struct _HTAnchor HTAnchor;
typedef struct _HTParentAnchor HTParentAnchor;
typedef struct _HTChildAnchor HTChildAnchor;
</PRE>

Must be AFTER definition of HTAnchor:

<PRE>
typedef HTAtom HTLinkType;

typedef enum _HTLinkResult
{
    HT_LINK_INVALID = -1,
    HT_LINK_NONE = 0,
    HT_LINK_ERROR,
    HT_LINK_OK
} HTLinkResult;

typedef struct {
    HTAnchor *		dest;		   /* The anchor to which this leads */
    HTLinkType *	type;		           /* Semantics of this link */
    HTMethod		method;		   /* Method for this link, e.g. PUT */
    HTLinkResult	result;    /* Result of any attempt to get this link */
} HTLink;
</PRE>

<A NAME="Generic"><H3>Generic Anchor type</H3></A>

This is the super class of anchors. We often use this as an argument
to the functions that both accept parent anchors and child anchors. We
separate the first link from the others to avoid too many small
mallocs involved by a list creation. Most anchors only point to one
place.

<PRE>
struct _HTAnchor {
  HTLink	mainLink;	/* Main (or default) destination of this */
  HTList *	links;  	/* List of extra links from this, if any */
  HTParentAnchor * parent;	/* Parent of this anchor (self for adults) */
};
</PRE>

<A NAME="parent"><H3>Anchor for a Parent Object</H3></A>

These anchors points to the whole contents of a graphic object
(document). The parent anchor of a parent anchor is itself. The parent
anchor now contains all meta information about the object. This is
largely the entity headers in the HTTP specification.

<PRE>
struct _HTParentAnchor {
  /* Common part from the generic anchor structure */
  HTLink	mainLink;	/* Main (or default) destination of this */
  HTList *	links;  	/* List of extra links from this, if any */
  HTParentAnchor * parent;	/* Parent of this anchor (self) */

  /* ParentAnchor-specific information */
  HTList *	children;	/* Subanchors of this, if any */
  HTList *	sources;	/* List of anchors pointing to this, if any */
  HyperDoc *	document;	/* The document within this is an anchor */
  char *	physical;	/* Physical address */
  BOOL		cacheHit;	/* Yes, if cached object found */
  char * 	address;	/* Absolute address of this node */
  BOOL		isIndex;	/* Acceptance of a keyword search */

  /* Entity header fields */
  BOOL		header_parsed;	/* Are we done parsing? */

  char *	title;
  int		methods;	/* Allowed methods (bit-flag) */

  HTEncoding	content_encoding;
  HTLanguage	content_language;	/* @@@ SHOULD BE LIST @@@ */
  long int	content_length;
  HTCte		cte;		/* Content-Transfer-Encoding */
  HTFormat	content_type;
  HTCharset	charset;	/* Parameter to content-type */
  HTLevel	level;		/* Parameter to content-type `text/html' */

  time_t	date;		/* When was the request issued */  
  time_t	expires;	/* When does the copy expire */
  time_t	last_modified;

  char *	derived_from;	/* Opaque string */
  char *	version;	/* Opaque string */

  /* List of unknown headers coming in from the network. Use the field in the
     request structure for sending test headers. */
  HTList *	extra_headers;
};
</PRE>

<A NAME="child"><H3>Anchor for a Child Object</H3></A>

A child anchor is a anchor object that points to a subpart of a
graphic object (document)

<PRE>
struct _HTChildAnchor {
  /* Common part from the generic anchor structure */
  HTLink	mainLink;	/* Main (or default) destination of this */
  HTList *	links;  	/* List of extra links from this, if any */
  HTParentAnchor * parent;	/* Parent of this anchor */

  /* ChildAnchor-specific information */
  char * 	tag;		/* Address of this anchor relative to parent */
};
</PRE>

<A NAME="creation"><H2>Creation and Deletion Methods</H2></A>

After we have defined the data structures we must define the methods
that can be used on them. All anchors are kept in an internal hash
table so that they are easier to find again.

<H3>Find/Create a Parent Anchor</H3>

This one is for a reference (link) which is found in a document, and
might not be already loaded. The parent anchor returned can either be
created on the spot or is already in the hash table.

<PRE>
extern HTAnchor * HTAnchor_findAddress		(CONST char * address);
</PRE>

<H3>Find/Create a Child Anchor</H3>

This one is for a new child anchor being edited into an existing
document. The parent anchor must already exist but the child returned
can either be created on the spot or is already in the hash table. The
<EM>tag</EM> is the part that's after the '#' sign in a URI.

<PRE>
extern HTChildAnchor * HTAnchor_findChild	(HTParentAnchor *parent,
						 CONST char *	tag);
</PRE>

<H3>Find/Create a Child Anchor and Link to Another Parent</H3>

Find a child anchor anchor with a given parent and possibly a
<EM>tag</EM>, and (if passed) link this child to the URI given in the
<EM>href</EM>. As we really want typed links to the caller should also
indicate what the type of the link is (see HTTP spec for more
information). The link is <EM>relative</EM> to the address of the
parent anchor.

<PRE>
extern HTChildAnchor * HTAnchor_findChildAndLink
		(HTParentAnchor * parent,		/* May not be 0 */
		CONST char * tag,			/* May be "" or 0 */
		CONST char * href,			/* May be "" or 0 */
		HTLinkType * ltype);			/* May be 0 */
</PRE>

<H3>Delete an Anchor</H3>

All outgoing links from parent and children are deleted, and this
anchor is removed from the sources list of all its targets. We also
delete the targets. If this anchor's source list is empty, we delete
it and its children.

<PRE>
extern BOOL HTAnchor_delete	(HTParentAnchor *me);
</PRE>

<H3>Delete all Anchors</H3>

Deletes <EM>all</EM> anchors and return a list of all the
<CODE>HyperDoc</CODE>s found while doing it. The application may keep
its own list of <CODE>HyperDoc</CODE>s, but this function returns it
anyway.  It is <EM>always</EM> for the application to delete any
<CODE>HyperDoc</CODE>s. If NULL then no hyperdocs are returned. Return
YES if OK, else NO. <P>

<B>Note:</B> This function is different from cleaning up the history
list!

<PRE>
extern BOOL HTAnchor_deleteAll	(HTList * objects);
</PRE>


<A NAME="links"><H2>The Link Object</H2></A>

Anchors are bound together using link objects. Each anchor can be the
source or destination of zero, one, or more links from and to other
anchors.

<H3>Link this Anchor to another given one</H3>

A single anchor may have many outgoing links of which the default is
the <EM>main link</EM>. If one already exists then this new link is
simply added to the list.

<PRE>
extern BOOL HTAnchor_link	(HTAnchor *	source,
				 HTAnchor *	destination,
				 HTLinkType *	type,
				 HTMethod	method);
</PRE>

<H3>Find the Link Object that Binds two Anchors</H3>

If the destination anchor is a target of a link from the source anchor
then return the link object, else NULL.

<PRE>
extern HTLink *HTAnchor_findLink (HTAnchor *src, HTAnchor *dest);
#define HTAnchor_findMainLink(me) ((me) ? &amp;((me)-&gt;mainLink) : NULL)
</PRE>

<H3>Find The Method of a Link</H3>

The method used in a link can be PUT, or POST, for example

<PRE>
#define HTAnchor_linkMethod(me)	((me) ? (me)-&gt;method : METHOD_INVALID)
</PRE>

<H3>Find destination of a Link</H3>

Find the anchor which is the main target of this anchor.

<PRE>
extern HTAnchor * HTAnchor_followMainLink (HTAnchor *me);
#define HTAnchor_linkDest(me) ((me) ? (me)-&gt;dest : NULL)
</PRE>

<H3>Find destination with given relationship</H3>

Return the anchor with a given typed link.

<PRE>
extern HTAnchor * HTAnchor_followTypedLink (HTAnchor *me, HTLinkType *type);
</PRE>

<H3>Result of a Link</H3>

When a link has been used for posting an object from a source to a
destination link, the result of the operation is stored as part of the
link information.

<PRE>
#define HTAnchor_linkResult(me)	((me) ? me-&gt;result : HT_LINK_INVALID)
extern BOOL HTAnchor_setLinkResult	(HTLink * link, HTLinkResult result);
</PRE>

<H3>Make a particular link the main link</H3>

Any outgoing link can at any time be the main destination.

<PRE>
extern BOOL HTAnchor_makeMainLink	(HTAnchor *me, HTLink *movingLink);
</PRE>

<H3>Move Link Information</H3>

Move all link information form one anchor to another. This is useful
when we get a redirection on a request and want to inherit the link
information to the new anchor and change the link information in the
old one to "redirect".

<PRE>
extern BOOL HTAnchor_moveAllLinks	(HTAnchor *src, HTAnchor *dest);
</PRE>

<H3>Remove Link Information</H3>

Delete link information between two or more anchors

<PRE>
extern BOOL HTAnchor_removeLink		(HTAnchor *src, HTAnchor *dest);
extern BOOL HTAnchor_removeAllLinks	(HTAnchor * me);
</PRE>

<H3>Move a child anchor to the head of the list of its siblings</H3>

This is to ensure that an anchor which might have already existed is
put in the correct order as we load the document.

<PRE>
extern void HTAnchor_makeLastChild	(HTChildAnchor *me);
</PRE>

<A NAME="access"><H2>Access Methods of an Anchor</H2></A>

These functions should be used to access information within the anchor
structures.

<H3>Relations to Other Anchors</H3>

<H4>Who is Parent?</H4>

For parent anchors this returns the anchor itself

<PRE>
extern HTParentAnchor * HTAnchor_parent	(HTAnchor *me);
</PRE>

<H4>Does it have any Anchors within it?</H4>

<PRE>
extern BOOL HTAnchor_hasChildren	(HTParentAnchor *me);
</PRE>

<H3>Graphic Object (HyperDoc)</H3>

HyperDoc is the application defined data structure that contains a
graphic object in memory.

<H4>Assign a HyperDoc to an Anchor</H4>

<PRE>
extern void HTAnchor_setDocument	(HTParentAnchor *me, HyperDoc *	doc);
</PRE>

<H4>Return the <EM>HyperDoc</EM> of an anchor (if any)</H4>

<PRE>
extern HyperDoc * HTAnchor_document	(HTParentAnchor *me);
</PRE>

<H3>URI Information of Anchors</H3>

There are two addresses of an anchor. The URI that was passed when the
anchor was crated and the physical address that's used when the URI is
going to be requested. The two addresses may be different if the
request is going through a proxy or a gateway.

<H4>Get URI Address</H4>

Returns the full URI of the anchor, child or parent as a malloc'd
string to be freed by the caller as when th eanchor was created.

<PRE>
extern char * HTAnchor_address		(HTAnchor *me);
</PRE>

<H3>Cache Information</H3>

If the cache manager finds a cached obejct, it is registered in the
anchor object. This way the <A HREF="HTFile.html">file loader</A>
knows that it is a MIME data object. The cache manager does not know
whether the data object is out of date (for example if a
<EM>Expires:</EM> header is in the MIME header. This is for the <A
HREF="HTMIME.html">MIME parser</A> to find out.

<PRE>
extern BOOL HTAnchor_cacheHit		(HTParentAnchor	*me);
extern void HTAnchor_setCacheHit	(HTParentAnchor	*me, BOOL cacheHit);
</PRE>

<H3>Physical address</H3>

Contains the physical address after we haved looked for proxies etc.

<PRE>
extern char * HTAnchor_physical		(HTParentAnchor * me);

extern void HTAnchor_setPhysical	(HTParentAnchor * me, char * protocol);
</PRE>

<H3>Is the Anchor searchable?</H3>

<PRE>
extern void HTAnchor_clearIndex		(HTParentAnchor *me);
extern void HTAnchor_setIndex		(HTParentAnchor *me);
extern BOOL HTAnchor_isIndex		(HTParentAnchor *me);
</PRE>

<H3>What Protocol should be Used</H3>

<PRE>
extern void * HTAnchor_protocol		(HTParentAnchor * me);
extern void HTAnchor_setProtocol	(HTParentAnchor * me, void* protocol);
</PRE>

<H3>Title handling</H3>

We keep the title in the anchor as we then can refer to it later in
the history list etc. We can also obtain the title element if it is
passed as a HTTP header in the response. Any title element found in an
HTML document will overwrite a title given in a HTTP header.

<PRE>
extern CONST char * HTAnchor_title	(HTParentAnchor *me);

extern void HTAnchor_setTitle		(HTParentAnchor *me,
					 CONST char *	title);

extern void HTAnchor_appendTitle	(HTParentAnchor *me,
					 CONST char *	title);
</PRE>

<H3>Media Types (Content-Type)</H3>

<PRE>
extern HTFormat HTAnchor_format		(HTParentAnchor *me);
extern void HTAnchor_setFormat		(HTParentAnchor *me,
					 HTFormat	form);
</PRE>

<H3>Charset parameter to Content-Type</H3>

<PRE>
extern HTCharset HTAnchor_charset	(HTParentAnchor *me);
extern void HTAnchor_setCharset		(HTParentAnchor *me,
					 HTCharset	charset);
</PRE>

<H3>Level parameter to Content-Type</H3>

<PRE>
extern HTLevel HTAnchor_level		(HTParentAnchor * me);
extern void HTAnchor_setLevel		(HTParentAnchor * me,
					 HTLevel	level);
</PRE>

<H3>Content Language</H3>

<PRE>
extern HTLanguage HTAnchor_language	(HTParentAnchor *me);
extern void HTAnchor_setLanguage	(HTParentAnchor *me,
					 HTLanguage	language);
</PRE>

<H3>Content Encoding</H3>

<PRE>
extern HTEncoding HTAnchor_encoding	(HTParentAnchor *me);
extern void HTAnchor_setEncoding	(HTParentAnchor *me,
					 HTEncoding	encoding);
</PRE>

<H3>Content Transfer Encoding</H3>

<PRE>
extern HTCte HTAnchor_cte		(HTParentAnchor *me);
extern void HTAnchor_setCte		(HTParentAnchor *me,
					 HTCte		cte);
</PRE>

<H3>Content Length</H3>

<PRE>
extern long int HTAnchor_length		(HTParentAnchor *me);
extern void HTAnchor_setLength		(HTParentAnchor *me,
					 long int	length);
</PRE>

<H3>Allowed methods (Allow)</H3>

<PRE>
extern int HTAnchor_methods		(HTParentAnchor *me);
extern void HTAnchor_setMethods		(HTParentAnchor *me,
					 int		methodset);
extern void HTAnchor_appendMethods	(HTParentAnchor *me,
					 int		methodset);
</PRE>

<H3>Version</H3>

<PRE>
extern CONST char * HTAnchor_version	(HTParentAnchor *me);
extern void HTAnchor_setVersion		(HTParentAnchor *me,
					 CONST char *	version);
</PRE>

<H3>Date</H3>

Returns the date that was registered in the RFC822 header "Date"

<PRE>
#define HTAnchor_date(me)		((me) ? (me)-&gt;date : -1)
extern void HTAnchor_setDate		(HTParentAnchor	*me,
					 CONST time_t	*date);
</PRE>

<H3>Last Modified Date</H3>

Returns the date that was registered in the RFC822 header "Last-Modified"

<PRE>
#define HTAnchor_lastModified(me)	((me) ? (me)-&gt;last_modified : -1)
extern void HTAnchor_setLastModified	(HTParentAnchor	*me,
					 CONST time_t	*lm);
</PRE>

<H3>Expires Date</H3>

<PRE>
#define HTAnchor_expires(me)		((me) ? (me)-&gt;expires : -1)
extern void HTAnchor_setExpires		(HTParentAnchor	*me,
					 CONST time_t	*expires);
</PRE>

<H3>Derived from</H3>

<PRE>
extern CONST char * HTAnchor_derived	(HTParentAnchor *me);
extern void HTAnchor_setDerived		(HTParentAnchor *me,
					 CONST char *	derived_from);
</PRE>

<H3>Extra Headers</H3>

List of unknown headers coming in from the network. Do not use the
<CODE>HTAnchor_addExtra()</CODE> function to extra headers here, but
use the field in the <A HREF="HTReq.html#z1">request structure</A>
for sending test headers.

<PRE>
extern HTList * HTAnchor_Extra		(HTParentAnchor *me);
extern void HTAnchor_addExtra		(HTParentAnchor *me,
					 CONST char *	header);
</PRE>

<H3>Status of Header Parsing</H3>

These are primarily for internal use

<PRE>
extern BOOL HTAnchor_headerParsed	(HTParentAnchor *me);
extern void HTAnchor_setHeaderParsed	(HTParentAnchor *me);
</PRE>

<H3>We want to clear the header information...</H3>

<PRE>
extern void HTAnchor_clearHeader	(HTParentAnchor *me);

#endif /* HTANCHOR_H */
</PRE>
</BODY>
</HTML>

Webmaster