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