caltdd.c
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 8k
Category:

Windows Develop

Development Platform:

Visual C++

  1. /*
  2.  *   Windows Calendar
  3.  *   Copyright (c) 1985 by Microsoft Corporation, all rights reserved.
  4.  *   Written by Mark L. Chamberlin, consultant to Microsoft.
  5.  *
  6. */
  7. /*
  8.  *****
  9.  ***** caltdd.c
  10.  *****
  11. */
  12. /* Get rid of more stuff from windows.h */
  13. #define NOWINSTYLES
  14. #define NOSYSMETRICS
  15. #define NOSYSCOMMANDS
  16. #define NOCLIPBOARD
  17. #define NOVIRTUALKEYCODES
  18. #include "cal.h"
  19. #define CDDMAX 512       /* Max number of DD in the tdd. */
  20. #define CDDEXTRA 8       /* When grabbing more memory for the tdd,
  21.                             allocate CDDEXTRA extra DDs.  This avoids
  22.                             doing a ReAlloc for each DD needed, so
  23.                             things happen faster.
  24.                          */
  25. /**** InitTdd - Initialize the tdd.  */
  26. VOID APIENTRY InitTdd ()
  27. {
  28. //- InitTdd: Fixed to take care of bug with LocalReAlloc of returning
  29. //- NULL when the original block is already of size zero.
  30. //- Now just free and allocate later.
  31. if (vcddAllocated != 0 && vhlmTdd)
  32. {
  33. LocalFree (vhlmTdd);
  34. }
  35. vcddUsed = vcddAllocated = 0;
  36. vhlmTdd = (LOCALHANDLE)NULL;
  37. }
  38. /**** FSearchTdd - Search the tdd for the specified DT.
  39.       If found, return TRUE and the index of the matching entry.
  40.       If not found, return FALSE and the index of where to insert (the
  41.       first dd having a DT greater than the one searched for).
  42. */
  43. BOOL APIENTRY FSearchTdd (
  44.     DT   dt,            /* Input - Date to search for. */
  45.     INT  *pitdd)        /* Output - index of match or insertion point if no
  46.    match.
  47. */
  48.      {
  49.      /* Note - it's important that the indices be declared as signed
  50.         ints since it's possible for itddHigh to go to -1 (if the
  51.         item being searched for is less than the first entry in the
  52.         table).  If it were necessary for the indices to be unsigned
  53.         (to allow a larger table size), some coding changes would be
  54.         necessary, but for this application ints will work fine since
  55.         the table will not be allowed to exceed 32767 entries (in fact,
  56.         the limit will be much lower).
  57.      */
  58.      register INT  itddLow;
  59.      register INT  itddHigh;
  60.      BOOL fFound;
  61.      DD   *pddFirst;
  62.      DT   dtTemp;
  63.      BOOL fGreater;
  64.      /* Lock down the tdd and get the address of the first dd in it. */
  65.      pddFirst = TddLock ();
  66.      /* Note - in case the tdd is empty, initialize the insertion point
  67.         to 0 for the caller.  Also set fGreater to FALSE so if the tdd is
  68.         empty, the 0 in itdd will get returned without being incremented.
  69.      */
  70.      *pitdd =  itddLow = 0;
  71.      itddHigh = vcddUsed - 1;
  72.      fFound = fGreater = FALSE;
  73.      while (itddLow <= itddHigh && !fFound)
  74.           {
  75.           fGreater = FALSE;
  76.           *pitdd = (itddLow + itddHigh) / 2;
  77.           if (dt == (dtTemp = (pddFirst + *pitdd) -> dt))
  78.                fFound = TRUE;
  79.           else if (dt > dtTemp)
  80.                {
  81.                fGreater = TRUE;
  82.                itddLow = *pitdd + 1;
  83.                }
  84.           else
  85.                itddHigh = *pitdd - 1;
  86.           }
  87.      TddUnlock ();
  88.      /* The search item was greater than the table item on the last
  89.         comparison made.  Return the index of the next higher table
  90.         entry, since this is the insertion point.  Note that if
  91.         dt == dtTemp, the index is already that of the matching item,
  92.         and if dt < dtTemp, the index is already that of the insertion
  93.         point.
  94.      */
  95.      if (fGreater)
  96.           (*pitdd)++;
  97.      return (fFound);
  98.      }
  99. /**** FGrowTdd - Grow the tdd by the specified number of DD at the specified
  100.       place.  If can't grow that much, put up an error message then return
  101.       FALSE.  If successful, return TRUE.
  102. */
  103. BOOL APIENTRY FGrowTdd (
  104.     INT  itdd,               /* INPUT - Where the insertion occurs. */
  105.     INT  cdd)                /* INPUT - How many DD to insert. */
  106. {
  107. DD   *pdd;
  108. register  INT cddUsedNew;
  109. register  INT cddAllocatedNew;
  110. if ((cddUsedNew = vcddUsed + cdd) > CDDMAX)
  111. {
  112. /* Can't make it that big. */
  113. AlertBox (vszTooManyDates, (CHAR *)NULL,
  114. MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION);
  115. return (FALSE);
  116. }
  117. if (cddUsedNew > vcddAllocated)
  118. {
  119. /* We must allocate some more memory to the tdd.  Allocate
  120.    more than we need right now to avoid always having to allocate
  121.    for each new DD.
  122. */
  123. cddAllocatedNew = cddUsedNew + CDDEXTRA;
  124. //- GrowTdd: Fixed to call LocalAlloc instead of LocalReAlloc because
  125. //- of bug in LocalReAlloc with zero size allocation.
  126. if (vcddAllocated == 0 || vhlmTdd == 0)
  127. {
  128. if ((vhlmTdd = LocalAlloc (LMEM_MOVEABLE,
  129. cddAllocatedNew * sizeof (DD))) == (LOCALHANDLE)NULL)
  130. {
  131. /* Could not get the requested memory. */
  132. AlertBox (vszOutOfMemory, (CHAR *)NULL,
  133. MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION);
  134. return (FALSE);
  135. }
  136. }
  137. else
  138. {
  139. if ((vhlmTdd = LocalReAlloc (vhlmTdd, cddAllocatedNew * sizeof (DD),
  140. LMEM_MOVEABLE)) == (LOCALHANDLE)NULL)
  141. {
  142. /* Could not get the requested memory. */
  143. AlertBox (vszOutOfMemory, (CHAR *)NULL,
  144. MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION);
  145. return (FALSE);
  146. }
  147. }
  148. vcddAllocated = cddAllocatedNew;
  149. }
  150. /* Block transfer up all DD at or beyond the insertion point. */
  151. pdd = TddLock () + itdd;
  152. BltByte ((BYTE *)pdd, (BYTE *)(pdd + cdd),
  153. (WORD)(sizeof (DD) * (vcddUsed - itdd)));
  154. TddUnlock ();
  155. vcddUsed = cddUsedNew;
  156. return (TRUE);
  157. }
  158. /**** ShrinkTdd - Shrink the tdd by the specified number of DD. */
  159. VOID APIENTRY ShrinkTdd (
  160.     INT  itdd,               /* The index of the first DD to be deleted. */
  161.     INT  cdd)                /* The number of DD to be deleted. */
  162. {
  163. register DD   *pdd;
  164. register INT  cddAllocatedNew;
  165. /* Lock the tdd, and get a pointer to the deletion point. */
  166. pdd = TddLock () + itdd;
  167. /* Block transfer down all dd beyond the deletion point. */
  168. BltByte ((BYTE *)(pdd + cdd), (BYTE *)pdd,
  169. (WORD)(sizeof (DD) * (vcddUsed - (itdd + cdd))));
  170. /* Adjust the count of dd. */
  171. vcddUsed -= cdd;
  172. TddUnlock ();
  173. if (vcddAllocated > (cddAllocatedNew = vcddUsed + CDDEXTRA))
  174. {
  175. /* There's more than CDDEXTRA free DDs now, so free up the
  176.    extra ones.
  177. */
  178. //- ShrinkTdd: Fixed to handle bug in LocalReAlloc when trying to do
  179. //- realloc of size zero.
  180. if ((vcddAllocated = cddAllocatedNew) == 0)
  181. {
  182. if (vhlmTdd)
  183. vhlmTdd = LocalFree (vhlmTdd);
  184. }
  185. else
  186. {
  187. if (vhlmTdd)
  188. vhlmTdd = LocalReAlloc (vhlmTdd, cddAllocatedNew * sizeof (DD),
  189. LMEM_MOVEABLE);
  190. }
  191. }
  192. }
  193. /**** BltByte - Block transfer a range of bytes either up or down. */
  194. BYTE * APIENTRY BltByte (
  195.     BYTE *pbSrc,
  196.     BYTE *pbDst,
  197.     WORD cb)
  198. {
  199. register BYTE *pbMax;
  200. pbMax = pbDst + cb;
  201. if (pbSrc >= pbDst)
  202. {
  203. /* Transferring down (from high to low addresses).
  204.    Start at the beginning of the block and work
  205.    towards higher addresses to avoid overwrite.
  206. */
  207. while (cb-- != 0)
  208. *pbDst++ = *pbSrc++;
  209. }
  210. else
  211. {
  212. /* Transferring up (from low to high addresses).
  213.    Start at the end of the block and work towards lower
  214.    addresses to avoid overwrite.
  215. */
  216. pbSrc += cb;
  217. pbDst = pbMax;
  218. while (cb-- != 0)
  219. *--pbDst = *--pbSrc;
  220. }
  221. /* Return a pointer to the first byte following those moved to the
  222.    destination.
  223. */
  224. return (pbMax);
  225. }
  226. /**** DeleteEmptyDd - delete DD from tdd if the DD is "empty".
  227.       The DD is "empty" if the date is not marked and it has
  228.       no longer has any data (on disk or in memory).  Note that
  229.       it cannot have any alarms if there are no Qrs for it, so
  230.       there is no need to check cAlarms.  If it is empty, get rid of the DD.
  231. */
  232. VOID APIENTRY DeleteEmptyDd (INT itdd)
  233. {
  234. register DD *pdd;
  235. register BOOL fEmpty;
  236. pdd = TddLock () + itdd;
  237. fEmpty = !pdd -> fMarked && pdd -> dl == DLNIL && pdd -> idr == IDRNIL;
  238. TddUnlock ();
  239. if (fEmpty)
  240. ShrinkTdd (itdd, 1);
  241. }
  242. /**** TddLock */
  243. DD   * APIENTRY TddLock ()
  244. {
  245. return ((DD *)LocalLock (vhlmTdd));
  246. }
  247. /**** TddUnlock */
  248. VOID APIENTRY TddUnlock ()
  249. {
  250. LocalUnlock (vhlmTdd);
  251. }