Annotation of libwww/Library/src/HTHist.c, revision 2.4
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: */
! 32: PUBLIC HTHistory *HTHistory_new NOARGS
! 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.4 ! frystyk 45: PUBLIC BOOL HTHistory_delete ARGS1(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.4 ! frystyk 61: PUBLIC BOOL HTHistory_record ARGS2(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.4 ! frystyk 74: PUBLIC BOOL HTHistory_replace ARGS2(HTHistory *, hist, HTAnchor *, cur)
! 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.4 ! frystyk 88: PUBLIC BOOL HTHistory_removeLast ARGS1(HTHistory *, hist)
! 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.4 ! frystyk 99: PUBLIC BOOL HTHistory_removeFrom ARGS2 (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.4 ! frystyk 115: PUBLIC int HTHistory_count ARGS1(HTHistory *, hist)
! 116: {
! 117: return (hist ? HTList_count(hist->alist) : -1);
! 118: }
! 119:
! 120: /* Current Location
! 121: ** ----------------
! 122: ** Returns the current position or -1
! 123: */
! 124: PUBLIC int HTHistory_position ARGS1(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.4 ! frystyk 139: PUBLIC HTAnchor * HTHistory_recall ARGS2(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: */
! 160: PUBLIC HTAnchor * HTHistory_find ARGS2(HTHistory *, hist, int, pos)
! 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.4 ! frystyk 176: PUBLIC HTAnchor * HTHistory_list ARGS2(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.4 ! frystyk 187: PUBLIC BOOL HTHistory_canBacktrack ARGS1(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.4 ! frystyk 200: PUBLIC HTAnchor * HTHistory_backtrack ARGS1(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.4 ! frystyk 217: PUBLIC HTAnchor * HTHistory_back ARGS1(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.4 ! frystyk 230: PUBLIC BOOL HTHistory_canForward ARGS1(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.4 ! frystyk 240: PUBLIC HTAnchor * HTHistory_forward ARGS1(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