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