Annotation of libwww/Library/src/HTHist.c, revision 2.9
2.1 frystyk 1: /* HTHist.c
2: ** NAVIGATION MANAGER
3: **
2.2 frystyk 4: ** (c) COPYRIGHT MIT 1995.
2.1 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
2.9 ! frystyk 6: ** @(#) $Id: HTHist.c,v 2.8 1996/04/12 17:47:12 frystyk Exp $
2.3 frystyk 7: **
2.4 frystyk 8: ** The history manager for the Library. This module is not called any
9: ** where in the Library so if the application does not call it, it is
10: ** not linked in at all.
2.1 frystyk 11: */
12:
13: /* Library include files */
2.9 ! frystyk 14: #include "wwwsys.h"
2.1 frystyk 15: #include "HTUtils.h"
2.3 frystyk 16: #include "HTAnchor.h"
17: #include "HTHist.h" /* Implemented here */
2.1 frystyk 18:
2.4 frystyk 19: struct _HTHistory {
20: HTList * alist; /* List of anchors */
21: int pos; /* Current position in list. 1 is home anchor */
22: };
2.1 frystyk 23:
2.3 frystyk 24: /* ------------------------------------------------------------------------- */
2.1 frystyk 25:
2.4 frystyk 26: /* Create a new History List
27: ** -------------------------
28: ** Creates a new history list and returns a handle to it. There can be
29: ** multiple history lists - for example one for each open window in
30: ** an application.
31: ** Returns HTHistory object if OK, else NULL
32: */
2.5 frystyk 33: PUBLIC HTHistory *HTHistory_new (void)
2.4 frystyk 34: {
2.6 frystyk 35: HTHistory *element;
36: if ((element = (HTHistory *) HT_CALLOC(1, (sizeof(HTHistory)))) == NULL)
37: HT_OUTOFMEM("HTHistory_new");
2.4 frystyk 38: element->alist = HTList_new();
39: return element;
40: }
41:
42: /* Delete a History list
43: ** ---------------------
44: ** Deletes the history list.
2.3 frystyk 45: ** Returns YES if OK, else NO
2.1 frystyk 46: */
2.5 frystyk 47: PUBLIC BOOL HTHistory_delete (HTHistory * hist)
2.1 frystyk 48: {
2.4 frystyk 49: if (hist) {
50: HTList_delete(hist->alist);
2.6 frystyk 51: HT_FREE(hist);
2.4 frystyk 52: return YES;
2.3 frystyk 53: }
54: return NO;
2.1 frystyk 55: }
56:
2.4 frystyk 57: /* Record an entry in a list
58: ** -------------------------
59: ** Registers the object in the linear list. The first entry is the
60: ** home page. No check is done for duplicates.
61: ** Returns YES if ok, else NO
2.1 frystyk 62: */
2.5 frystyk 63: PUBLIC BOOL HTHistory_record (HTHistory * hist, HTAnchor * cur)
2.1 frystyk 64: {
2.4 frystyk 65: return (hist && cur && HTList_addObject(hist->alist, cur) && hist->pos++);
2.1 frystyk 66: }
67:
2.4 frystyk 68: /* Replace list with new element
69: ** -----------------------------
70: ** Inserts the new element at the current position and removes all any
71: ** old list from current position. For example if c is cur pos
72: ** before: a b c d e
73: ** after : a b f
74: ** Returns YES if ok, else NO
2.3 frystyk 75: */
2.5 frystyk 76: PUBLIC BOOL HTHistory_replace (HTHistory * hist, HTAnchor * cur)
2.4 frystyk 77: {
78: if (hist && cur) {
79: HTHistory_removeFrom(hist, hist->pos);
80: HTHistory_record(hist, cur);
2.3 frystyk 81: }
82: return NO;
2.1 frystyk 83: }
84:
2.4 frystyk 85: /* Delete last entry in a list
86: ** ---------------------------
87: ** Deletes the last object from the list
2.3 frystyk 88: ** Returns YES if OK, else NO
89: */
2.5 frystyk 90: PUBLIC BOOL HTHistory_removeLast (HTHistory * hist)
2.4 frystyk 91: {
92: return (hist && HTList_removeLastObject(hist->alist) && hist->pos--);
2.3 frystyk 93: }
2.1 frystyk 94:
2.4 frystyk 95: /* Remove the History list from position
96: ** ------------------------------------
97: ** Deletes the history list FROM the entry at position 'cur' (excluded).
98: ** Home page has position 1.
2.3 frystyk 99: ** Returns YES if OK, else NO
100: */
2.5 frystyk 101: PUBLIC BOOL HTHistory_removeFrom (HTHistory * hist, int pos)
2.1 frystyk 102: {
2.4 frystyk 103: if (hist && pos>=0) {
104: int cnt = HTList_count(hist->alist) - pos;
105: while (cnt-->0 && HTList_removeLastObject(hist->alist));
106: if (hist->pos > pos)
107: hist->pos = pos;
2.3 frystyk 108: return YES;
2.1 frystyk 109: }
2.3 frystyk 110: return NO;
2.1 frystyk 111: }
112:
2.3 frystyk 113: /* Number of elements stored
114: ** -------------------------
115: ** Returns the size of the history list or -1 if none.
116: */
2.5 frystyk 117: PUBLIC int HTHistory_count (HTHistory * hist)
2.4 frystyk 118: {
119: return (hist ? HTList_count(hist->alist) : -1);
120: }
121:
122: /* Current Location
123: ** ----------------
124: ** Returns the current position or -1
125: */
2.5 frystyk 126: PUBLIC int HTHistory_position (HTHistory * hist)
2.1 frystyk 127: {
2.4 frystyk 128: return (hist ? hist->pos : -1);
2.1 frystyk 129: }
130:
2.3 frystyk 131: /* ------------------------------------------------------------------------- */
132: /* NAVIGATION */
133: /* ------------------------------------------------------------------------- */
2.1 frystyk 134:
2.3 frystyk 135: /* Find and re-register visited anchor
136: ** -----------------------------------
2.4 frystyk 137: ** Finds already registered anchor at given position and registers it
2.3 frystyk 138: ** again EXCEPT if last entry. This allows for `circular' history lists
2.4 frystyk 139: ** with duplicate entries. Position 1 is the home anchor.
2.3 frystyk 140: */
2.5 frystyk 141: PUBLIC HTAnchor * HTHistory_recall (HTHistory * hist, int pos)
2.1 frystyk 142: {
2.3 frystyk 143: HTAnchor *cur = NULL;
2.4 frystyk 144: if (hist && pos > 0) {
145: int len = HTList_count(hist->alist);
146: if ((cur = (HTAnchor *) HTList_objectAt(hist->alist, len-pos))) {
147: if (cur != HTList_lastObject (hist->alist)) {
148: HTHistory_record(hist, cur);
149: } else
150: hist->pos = pos;
151: }
152: }
153: return cur;
154: }
155:
156: /* Find Entry at position
157: ** ----------------------
158: ** Entry with the given index in the list (1 is the home page). Like
159: ** HTHistory_recall but without re-registration. Current position is
160: ** updated.
161: */
2.5 frystyk 162: PUBLIC HTAnchor * HTHistory_find (HTHistory * hist, int pos)
2.4 frystyk 163: {
164: HTAnchor *cur = NULL;
165: if (hist && pos > 0) {
166: if ((cur = (HTAnchor *)
167: (HTList_objectAt(hist->alist, HTList_count(hist->alist)-pos))))
168: hist->pos = pos;
2.3 frystyk 169: }
170: return cur;
2.1 frystyk 171: }
172:
2.4 frystyk 173: /* List Entry at position
174: ** ----------------------
2.3 frystyk 175: ** Entry with the given index in the list (1 is the home page). Like
2.4 frystyk 176: ** HTHistory_find but current position is NOT updated.
2.1 frystyk 177: */
2.5 frystyk 178: PUBLIC HTAnchor * HTHistory_list (HTHistory * hist, int pos)
2.3 frystyk 179: {
2.4 frystyk 180: return (hist ? (HTAnchor *)
181: (HTList_objectAt(hist->alist, HTList_count(hist->alist)-pos)) :
2.3 frystyk 182: NULL);
183: }
2.1 frystyk 184:
2.3 frystyk 185: /* Can we back in history
186: ** ----------------------
187: ** Returns YES if the current anchor is not the first entry (home page)
188: */
2.5 frystyk 189: PUBLIC BOOL HTHistory_canBacktrack (HTHistory * hist)
2.3 frystyk 190: {
2.4 frystyk 191: return ((hist && hist->pos > 1) ? YES : NO);
2.3 frystyk 192: }
2.1 frystyk 193:
2.3 frystyk 194: /*
195: ** Backtrack with deletion
196: ** -----------------------
197: ** Returns the previous object and erases the last object. This does not
198: ** allow for 'forward' as we are always at the end of the list. If no
199: ** previous object exists, NULL is returned so that the application knows
200: ** that no previous object was found. See also HTHistory_back().
2.1 frystyk 201: */
2.5 frystyk 202: PUBLIC HTAnchor * HTHistory_backtrack (HTHistory * hist)
2.1 frystyk 203: {
2.4 frystyk 204: if (HTHistory_canBacktrack(hist)) {
205: HTHistory_removeLast(hist);
206: return (HTAnchor *) HTList_lastObject(hist->alist);
2.1 frystyk 207: }
2.3 frystyk 208: return NULL;
2.1 frystyk 209: }
210:
2.3 frystyk 211: /*
212: ** Backtrack without deletion
213: ** --------------------------
214: ** Returns the previos object but does not erase the last object. This
215: ** does not allow for 'forward'. If no previous object exists, NULL is
216: ** returned so that the application knows that no previous object was
217: ** found. See also HTHistory_backtrack()
218: */
2.5 frystyk 219: PUBLIC HTAnchor * HTHistory_back (HTHistory * hist)
2.1 frystyk 220: {
2.4 frystyk 221: if (HTHistory_canBacktrack(hist)) {
222: int pos = HTList_count(hist->alist) - (--hist->pos);
223: return ((HTAnchor *) HTList_objectAt(hist->alist, pos));
2.3 frystyk 224: }
225: return NULL;
2.1 frystyk 226: }
227:
2.3 frystyk 228: /* Can we go forward
229: ** -----------------
230: ** Returns YES if the current anchor is not the last entry
2.1 frystyk 231: */
2.5 frystyk 232: PUBLIC BOOL HTHistory_canForward (HTHistory * hist)
2.3 frystyk 233: {
2.4 frystyk 234: return ((hist && hist->pos < HTList_count(hist->alist)) ? YES : NO);
2.3 frystyk 235: }
2.1 frystyk 236:
2.3 frystyk 237: /*
238: ** Forward
239: ** -------
240: ** Return the next object in the list or NULL if none
2.1 frystyk 241: */
2.5 frystyk 242: PUBLIC HTAnchor * HTHistory_forward (HTHistory * hist)
2.1 frystyk 243: {
2.4 frystyk 244: if (HTHistory_canForward(hist)) {
245: int pos = HTList_count(hist->alist) - (++hist->pos);
246: return ((HTAnchor *) HTList_objectAt(hist->alist, pos));
2.3 frystyk 247: }
248: return NULL;
2.1 frystyk 249: }
Webmaster