Annotation of libwww/Library/src/HTAnchor.c, revision 1.16.2.1
1.14 frystyk 1: /* HTAnchor.c
2: ** HYPERTEXT "ANCHOR" OBJECT
1.1 timbl 3: **
1.14 frystyk 4: ** (c) COPYRIGHT CERN 1994.
5: ** Please first read the full copyright statement in the file COPYRIGH.
6: **
7: ** An anchor represents a region of a hypertext document which is
8: ** linked to another anchor in the same or a different document.
1.1 timbl 9: **
10: ** History
11: ** Nov 1990 Written in Objective-C for the NeXT browser (TBL)
12: ** 24-Oct-1991 (JFG), written in C, browser-independant
13: ** 21-Nov-1991 (JFG), first complete version
1.16.2.1! frystyk 14: ** 3-May-1995 (HF), Added a lot of methods and other stuff
1.1 timbl 15: */
16:
1.16 frystyk 17: /* Library include files */
18: #include "tcp.h"
19: #include "HTUtils.h"
20: #include "HTString.h"
1.7 luotonen 21: #include "HTFormat.h"
1.1 timbl 22: #include "HTParse.h"
1.16 frystyk 23: #include "HTFWrite.h" /* for cache stuff */
1.11 frystyk 24: #include "HTAnchor.h" /* Implemented here */
25:
26: #define HASH_SIZE 101 /* Arbitrary prime. Memory/speed tradeoff */
1.1 timbl 27:
28: typedef struct _HyperDoc Hyperdoc;
1.16 frystyk 29: #ifdef VMS
1.1 timbl 30: struct _HyperDoc {
1.16 frystyk 31: int junk; /* VMS cannot handle pointers to undefined structs */
1.1 timbl 32: };
33: #endif
34:
35: PRIVATE HTList **adult_table=0; /* Point to table of lists of all parents */
36:
1.16.2.1! frystyk 37: /* ------------------------------------------------------------------------- */
! 38: /* Creation Methods */
! 39: /* ------------------------------------------------------------------------- */
! 40:
! 41: /*
1.1 timbl 42: ** Do not use "new" by itself outside this module. In order to enforce
43: ** consistency, we insist that you furnish more information about the
44: ** anchor you are creating : use newWithParent or newWithAddress.
45: */
1.16 frystyk 46: PRIVATE HTParentAnchor * HTParentAnchor_new NOARGS
1.1 timbl 47: {
1.16 frystyk 48: HTParentAnchor *newAnchor =
49: (HTParentAnchor *) calloc(1, sizeof (HTParentAnchor));
50: newAnchor->parent = newAnchor;
1.16.2.1! frystyk 51: newAnchor->content_type = WWW_UNKNOWN;
1.16 frystyk 52: return newAnchor;
1.1 timbl 53: }
54:
1.16 frystyk 55:
56: PRIVATE HTChildAnchor * HTChildAnchor_new NOARGS
1.1 timbl 57: {
1.16 frystyk 58: return (HTChildAnchor *) calloc (1, sizeof (HTChildAnchor));
1.1 timbl 59: }
60:
61:
1.16.2.1! frystyk 62: /* Create new or find old child anchor
! 63: ** -----------------------------------
1.1 timbl 64: **
1.3 timbl 65: ** Me one is for a new anchor being edited into an existing
1.16.2.1! frystyk 66: ** document. The parent anchor must already exist. All
! 67: ** children without tags (no NAME attribut) points to the same NULL
! 68: ** child.
1.1 timbl 69: */
1.16.2.1! frystyk 70: PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2 (HTParentAnchor *, parent,
! 71: CONST char *,tag)
1.1 timbl 72: {
1.16.2.1! frystyk 73: HTChildAnchor *child;
! 74: HTList *kids;
! 75:
! 76: if (!parent) {
! 77: if (ANCH_TRACE)
! 78: fprintf(TDEST, "Find Child.. called with NULL parent.\n");
! 79: return NULL;
! 80: }
1.1 timbl 81:
1.16.2.1! frystyk 82: /* First search list of children to see if tag is already there */
! 83: if ((kids = parent->children)) {
! 84: if (tag && *tag) { /* TBL */
! 85: while ((child = (HTChildAnchor *) HTList_nextObject(kids))) {
! 86: if (child->tag && !strcasecomp(child->tag, tag)) {
! 87: if (ANCH_TRACE)
! 88: fprintf (TDEST,
! 89: "Find Child.. %p of parent %p with name `%s' already exists.\n",
! 90: (void *) child, (void *) parent, tag);
! 91: return child;
! 92: }
1.1 timbl 93: }
94: }
1.16.2.1! frystyk 95: } else /* Create new list of children */
! 96: parent->children = HTList_new ();
! 97:
! 98: /* Did't find it so we need to create a new one */
! 99: child = HTChildAnchor_new();
! 100: HTList_addObject(parent->children, child);
! 101: child->parent = parent;
! 102: StrAllocCopy(child->tag, tag);
! 103: if (ANCH_TRACE)
! 104: fprintf(TDEST,"Find Child.. New Anchor %p named `%s' is child of %p\n",
! 105: (void *) child, tag ? tag : (CONST char *) "", (void *)parent);
! 106: return child;
1.1 timbl 107: }
108:
109:
110: /* Create new or find old named anchor
111: ** -----------------------------------
112: **
1.3 timbl 113: ** Me one is for a reference which is found in a document, and might
1.1 timbl 114: ** not be already loaded.
115: ** Note: You are not guaranteed a new anchor -- you might get an old one,
116: ** like with fonts.
117: */
1.16 frystyk 118: PUBLIC HTAnchor * HTAnchor_findAddress ARGS1 (CONST char *, address)
1.1 timbl 119: {
1.16 frystyk 120: char *tag = HTParse (address, "", PARSE_ANCHOR); /* Any tags? */
121: char *newaddr=NULL;
1.1 timbl 122:
1.16.2.1! frystyk 123: StrAllocCopy(newaddr, address); /* Get our own copy */
1.16 frystyk 124: if (!HTImProxy)
1.16.2.1! frystyk 125: newaddr = HTSimplify(&newaddr); /* Proxy has already simplified */
1.16 frystyk 126:
127: /* If the address represents a sub-anchor, we recursively load its parent,
128: then we create a child anchor within that document. */
129: if (*tag) {
130: char *docAddress = HTParse(newaddr, "", PARSE_ACCESS | PARSE_HOST |
131: PARSE_PATH | PARSE_PUNCTUATION);
132: HTParentAnchor * foundParent =
133: (HTParentAnchor *) HTAnchor_findAddress (docAddress);
134: HTChildAnchor * foundAnchor = HTAnchor_findChild (foundParent, tag);
135: free (docAddress);
136: free (tag);
1.16.2.1! frystyk 137: free (newaddr);
1.16 frystyk 138: return (HTAnchor *) foundAnchor;
139: } else { /* Else check whether we have this node */
140: int hash;
141: CONST char *p;
142: HTList * adults;
143: HTList *grownups;
144: HTParentAnchor * foundAnchor;
145: free (tag);
146:
147: /* Select list from hash table */
148: for(p=newaddr, hash=0; *p; p++)
149: hash = (int) ((hash * 3 + (*(unsigned char*)p)) % HASH_SIZE);
150: if (!adult_table)
151: adult_table = (HTList**) calloc(HASH_SIZE, sizeof(HTList*));
152: if (!adult_table[hash]) adult_table[hash] = HTList_new();
153: adults = adult_table[hash];
154:
155: /* Search list for anchor */
156: grownups = adults;
157: while ((foundAnchor = (HTParentAnchor *) HTList_nextObject(grownups))){
1.16.2.1! frystyk 158: if (!strcasecomp(foundAnchor->address, newaddr)) {
1.16 frystyk 159: if (ANCH_TRACE)
1.16.2.1! frystyk 160: fprintf(TDEST, "Find Parent. %p with address `%s' already exists.\n",
1.16 frystyk 161: (void*) foundAnchor, newaddr);
1.16.2.1! frystyk 162: free(newaddr); /* We already have it */
1.16 frystyk 163: return (HTAnchor *) foundAnchor;
164: }
165: }
166:
167: /* Node not found : create new anchor. */
168: foundAnchor = HTParentAnchor_new();
169: foundAnchor->address = newaddr; /* Remember our copy */
170: HTList_addObject (adults, foundAnchor);
1.16.2.1! frystyk 171: if (ANCH_TRACE) fprintf(TDEST, "Find Parent. %p with hash %d and address `%s' created\n", (void*)foundAnchor, hash, newaddr);
1.1 timbl 172: return (HTAnchor *) foundAnchor;
173: }
174: }
175:
1.16.2.1! frystyk 176: /* ------------------------------------------------------------------------- */
! 177: /* Link Methods */
! 178: /* ------------------------------------------------------------------------- */
! 179:
! 180: /* Create or find a child anchor with a possible link
! 181: ** --------------------------------------------------
! 182: **
! 183: ** Create new anchor with a given parent and possibly
! 184: ** a name, and possibly a link to a _relatively_ named anchor.
! 185: ** (Code originally in ParseHTML.h)
! 186: */
! 187: PUBLIC HTChildAnchor * HTAnchor_findChildAndLink
! 188: ARGS4(
! 189: HTParentAnchor *,parent, /* May not be 0 */
! 190: CONST char *,tag, /* May be "" or 0 */
! 191: CONST char *,href, /* May be "" or 0 */
! 192: HTLinkType *,ltype /* May be 0 */
! 193: )
! 194: {
! 195: HTChildAnchor * child = HTAnchor_findChild(parent, tag);
! 196: if (href && *href) {
! 197: char * relative_to = HTAnchor_address((HTAnchor *) parent);
! 198: char * parsed_address = HTParse(href, relative_to, PARSE_ALL);
! 199: HTAnchor * dest = HTAnchor_findAddress(parsed_address);
! 200: HTAnchor_link((HTAnchor *) child, dest, ltype);
! 201: free(parsed_address);
! 202: free(relative_to);
! 203: }
! 204: return child;
! 205: }
! 206:
! 207: /* Link me Anchor to another given one
! 208: ** -------------------------------------
! 209: */
! 210: PUBLIC BOOL HTAnchor_link ARGS3(HTAnchor *, source,
! 211: HTAnchor *, destination,
! 212: HTLinkType *, type)
! 213: {
! 214: if (!(source && destination))
! 215: return NO; /* Can't link to/from non-existing anchor */
! 216: if (ANCH_TRACE)
! 217: fprintf(TDEST, "Link Anchors anchor %p to anchor %p\n",
! 218: (void *) source, (void *) destination);
! 219: if (!source->mainLink.dest) {
! 220: source->mainLink.dest = destination;
! 221: source->mainLink.type = type;
! 222: } else {
! 223: HTLink * newLink = (HTLink *) calloc(1, sizeof (HTLink));
! 224: if (newLink == NULL) outofmem(__FILE__, "HTAnchor_link");
! 225: newLink->dest = destination;
! 226: newLink->type = type;
! 227: if (! source->links)
! 228: source->links = HTList_new ();
! 229: HTList_addObject (source->links, newLink);
! 230: }
! 231: if (!destination->parent->sources)
! 232: destination->parent->sources = HTList_new ();
! 233: HTList_addObject (destination->parent->sources, source);
! 234: return YES;
! 235: }
! 236:
! 237:
! 238: /* Manipulation of links
! 239: ** ---------------------
! 240: */
! 241:
! 242: PUBLIC HTAnchor * HTAnchor_followMainLink
! 243: ARGS1 (HTAnchor *,me)
! 244: {
! 245: return me->mainLink.dest;
! 246: }
! 247:
! 248: PUBLIC HTAnchor * HTAnchor_followTypedLink
! 249: ARGS2 (HTAnchor *,me, HTLinkType *,type)
! 250: {
! 251: if (me->mainLink.type == type)
! 252: return me->mainLink.dest;
! 253: if (me->links) {
! 254: HTList *links = me->links;
! 255: HTLink *link;
! 256: while ((link = (HTLink *) HTList_nextObject (links)))
! 257: if (link->type == type)
! 258: return link->dest;
! 259: }
! 260: return NULL; /* No link of me type */
! 261: }
! 262:
! 263:
! 264: /* Make main link
! 265: */
! 266: PUBLIC BOOL HTAnchor_makeMainLink
! 267: ARGS2 (HTAnchor *,me, HTLink *,movingLink)
! 268: {
! 269: /* Check that everything's OK */
! 270: if (! (me && HTList_removeObject (me->links, movingLink)))
! 271: return NO; /* link not found or NULL anchor */
! 272: else {
! 273: /* First push current main link onto top of links list */
! 274: HTLink *newLink = (HTLink*) malloc (sizeof (HTLink));
! 275: if (newLink == NULL) outofmem(__FILE__, "HTAnchor_makeMainLink");
! 276: memcpy (newLink, & me->mainLink, sizeof (HTLink));
! 277: HTList_addObject (me->links, newLink);
! 278:
! 279: /* Now make movingLink the new main link, and free it */
! 280: memcpy (& me->mainLink, movingLink, sizeof (HTLink));
! 281: free (movingLink);
! 282: return YES;
! 283: }
! 284: }
! 285:
! 286: /* Move an anchor to the head of the list of its siblings
! 287: ** ------------------------------------------------------
! 288: **
! 289: ** This is to ensure that an anchor which might have already existed
! 290: ** is put in the correct order as we load the document.
! 291: */
! 292:
! 293: PUBLIC void HTAnchor_makeLastChild
! 294: ARGS1(HTChildAnchor *,me)
! 295: {
! 296: if (me->parent != (HTParentAnchor *) me) { /* Make sure it's a child */
! 297: HTList * siblings = me->parent->children;
! 298: HTList_removeObject (siblings, me);
! 299: HTList_addObject (siblings, me);
! 300: }
! 301: }
! 302:
! 303: /* ------------------------------------------------------------------------- */
! 304: /* Deletion Methods */
! 305: /* ------------------------------------------------------------------------- */
1.1 timbl 306:
307: /* Delete an anchor and possibly related things (auto garbage collection)
308: ** --------------------------------------------
309: **
310: ** The anchor is only deleted if the corresponding document is not loaded.
1.10 frystyk 311: ** All outgoing links from parent and children are deleted, and this
312: ** anchor is removed from the sources list of all its targets.
1.1 timbl 313: ** We also try to delete the targets whose documents are not loaded.
314: ** If this anchor's source list is empty, we delete it and its children.
315: */
316:
1.16.2.1! frystyk 317: /* Deletes all the memory allocated in a parent anchor and returns the
! 318: ** hyperdoc
! 319: */
! 320: PRIVATE HyperDoc * delete_parent ARGS1(HTParentAnchor *, me)
! 321: {
! 322: HyperDoc *doc = me->document;
! 323:
! 324: /* Remove link and address information */
! 325: HTList_delete (me->links);
! 326: HTList_delete (me->children);
! 327: HTList_delete (me->sources);
! 328: FREE(me->physical);
! 329: FREE(me->address);
! 330:
! 331: /* Then remove entity header information (metainformation) */
! 332: FREE(me->title);
! 333: FREE(me->derived_from);
! 334: FREE(me->version);
! 335: if (me->extra_headers) {
! 336: HTList *cur = me->extra_headers;
! 337: char *pres;
! 338: while ((pres = (char *) HTList_nextObject(cur)))
! 339: free(pres);
! 340: HTList_delete(me->extra_headers);
! 341: }
! 342:
! 343: /* @@@ TEMPORARY SOLUTION FOR CACHE - SHOULD BE PERSISTENT */
! 344: if (me->cacheItems) {
! 345: HTCacheClear(me->cacheItems);
! 346: }
! 347: free(me);
! 348: return doc;
! 349: }
! 350:
! 351:
! 352: /* Delete a parent anchor and all its children. If a HyperDoc is found
! 353: ** then it's returned
! 354: */
! 355: PRIVATE HyperDoc *delete_family ARGS1(HTAnchor *, me)
! 356: {
! 357: HTParentAnchor *parent = me->parent;
! 358: if (ANCH_TRACE)
! 359: fprintf(TDEST, "AnchorDelete Remove parent %p and children\n", parent);
! 360: if (!me) {
! 361: if (ANCH_TRACE)
! 362: fprintf(TDEST, "AnchorDelete No anchor found\n");
! 363: return NULL;
! 364: }
! 365:
! 366: /* Delete children */
! 367: if (parent->children) {
! 368: HTChildAnchor *child;
! 369: while ((child = (HTChildAnchor *)
! 370: HTList_removeLastObject(parent->children))) {
! 371: FREE(child->tag);
! 372: free(child);
! 373: }
! 374: }
! 375: return delete_parent(parent);
! 376: }
! 377:
! 378:
! 379: /* DELETE ALL ANCHORS
! 380: ** ------------------
! 381: ** Deletes all anchors and return a list of all the HyperDocs found.
! 382: ** It is for the application to delete any HyperDocs.
! 383: ** Return YES if OK, else NO
! 384: */
! 385: PUBLIC BOOL HTAnchor_deleteAll ARGS1(HTList *, documents)
! 386: {
! 387: int cnt;
! 388: HTList *cur;
! 389: if (!documents)
! 390: return NO;
! 391: for (cnt=0; cnt<HASH_SIZE; cnt++) {
! 392: if ((cur = adult_table[cnt])) {
! 393: HTParentAnchor *pres;
! 394: while ((pres = (HTParentAnchor *) HTList_nextObject(cur)) != NULL){
! 395: HyperDoc *doc = delete_family((HTAnchor *) pres);
! 396: if (doc) HTList_addObject(documents, (void *) doc);
! 397: }
! 398: }
! 399: HTList_delete(adult_table[cnt]);
! 400: adult_table[cnt] = NULL;
! 401: }
! 402: return YES;
! 403: }
! 404:
! 405:
1.1 timbl 406: PRIVATE void deleteLinks
1.3 timbl 407: ARGS1 (HTAnchor *,me)
1.1 timbl 408: {
1.3 timbl 409: if (! me)
1.1 timbl 410: return;
411:
412: /* Recursively try to delete target anchors */
1.3 timbl 413: if (me->mainLink.dest) {
414: HTParentAnchor *parent = me->mainLink.dest->parent;
415: HTList_removeObject (parent->sources, me);
1.1 timbl 416: if (! parent->document) /* Test here to avoid calling overhead */
417: HTAnchor_delete (parent);
418: }
1.3 timbl 419: if (me->links) { /* Extra destinations */
1.1 timbl 420: HTLink *target;
1.12 frystyk 421: while ((target = (HTLink *) HTList_removeLastObject (me->links))) {
1.1 timbl 422: HTParentAnchor *parent = target->dest->parent;
1.3 timbl 423: HTList_removeObject (parent->sources, me);
1.1 timbl 424: if (! parent->document) /* Test here to avoid calling overhead */
425: HTAnchor_delete (parent);
426: }
427: }
428: }
429:
430: PUBLIC BOOL HTAnchor_delete
1.3 timbl 431: ARGS1 (HTParentAnchor *,me)
1.1 timbl 432: {
433: HTChildAnchor *child;
434:
435: /* Don't delete if document is loaded */
1.3 timbl 436: if (me->document)
1.1 timbl 437: return NO;
438:
439: /* Recursively try to delete target anchors */
1.3 timbl 440: deleteLinks ((HTAnchor *) me);
1.1 timbl 441:
1.3 timbl 442: if (! HTList_isEmpty (me->sources)) { /* There are still incoming links */
1.1 timbl 443: /* Delete all outgoing links from children, if any */
1.3 timbl 444: HTList *kids = me->children;
1.12 frystyk 445: while ((child = (HTChildAnchor *) HTList_nextObject (kids)))
1.1 timbl 446: deleteLinks ((HTAnchor *) child);
447: return NO; /* Parent not deleted */
448: }
449:
450: /* No more incoming links : kill everything */
451: /* First, recursively delete children */
1.12 frystyk 452: while ((child = (HTChildAnchor *) HTList_removeLastObject (me->children))) {
1.1 timbl 453: deleteLinks ((HTAnchor *) child);
454: free (child->tag);
455: free (child);
456: }
457:
458: /* Now kill myself */
1.16.2.1! frystyk 459: delete_parent(me);
1.1 timbl 460: return YES; /* Parent deleted */
461: }
462:
1.16.2.1! frystyk 463: /* ------------------------------------------------------------------------- */
! 464: /* Data Access Methods */
! 465: /* ------------------------------------------------------------------------- */
1.1 timbl 466:
1.16.2.1! frystyk 467: PUBLIC HTParentAnchor * HTAnchor_parent ARGS1 (HTAnchor *,me)
1.1 timbl 468: {
1.16.2.1! frystyk 469: return me ? me->parent : NULL;
1.1 timbl 470: }
471:
1.16.2.1! frystyk 472: PUBLIC void HTAnchor_setDocument ARGS2 (HTParentAnchor *, me, HyperDoc *,doc)
1.1 timbl 473: {
1.16.2.1! frystyk 474: if (me)
! 475: me->document = doc;
1.1 timbl 476: }
477:
1.16.2.1! frystyk 478: PUBLIC HyperDoc * HTAnchor_document ARGS1 (HTParentAnchor *,me)
1.1 timbl 479: {
1.16.2.1! frystyk 480: return me ? me->document : NULL;
1.1 timbl 481: }
482:
483:
1.10 frystyk 484: #if 0
1.16.2.1! frystyk 485: /* We might want to use this when we have a link editing application */
1.10 frystyk 486: PUBLIC void HTAnchor_setAddress
1.3 timbl 487: ARGS2 (HTAnchor *,me, char *,addr)
1.1 timbl 488: {
1.3 timbl 489: if (me)
490: StrAllocCopy (me->parent->address, addr);
1.1 timbl 491: }
1.10 frystyk 492: #endif
493:
1.16.2.1! frystyk 494: PUBLIC char * HTAnchor_address ARGS1 (HTAnchor *, me)
1.1 timbl 495: {
1.16.2.1! frystyk 496: char *addr = NULL;
! 497: if (me) {
! 498: if (((HTParentAnchor *) me == me->parent) ||
! 499: !((HTChildAnchor *) me)->tag) { /* it's an adult or no tag */
! 500: StrAllocCopy (addr, me->parent->address);
! 501: }
! 502: else { /* it's a named child */
! 503: addr = (char *) malloc (2 + strlen (me->parent->address)
! 504: + strlen (((HTChildAnchor *) me)->tag));
! 505: if (addr == NULL) outofmem(__FILE__, "HTAnchor_address");
! 506: sprintf (addr, "%s#%s", me->parent->address,
! 507: ((HTChildAnchor *) me)->tag);
! 508: }
1.1 timbl 509: }
1.16.2.1! frystyk 510: return addr;
1.1 timbl 511: }
512:
1.16.2.1! frystyk 513: PUBLIC BOOL HTAnchor_hasChildren ARGS1 (HTParentAnchor *,me)
! 514: {
! 515: return me ? ! HTList_isEmpty(me->children) : NO;
! 516: }
1.1 timbl 517:
1.16.2.1! frystyk 518: PUBLIC void HTAnchor_clearIndex ARGS1 (HTParentAnchor *,me)
! 519: {
! 520: if (me)
! 521: me->isIndex = NO;
! 522: }
1.1 timbl 523:
1.16.2.1! frystyk 524: PUBLIC void HTAnchor_setIndex ARGS1 (HTParentAnchor *,me)
1.1 timbl 525: {
1.3 timbl 526: if (me)
1.16.2.1! frystyk 527: me->isIndex = YES;
1.1 timbl 528: }
529:
1.16.2.1! frystyk 530: PUBLIC BOOL HTAnchor_isIndex ARGS1 (HTParentAnchor *,me)
1.1 timbl 531: {
1.16.2.1! frystyk 532: return me ? me->isIndex : NO;
1.1 timbl 533: }
534:
1.16.2.1! frystyk 535: /* Protocol
! 536: ** --------
! 537: */
! 538:
! 539: PUBLIC void * HTAnchor_protocol ARGS1(HTParentAnchor *, me)
1.9 frystyk 540: {
1.16.2.1! frystyk 541: return me->protocol;
1.9 frystyk 542: }
1.1 timbl 543:
1.16.2.1! frystyk 544: PUBLIC void HTAnchor_setProtocol ARGS2(HTParentAnchor *, me,
! 545: void*, protocol)
1.1 timbl 546: {
1.16.2.1! frystyk 547: me->protocol = protocol;
1.1 timbl 548: }
549:
1.16.2.1! frystyk 550: /* Physical Address
! 551: ** ----------------
! 552: */
! 553:
! 554: PUBLIC char * HTAnchor_physical ARGS1(HTParentAnchor *, me)
1.1 timbl 555: {
1.16.2.1! frystyk 556: return me->physical;
1.1 timbl 557: }
558:
1.16.2.1! frystyk 559: PUBLIC void HTAnchor_setPhysical ARGS2(HTParentAnchor *, me,
! 560: char *, physical)
1.1 timbl 561: {
1.16.2.1! frystyk 562: if (!me || !physical) {
! 563: if (ANCH_TRACE)
! 564: fprintf(TDEST, "HTAnchor.... setPhysical, called with null argument\n");
! 565: return;
! 566: }
! 567: StrAllocCopy(me->physical, physical);
1.1 timbl 568: }
569:
1.16.2.1! frystyk 570: /* ------------------------------------------------------------------------- */
! 571: /* Entity Header Information */
! 572: /* ------------------------------------------------------------------------- */
! 573:
! 574: /*
! 575: ** Media Types (Content-Type)
1.1 timbl 576: */
1.16.2.1! frystyk 577: PUBLIC HTFormat HTAnchor_format ARGS1(HTParentAnchor *,me)
1.1 timbl 578: {
1.16.2.1! frystyk 579: return me ? me->content_type : NULL;
1.1 timbl 580: }
581:
1.16.2.1! frystyk 582: PUBLIC void HTAnchor_setFormat ARGS2(HTParentAnchor *,me, HTFormat, form)
1.1 timbl 583: {
1.16.2.1! frystyk 584: if (me) me->content_type = form;
1.1 timbl 585: }
586:
1.16.2.1! frystyk 587: /*
! 588: ** Charset parameter to Content-Type
! 589: */
! 590: PUBLIC HTCharset HTAnchor_charset ARGS1(HTParentAnchor *, me)
1.1 timbl 591: {
1.16.2.1! frystyk 592: return me ? me->charset : NULL;
1.1 timbl 593: }
594:
1.16.2.1! frystyk 595: PUBLIC void HTAnchor_setCharset ARGS2(HTParentAnchor *,me, HTCharset, charset)
! 596: {
! 597: if (me) me->charset = charset;
! 598: }
! 599:
! 600: /*
! 601: ** Level parameter to Content-Type
1.1 timbl 602: */
1.16.2.1! frystyk 603: PUBLIC HTLevel HTAnchor_level ARGS1(HTParentAnchor *, me)
! 604: {
! 605: return me ? me->level : NULL;
! 606: }
1.1 timbl 607:
1.16.2.1! frystyk 608: PUBLIC void HTAnchor_setLevel ARGS2(HTParentAnchor *,me, HTLevel, level)
1.1 timbl 609: {
1.16.2.1! frystyk 610: if (me) me->level = level;
1.1 timbl 611: }
612:
1.16.2.1! frystyk 613: /*
! 614: ** Content Encoding
! 615: */
! 616: PUBLIC HTEncoding HTAnchor_encoding ARGS1(HTParentAnchor *,me)
! 617: {
! 618: return me ? me->content_encoding : NULL;
! 619: }
1.1 timbl 620:
1.16.2.1! frystyk 621: PUBLIC void HTAnchor_setEncoding ARGS2(HTParentAnchor *,me,
! 622: HTEncoding, encoding)
! 623: {
! 624: if (me) me->content_encoding = encoding;
! 625: }
! 626:
! 627: /*
! 628: ** Content Transfer Encoding
1.1 timbl 629: */
1.16.2.1! frystyk 630: PUBLIC HTCte HTAnchor_cte ARGS1(HTParentAnchor *,me)
! 631: {
! 632: return me ? me->cte : NULL;
! 633: }
1.1 timbl 634:
1.16.2.1! frystyk 635: PUBLIC void HTAnchor_setCte ARGS2(HTParentAnchor *,me, HTCte, cte)
1.1 timbl 636: {
1.16.2.1! frystyk 637: if (me) me->cte = cte;
1.1 timbl 638: }
639:
1.16.2.1! frystyk 640: /*
! 641: ** Content Length
! 642: */
! 643: PUBLIC long int HTAnchor_length ARGS1(HTParentAnchor *,me)
1.1 timbl 644: {
1.16.2.1! frystyk 645: return me ? me->content_length : -1;
1.1 timbl 646: }
647:
1.16.2.1! frystyk 648: PUBLIC void HTAnchor_setLength ARGS2(HTParentAnchor *,me, long int, length)
! 649: {
! 650: if (me) me->content_length = length;
! 651: }
1.2 timbl 652:
1.16.2.1! frystyk 653: /*
! 654: ** Allowed methods (Allow)
1.2 timbl 655: */
1.16.2.1! frystyk 656: PUBLIC int HTAnchor_methods ARGS1(HTParentAnchor *, me)
1.1 timbl 657: {
1.16.2.1! frystyk 658: return me ? me->methods : 0;
! 659: }
1.1 timbl 660:
1.16.2.1! frystyk 661: PUBLIC void HTAnchor_setMethods ARGS2(HTParentAnchor *,me, int, methodset)
! 662: {
! 663: if (me) me->methods = methodset;
1.2 timbl 664: }
665:
1.16.2.1! frystyk 666: PUBLIC void HTAnchor_appendMethods ARGS2(HTParentAnchor *,me, int, methodset)
! 667: {
! 668: if (me) me->methods += methodset;
! 669: }
1.2 timbl 670:
1.16.2.1! frystyk 671: /*
! 672: ** Title
1.2 timbl 673: */
1.16.2.1! frystyk 674: PUBLIC CONST char * HTAnchor_title ARGS1 (HTParentAnchor *,me)
! 675: {
! 676: return me ? me->title : NULL;
! 677: }
1.2 timbl 678:
1.16.2.1! frystyk 679: PUBLIC void HTAnchor_setTitle ARGS2(HTParentAnchor *,me, CONST char *, title)
1.2 timbl 680: {
1.16.2.1! frystyk 681: if (me && title) StrAllocCopy(me->title, title);
1.2 timbl 682: }
683:
1.16.2.1! frystyk 684: PUBLIC void HTAnchor_appendTitle ARGS2(HTParentAnchor *,me, CONST char *,title)
! 685: {
! 686: if (me && title) StrAllocCat(me->title, title);
! 687: }
1.2 timbl 688:
1.16.2.1! frystyk 689: /*
! 690: ** Version
! 691: */
! 692: PUBLIC CONST char * HTAnchor_version ARGS1 (HTParentAnchor *,me)
1.2 timbl 693: {
1.16.2.1! frystyk 694: return me ? me->version : NULL;
1.2 timbl 695: }
696:
1.16.2.1! frystyk 697: PUBLIC void HTAnchor_setVersion ARGS2(HTParentAnchor *, me,
! 698: CONST char *, version)
1.2 timbl 699: {
1.16.2.1! frystyk 700: if (me && version) StrAllocCopy(me->version, version);
1.2 timbl 701: }
702:
1.16.2.1! frystyk 703: /*
! 704: ** Derived from
1.2 timbl 705: */
1.16.2.1! frystyk 706: PUBLIC CONST char * HTAnchor_derived ARGS1 (HTParentAnchor *,me)
! 707: {
! 708: return me ? me->derived_from : NULL;
! 709: }
1.2 timbl 710:
1.16.2.1! frystyk 711: PUBLIC void HTAnchor_setDerived ARGS2(HTParentAnchor *, me,
! 712: CONST char *, derived_from)
1.2 timbl 713: {
1.16.2.1! frystyk 714: if (me && derived_from) StrAllocCopy(me->derived_from, derived_from);
1.2 timbl 715: }
716:
1.16.2.1! frystyk 717: /*
! 718: ** Extra Header List of unknown headers
! 719: */
! 720: PUBLIC HTList * HTAnchor_Extra ARGS1 (HTParentAnchor *, me)
1.2 timbl 721: {
1.16.2.1! frystyk 722: return me ? me->extra_headers : NULL;
! 723: }
! 724:
! 725: PUBLIC void HTAnchor_addExtra ARGS2(HTParentAnchor *, me,
! 726: CONST char * , header)
! 727: {
! 728: if (me) {
! 729: char *newhead = NULL;
! 730: StrAllocCopy(newhead, header);
! 731: if (!me->extra_headers)
! 732: me->extra_headers = HTList_new();
! 733: HTList_addObject(me->extra_headers, (void *) newhead);
1.9 frystyk 734: }
1.1 timbl 735: }
1.10 frystyk 736:
1.16.2.1! frystyk 737: /* Has header been parsed?
! 738: ** -----------------------
! 739: */
! 740: PUBLIC BOOL HTAnchor_headerParsed ARGS1(HTParentAnchor *, me)
! 741: {
! 742: return (me ? me->header_parsed : NO);
! 743: }
! 744:
! 745: /* Clear Header Information
! 746: ** ------------------------
! 747: */
! 748: PUBLIC void HTAnchor_clearHeader ARGS1(HTParentAnchor *, me)
! 749: {
! 750: me->methods = METHOD_INVALID;
! 751: me->content_encoding = NULL;
! 752: if (me->content_language) {
! 753: HTList_delete(me->content_language);
! 754: me->content_language = HTList_new();
! 755: }
! 756: me->content_length = -1; /* Invalid */
! 757: me->cte = NULL;
! 758: me->content_type = WWW_UNKNOWN;
! 759: me->charset = NULL;
! 760: me->level = NULL;
! 761:
! 762: me->date = (time_t) 0;
! 763: me->expires = (time_t) 0;
! 764: me->last_modified = (time_t) 0;
! 765:
! 766: FREE(me->derived_from);
! 767: FREE(me->version);
! 768:
! 769: if (me->extra_headers) {
! 770: HTList *cur = me->extra_headers;
! 771: char *pres;
! 772: while ((pres = (char *) HTList_nextObject(cur)))
! 773: free(pres);
! 774: HTList_delete(me->extra_headers);
! 775: me->extra_headers = NULL;
! 776: }
! 777: me->header_parsed = NO; /* All cleared */
! 778: }
Webmaster