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