Annotation of libwww/Library/src/HTHist.c, revision 2.3

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: **
        !             7: **     A simple linear history list manager. The manager can only operate
        !             8: **     with _one_ linear list. A tree structure would be nice!
2.1       frystyk     9: */
                     10: 
                     11: /* Library include files */
                     12: #include "tcp.h"
                     13: #include "HTUtils.h"
2.3     ! frystyk    14: #include "HTAnchor.h"
        !            15: #include "HTHist.h"                                     /* Implemented here */
2.1       frystyk    16: 
2.3     ! frystyk    17: PRIVATE HTList * HTHistory = NULL;               /* List of visited anchors */
2.1       frystyk    18: 
2.3     ! frystyk    19: /* ------------------------------------------------------------------------- */
2.1       frystyk    20: 
2.3     ! frystyk    21: /*     Record an entry in the list
        !            22: **     ---------------------------
        !            23: **      Registers the object in the linear list. The first entry is the
        !            24: **     home page. No check is done for duplicates.
        !            25: **     Returns YES if OK, else NO
2.1       frystyk    26: */
2.3     ! frystyk    27: PUBLIC BOOL HTHistory_record ARGS1(HTAnchor *, destination)
2.1       frystyk    28: {
2.3     ! frystyk    29:     if (destination) {
        !            30:        if (!HTHistory)
        !            31:            HTHistory = HTList_new();
        !            32:        return HTList_addObject(HTHistory, destination);        
        !            33:     }
        !            34:     return NO;
2.1       frystyk    35: }
                     36: 
2.3     ! frystyk    37: /*     Delete an entry
        !            38: **     ---------------
        !            39: **      Deletes the object from the list
        !            40: **     Returns YES if OK, else NO
2.1       frystyk    41: */
2.3     ! frystyk    42: PUBLIC BOOL HTHistory_delete ARGS1(HTAnchor *, old)
2.1       frystyk    43: {
2.3     ! frystyk    44:     return (HTHistory ? HTList_removeObject(HTHistory, old) : NO);
2.1       frystyk    45: }
                     46: 
2.3     ! frystyk    47: /*     Clear the History list
        !            48: **     ----------------------
        !            49: **      Deletes the history list FROM the last entered occurance of the
        !            50: **     current entry and forward.
        !            51: **     Returns YES if OK, else NO
        !            52: */
        !            53: PUBLIC BOOL HTHistory_clearFrom ARGS1 (HTAnchor *, cur)
        !            54: {    
        !            55:     if (HTHistory && cur) {
        !            56:        while (!HTList_isEmpty(HTHistory) && HTList_lastObject(HTHistory)!=cur)
        !            57:            HTList_removeLastObject(HTHistory);
        !            58:        return YES;
        !            59:     }
        !            60:     return NO;
2.1       frystyk    61: }
                     62: 
2.3     ! frystyk    63: /*     Clear the History list
        !            64: **     ----------------------
        !            65: **      Deletes the history list FROM the entry at position 'cur'. Home page
        !            66: **     has position 1.
        !            67: **     Returns YES if OK, else NO
        !            68: */
        !            69: PUBLIC BOOL HTHistory_clearFromPos ARGS1 (int, ind)
        !            70: {    
        !            71:     if (HTHistory && ind>=0) {
        !            72:        HTAnchor *cur = (HTAnchor *)
        !            73:            (HTList_objectAt(HTHistory, HTList_count(HTHistory) - ind));
        !            74:        while (!HTList_isEmpty(HTHistory) && HTList_lastObject(HTHistory)!=cur)
        !            75:            HTList_removeLastObject(HTHistory);
        !            76:        return YES;
        !            77:     }
        !            78:     return NO;
        !            79: }
2.1       frystyk    80: 
2.3     ! frystyk    81: /*     Delete the whole list
        !            82: **     ---------------------
        !            83: **      Deletes the whole list from memory, so a new list can be started
        !            84: **     Returns YES if OK, else NO
        !            85: */
        !            86: PUBLIC BOOL HTHistory_clearAll NOARGS
2.1       frystyk    87: {
2.3     ! frystyk    88:     if (HTHistory) {
        !            89:        HTList_delete(HTHistory);
        !            90:        HTHistory = NULL;
        !            91:        return YES;
2.1       frystyk    92:     }
2.3     ! frystyk    93:     return NO;
2.1       frystyk    94: }
                     95: 
2.3     ! frystyk    96: /*     Number of elements stored
        !            97: **             -------------------------
        !            98: **     Returns the size of the history list or -1 if none.
        !            99: */
        !           100: PUBLIC int HTHistory_count NOARGS
2.1       frystyk   101: {
2.3     ! frystyk   102:     return (HTHistory ? HTList_count(HTHistory) : -1);
2.1       frystyk   103: }
                    104: 
2.3     ! frystyk   105: /* ------------------------------------------------------------------------- */
        !           106: /*                                 NAVIGATION                               */
        !           107: /* ------------------------------------------------------------------------- */
2.1       frystyk   108: 
2.3     ! frystyk   109: /*     Find and re-register visited anchor
        !           110: **             -----------------------------------
        !           111: **     Finds already registered anchor with given index and registers it
        !           112: **     again EXCEPT if last entry. This allows for `circular' history lists
        !           113: **     with duplicate entries.
        !           114: */
        !           115: PUBLIC HTAnchor * HTHistory_recall ARGS1(int, cnt)
2.1       frystyk   116: {
2.3     ! frystyk   117:     HTAnchor *cur = NULL;
        !           118:     if (HTHistory) {
        !           119:        cur=(HTAnchor*)HTList_objectAt(HTHistory, HTList_count(HTHistory)-cnt);
        !           120:        if (cur && cur != HTList_lastObject (HTHistory))
        !           121:            HTList_addObject (HTHistory, cur);
        !           122:     }
        !           123:     return cur;
2.1       frystyk   124: }
                    125: 
2.3     ! frystyk   126: /*     Find Indexed entry
        !           127: **     ------------------
        !           128: **     Entry with the given index in the list (1 is the home page). Like
        !           129: **     HTHistory_recall but without re-registration
2.1       frystyk   130: */
2.3     ! frystyk   131: PUBLIC HTAnchor * HTHistory_findPos ARGS1(int, n)
        !           132: {
        !           133:     return (HTHistory ?
        !           134:            (HTAnchor*)(HTList_objectAt(HTHistory,HTList_count(HTHistory)-n)) :
        !           135:            NULL);
        !           136: }
2.1       frystyk   137: 
2.3     ! frystyk   138: /*     Can we back in history
        !           139: **     ----------------------
        !           140: **     Returns YES if the current anchor is not the first entry (home page)
        !           141: */
        !           142: PUBLIC BOOL HTHistory_canBacktrack ARGS1(HTAnchor *, cur)
        !           143: {
        !           144:     if (HTHistory)
        !           145:        return (HTList_indexOf(HTHistory, cur) < HTList_count(HTHistory)-1);
        !           146:     return NO;
        !           147: }
2.1       frystyk   148: 
2.3     ! frystyk   149: /*
        !           150: **     Backtrack with deletion
        !           151: **     -----------------------
        !           152: **     Returns the previous object and erases the last object. This does not
        !           153: **     allow for 'forward' as we are always at the end of the list. If no
        !           154: **     previous object exists, NULL is returned so that the application knows
        !           155: **     that no previous object was found. See also HTHistory_back(). 
2.1       frystyk   156: */
2.3     ! frystyk   157: PUBLIC HTAnchor * HTHistory_backtrack NOARGS
2.1       frystyk   158: {
2.3     ! frystyk   159:     if (HTHistory && HTList_count(HTHistory) > 1) {
        !           160:        HTList_removeLastObject (HTHistory);
        !           161:        return (HTAnchor *) HTList_lastObject (HTHistory);
2.1       frystyk   162:     }
2.3     ! frystyk   163:     return NULL;
2.1       frystyk   164: }
                    165: 
2.3     ! frystyk   166: /*
        !           167: **     Backtrack without deletion
        !           168: **     --------------------------
        !           169: **     Returns the previos object but does not erase the last object. This
        !           170: **     does not allow for 'forward'. If no previous object exists,  NULL is
        !           171: **     returned so that the application knows that no previous object was
        !           172: **     found. See also HTHistory_backtrack()
        !           173: */
        !           174: PUBLIC HTAnchor * HTHistory_back ARGS1(HTAnchor *, cur)
2.1       frystyk   175: {
2.3     ! frystyk   176:     if (HTHistory && HTHistory_canBacktrack(cur)) {
        !           177:        int pos = HTList_indexOf(HTHistory, cur);
        !           178:        return ((HTAnchor *) HTList_objectAt(HTHistory, pos + 1));
        !           179:     }
        !           180:     return NULL;
2.1       frystyk   181: }
                    182: 
2.3     ! frystyk   183: /*     Can we go forward
        !           184: **     -----------------
        !           185: **     Returns YES if the current anchor is not the last entry
2.1       frystyk   186: */
2.3     ! frystyk   187: PUBLIC BOOL HTHistory_canForward ARGS1(HTAnchor *, cur)
        !           188: {
        !           189:     return (HTHistory && cur && (cur != HTList_lastObject(HTHistory)));
        !           190: }
2.1       frystyk   191: 
2.3     ! frystyk   192: /*
        !           193: **     Forward
        !           194: **     -------
        !           195: **     Return the next object in the list or NULL if none
2.1       frystyk   196: */
2.3     ! frystyk   197: PUBLIC HTAnchor * HTHistory_forward ARGS1(HTAnchor *, cur)
2.1       frystyk   198: {
2.3     ! frystyk   199:     if (HTHistory && HTHistory_canForward(cur)) {
        !           200:        int pos = HTList_indexOf(HTHistory, cur);
        !           201:        return ((HTAnchor *) HTList_objectAt(HTHistory, pos - 1));
        !           202:     }
        !           203:     return NULL;
2.1       frystyk   204: }
                    205: 
2.3     ! frystyk   206: /*
        !           207: **     Can Move By Offset
        !           208: **     ------------------
        !           209: **     Support for Next and Previous in order to allow for browsing through
        !           210: **     the same parent node
2.1       frystyk   211: */
2.3     ! frystyk   212: PUBLIC BOOL HTHistory_canMoveBy ARGS1(int, offset)
        !           213: {
        !           214:     HTAnchor *last = (HTAnchor *) HTList_lastObject(HTHistory);
2.1       frystyk   215: 
2.3     ! frystyk   216:     /* If we have a last entry and this is a child */
        !           217:     if (last && last != (HTAnchor *) last->parent) {
        !           218:        HTList *kids = last->parent->children;
        !           219:        int cur = HTList_indexOf(kids, last); 
        !           220:        return (HTList_objectAt(kids, cur-(offset)) != NULL);
        !           221:     }
        !           222:     return NO;
2.1       frystyk   223: }
                    224: 
2.3     ! frystyk   225: /*     Browse through references in the same parent node
        !           226: **     -------------------------------------------------
        !           227: **     Take the n-th child's link after or before the one we took to get here.
        !           228: **     Positive offset means go towards most recently added children or "Next"
        !           229: **     and negative value means "Previous"
        !           230: */
        !           231: PUBLIC HTAnchor * HTHistory_moveBy ARGS1 (int, offset)
2.1       frystyk   232: {
2.3     ! frystyk   233:     HTAnchor *last = (HTAnchor *) HTList_lastObject(HTHistory);
        !           234: 
        !           235:     /* If we have a last entry and this is a child */
        !           236:     if (last && last != (HTAnchor *) last->parent) {
        !           237:        HTList *kids = last->parent->children;
        !           238:        int cur = HTList_indexOf(kids, last); 
        !           239:        HTAnchor *nextOne = (HTAnchor *) HTList_objectAt (kids, cur-(offset));
        !           240:        if (nextOne) {
        !           241:            HTAnchor * destination = HTAnchor_followMainLink(nextOne);
        !           242:            if (destination) {
        !           243:                HTList_removeLastObject(HTHistory);
        !           244:                HTList_removeLastObject (HTHistory);
        !           245:                HTList_addObject (HTHistory, nextOne);
        !           246:                HTList_addObject (HTHistory, destination);
        !           247:            }
        !           248:            return destination;
        !           249:        } else {
        !           250:            if (TRACE)
        !           251:                fprintf(TDEST, 
        !           252:                        "HTHistory... Index out of range %d of list %p.\n",
        !           253:                        offset, (void*)kids);
        !           254:        }
        !           255:     }
        !           256:     return NULL;
2.1       frystyk   257: }
                    258: 
2.3     ! frystyk   259: /*     Change last history entry
        !           260: **     -------------------------
2.1       frystyk   261: **     Sometimes we load a node by one anchor but leave by a different
                    262: **     one, and it is the one we left from which we want to remember.
                    263: */
2.3     ! frystyk   264: PUBLIC void HTHistory_leavingFrom ARGS1 (HTAnchor *, anchor)
2.1       frystyk   265: {
2.3     ! frystyk   266:     if (HTHistory) {
        !           267:        if (HTList_removeLastObject (HTHistory))
        !           268:            HTList_addObject (HTHistory, anchor);
        !           269:     }
2.1       frystyk   270: }

Webmaster