home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / winsock / fingd100 / src / dsplist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  7.7 KB  |  344 lines

  1. // Contents ---------------------------------------------------------------
  2. //
  3. //   dsplist.c -- Display linked lists module
  4. //
  5. //   Version 1.0, Windows Socket Finger Daemon
  6. //
  7. //   Copyright (C) Frederick W. Bent 1994
  8. //   All rights reserved.
  9. //
  10. //
  11. // Description
  12. //
  13. // Module DSPLIST allows the NETWRK_ module to build a display list,
  14. // and the FINGERD module to retrieve one.  A display list is a linked
  15. // list of text lines accompanied by a count of list entries.  The finger
  16. // daemon uses display lists to represent the the remote finger client's
  17. // return data in a form suitable for scrolling window display.
  18. //
  19. // The display lists are stored in the local heap using Windows functions
  20. // rather than the C library functions so that the heap can grow easily.
  21. //
  22. // Ends -------------------------------------------------------------------
  23.  
  24. // History ----------------------------------------------------------------
  25. //
  26. // 10/20/92  Lee Murach    Created.
  27. // 12/02/92  Lee Murach    PushChars() replaces PushChar() as export, LF
  28. //                         triggers newline, CRs discarded
  29. // 01/08/94  Fred Bent     Converted everything from malloc() to LocalAlloc()
  30. //               also made sure everything is left moveable.
  31. //
  32. // Ends -------------------------------------------------------------------
  33.  
  34. // Legal Stuff ------------------------------------------------------------
  35. //
  36. // Finger Version 3.1, a Windows Sockets Finger Client
  37. //
  38. // Copyright 1992, 1993 Network Research Corporation
  39. //
  40. // Permission to use, modify, and distribute this software and its
  41. // documentation for any purpose and without fee is hereby granted, provided
  42. // that the above copyright notice appears in all copies and that both
  43. // that copyright notice and this permission notice appear in supporting
  44. // documentation.  NRC makes no claims as to the suitability of this software
  45. // for any purpose.
  46. //
  47. // Ends -------------------------------------------------------------------
  48.  
  49.  
  50. // Interface Dependencies -------------------------------------------------
  51.  
  52.  
  53.  
  54.  
  55. #include <string.h>
  56. #include <stdlib.h>
  57. #include <windows.h>
  58. #include "dsplist.h"
  59.  
  60. #define  LF 10                         // linefeed
  61. #define  CR 13                         // carriage return
  62. #define  TABSTRING "        "          // 8 character tab
  63.  
  64. VOID PushChar(char ch);
  65. VOID PushLine(VOID);
  66. VOID FreeLine(HLOCAL hLine);
  67.  
  68. char LineBuf[132];                     // holds accumulating text line
  69. int LineLen;                           // length of text line
  70. int LineCount;                         // n items in list
  71. HLOCAL    hLast;
  72. HLOCAL  hFirst;
  73.  
  74. //
  75. // PushChars -- pushes buffer of characters into the display list;
  76. // expands tabs.
  77. //
  78. VOID PushChars(char *buf, int buflen)
  79. {
  80.    while (buflen--)
  81.    {
  82.       if (*buf == '\t')
  83.          PushChars(TABSTRING, strlen(TABSTRING));
  84.       else
  85.          PushChar(*buf);
  86.    
  87.       buf++;
  88.    }
  89. }
  90.  
  91.  
  92. //
  93. // PushChar -- pushes a character into the LineBuf.  Pushes line into
  94. // the line list if <cr> encountered, or LineBuf is full.  Discards
  95. // linefeeds.
  96. //
  97. VOID PushChar(char ch)
  98. {
  99.    if (LineLen < sizeof(LineBuf))
  100.       if (ch != LF)
  101.      if (ch != CR)
  102.             LineBuf[LineLen++] = ch;
  103.      else;                         // discard carriage returns
  104.       else                             // linefeeds signal newline
  105.          PushLine();
  106.    else
  107.       PushLine();
  108. }
  109.  
  110. //
  111. // PushLine -- pushes a text line into the accumulating list of text lines.
  112. //
  113. VOID PushLine(VOID)
  114. {
  115.    HLOCAL   hLocal;
  116.    LINEITEM *p, *pLast;
  117.    PSTR    szText;
  118.  
  119.  
  120.    hLocal = LocalAlloc(LHND, sizeof(LINEITEM));
  121.  
  122.    if ( hLocal != NULL )
  123.    {
  124.        p = (LINEITEM *) LocalLock(hLocal);
  125.        if (p != NULL)
  126.        {
  127.           p->next = NULL;
  128.  
  129.           if (LineLen > 0)
  130.           {
  131.           HLOCAL hTemp;
  132.  
  133.           hTemp = LocalAlloc(LHND, (LineLen+1));
  134.           p->hText = hTemp;
  135.           if ( hTemp != NULL )
  136.                   {
  137.             szText = LocalLock(hTemp);
  138.             if (szText != NULL)
  139.             {
  140.                             p->len = LineLen;
  141.                 lstrcpyn(szText, (LPSTR) LineBuf, (LineLen+1));
  142.                 LocalUnlock(hTemp);
  143.             } else {
  144.                 LocalFree(hTemp);
  145.                 p->len = 0;
  146.             }
  147.           } else {
  148.             p->len = 0;
  149.           }
  150.           } else {
  151.           p->hText = NULL;
  152.           p->len = 0;
  153.           }
  154.  
  155.               pLast = (LINEITEM *) LocalLock(hLast);
  156.           pLast->next = hLocal;
  157.           LocalUnlock(hLast);
  158.  
  159.           hLast = hLocal;
  160.           LocalUnlock(hLocal);
  161.  
  162.           LineLen = 0;
  163.           LineCount++;
  164.  
  165.        } else {
  166.         LocalFree(hLocal);
  167.            }
  168.    }
  169. }
  170.  
  171.  
  172. VOID    RemoveFirstDisplayLine(VOID)
  173. {
  174.     LINEITEM *temp;
  175.     HLOCAL    hNext;
  176.  
  177.     if (hFirst != NULL)
  178.     {
  179.             temp = (LINEITEM *) LocalLock(hFirst);
  180.         hNext = temp->next;
  181.         LocalUnlock(hFirst);
  182.         FreeLine(hFirst);
  183.         hFirst = hNext;
  184.         LineCount--;
  185.     }
  186. }
  187.  
  188. //
  189. // FreeDisplayList -- frees the display list, leaves a null list.
  190. //
  191. VOID FreeDisplayList(VOID)
  192. {
  193.    FreeLineList(hFirst);
  194.    hFirst = NULL;
  195.    LineCount = 0;
  196. }
  197.  
  198. //
  199. // FreeLineList -- frees a LINEITEM list
  200. //
  201. VOID FreeLineList(HLOCAL hLine)
  202. {
  203.    LINEITEM    *p;
  204.    HLOCAL    hNext, hItem;
  205.  
  206.    hItem = hLine;
  207.    while (hItem != NULL)
  208.    {
  209.     p = (LINEITEM *) LocalLock(hItem);    // local current item
  210.     hNext = p->next;    // what's next?
  211.     LocalUnlock(hItem);
  212.     FreeLine(hItem);
  213.     hItem = hNext;
  214.    }
  215. }
  216.  
  217.  
  218. //
  219. // FreeLine -- frees a LINEITEM
  220. //
  221. VOID FreeLine(HLOCAL hLine)
  222. {
  223.  
  224.    LINEITEM    *p;
  225.  
  226.    if (hLine != NULL)
  227.    {
  228.     p = (LINEITEM *) LocalLock(hLine);    // local current item
  229.         if ( p->hText != NULL )
  230.         LocalFree(p->hText);    // bye bye test buffer
  231.     LocalUnlock(hLine);
  232.     LocalFree(hLine);    // bye bye item
  233.    }
  234. }
  235.  
  236.  
  237. //
  238. // OpenDisplayList -- initializes a display list.  Call before using
  239. // PushChar() to build the list.
  240. //
  241. BOOL OpenDisplayList(VOID)
  242. {
  243.    LineCount = LineLen = 0;
  244.  
  245.    // initialize list with a dummy LINEITEM
  246.    if ((hLast = hFirst = LocalAlloc(LHND, sizeof(LINEITEM))) != NULL )
  247.       return TRUE;
  248.  
  249.    return FALSE;  // failure
  250. }
  251.  
  252. //
  253. // CloseDisplayList -- pushes final LINEITEM (if any) onto list, and
  254. // releases dummy list header.  Call after last PushChar() to complete
  255. // the display list.
  256. //
  257. VOID CloseDisplayList(VOID)
  258. {
  259.    LINEITEM *pFirst;
  260.    HLOCAL hNext;
  261.  
  262.    if (LineLen > 0)    // part of a line
  263.       PushLine();
  264.  
  265.    pFirst = (LINEITEM *) LocalLock(hFirst);
  266.    hNext = pFirst->next;
  267.    LocalUnlock(hFirst);
  268.    FreeLine(hFirst);
  269.    hFirst = hNext;
  270. }
  271.  
  272. //
  273. // GetDispList -- retrieves the display list.
  274. //
  275. VOID GetDisplayList(HLOCAL *ppLine, int *pNLines)
  276. {
  277.    *ppLine = hFirst;
  278.    *pNLines = LineCount;
  279. }
  280.  
  281.  
  282. long    GetSizeOfDisplay(HLOCAL hItem)
  283. {
  284.     long    lSize;
  285.     LINEITEM    *p;
  286.     HLOCAL    hNext;
  287.  
  288.     hItem = hItem;
  289.         lSize = 0L;
  290.     while (hItem != NULL)
  291.     {
  292.         p = (LINEITEM *) LocalLock(hItem);    // local current item
  293.         hNext = p->next;    // what's next?
  294.         lSize += p->len + 2;    // don't forget <CRLF>!
  295.         LocalUnlock(hItem);
  296.         hItem = hNext;
  297.     }
  298.  
  299.     return lSize;
  300. }
  301.  
  302. HGLOBAL CopyDisplayList(VOID)
  303. {
  304.     long    lSize;
  305.     HGLOBAL hGlobal;
  306.     LINEITEM    *p;
  307.     HLOCAL    hNext, hItem;
  308.     PSTR    szText;
  309.     LPSTR    lpszBuffer;
  310.  
  311.  
  312.     hGlobal = GlobalAlloc(GHND, GetSizeOfDisplay(hFirst));
  313.     if ( hGlobal == NULL) return NULL;
  314.  
  315.     lpszBuffer = GlobalLock(hGlobal);
  316.     if ( lpszBuffer == NULL)
  317.     {
  318.         GlobalFree(hGlobal);
  319.         return NULL;
  320.         }
  321.  
  322.     hItem = hFirst;
  323.     while (hItem != NULL)
  324.     {
  325.         p = (LINEITEM *)LocalLock(hItem);    // local current item
  326.         hNext = p->next;    // what's next?
  327.         if ( p->hText != NULL)
  328.                 {
  329.             szText = LocalLock(p->hText);
  330.             lstrcat(lpszBuffer, (LPSTR) szText);
  331.             LocalUnlock(p->hText);
  332.         }
  333.         lstrcat(lpszBuffer, "\r\n");
  334.         LocalUnlock(hItem);
  335.         hItem = hNext;
  336.     }
  337.     GlobalUnlock(hGlobal);
  338.  
  339.     return hGlobal;
  340.  
  341. }
  342.  
  343.  
  344.