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