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