home *** CD-ROM | disk | FTP | other *** search
/ CLIX - Fazer Clix Custa Nix / CLIX-CD.cdr / mac / lib / Mac / Memory.xs < prev    next >
Text File  |  1998-04-05  |  21KB  |  1,079 lines

  1. /*
  2.  *
  3.  *    Copyright (c) 1996 Matthias Neeracher
  4.  *
  5.  *    You may distribute under the terms of the Perl Artistic License,
  6.  *    as specified in the README file.
  7.  *
  8.  * $Log: Memory.xs,v $
  9.  * Revision 1.2  1997/11/18 00:52:34  neeri
  10.  * MacPerl 5.1.5
  11.  *
  12.  * Revision 1.1  1997/04/07 20:49:55  neeri
  13.  * Synchronized with MacPerl 5.1.4a1
  14.  *
  15.  */
  16.  
  17. #define MAC_CONTEXT
  18.  
  19. #include "EXTERN.h"
  20. #include "perl.h"
  21. #include "XSUB.h"
  22. #include <Types.h>
  23. #include <Memory.h>
  24. #include <TextUtils.h>
  25.  
  26. typedef int SysRet;
  27.  
  28. #define MemErrorReturn  \
  29.     ST(0) = sv_newmortal();                 \
  30.     if (!(gLastMacOSErr = MemError()))  \
  31.         sv_setiv(ST(0), 1);
  32.  
  33. MODULE = Mac::Memory    PACKAGE = Handle
  34.  
  35. =head2 Handle
  36.  
  37. Handle provides an object interface to do simple operations on MacOS handles.
  38. The interface is simpler than the more general memory management functions.
  39.  
  40. =item new
  41.  
  42. =item new STRING
  43.  
  44. Create a new handle and return it. Copy $STRING into the handle if present.
  45. Return a 0 value if a handle could not be created.
  46.  
  47.     $h = new Handle;
  48.     $hs = new Handle("This string will now exist in hyperspace");
  49.  
  50. =cut
  51.  
  52. HandleRet
  53. new(package,data=0)
  54.     SV *    package
  55.     SV *    data
  56.     CODE:
  57.     if (data) {
  58.         STRLEN  len;
  59.         Ptr     ptr =   SvPV(data, len);
  60.         if (gLastMacOSErr = PtrToHand(ptr, &RETVAL, len)) {
  61.             XSRETURN_UNDEF;
  62.         }
  63.     } else
  64.         RETVAL = NewHandle(0);
  65.     OUTPUT:
  66.     RETVAL
  67.  
  68. =item size
  69.  
  70. Return the size of a handle (i.e., its data portion).
  71.  
  72.     die unless (new Handle)->size == 0;
  73.     die unless $hs->size == 40;
  74.  
  75. =cut
  76.  
  77. long
  78. size(hand)
  79.     Handle  hand
  80.     CODE:
  81.     RETVAL = GetHandleSize(hand);
  82.     OUTPUT:
  83.     RETVAL
  84.  
  85. =item append DATA 
  86.  
  87. Appends the DATA to the end of the handle
  88. and returns the success as the result.
  89.  
  90.     $h->append("This string will now exist in hyperspace");
  91.     die unless $h->size == 40;
  92.  
  93. =cut
  94.  
  95. Boolean
  96. append(hand, data)
  97.     Handle  hand
  98.     SV *        data
  99.     CODE:
  100.     {
  101.         STRLEN  len;
  102.         Ptr     ptr =   SvPV(data, len);
  103.         RETVAL = !PtrAndHand(ptr, hand, len);
  104.     }
  105.     OUTPUT:
  106.     RETVAL
  107.  
  108. =item set OFFSET, LENGTH, DATA 
  109.  
  110. =item set OFFSET, LENGTH 
  111.  
  112. =item set OFFSET 
  113.  
  114. =item set
  115.  
  116. Munge the contents of the handle with the $DATA (deleting if not present), for the
  117. $LENGTH (through to the end of the handle contents if not present), starting at
  118. $OFFSET (the beginning if not present).
  119.  
  120.     $h->set(5, 6, "datum");
  121.     
  122. yields
  123.  
  124.     "This datum will now exist in hyperspace"
  125.  
  126.  
  127. =cut
  128.  
  129. Boolean
  130. set(hand, offset=0, length=-1, data=0)
  131.     Handle  hand
  132.     long        offset
  133.     long        length
  134.     SV *        data
  135.     CODE:   
  136.     {
  137.         STRLEN  len;
  138.         Ptr     ptr;
  139.         if (data)
  140.             ptr =   SvPV(data, len);
  141.         else {
  142.             len = 0;
  143.             ptr = (char *) -1;
  144.         }
  145.         RETVAL = 0 <= Munger(hand, offset, nil, length, ptr, len);
  146.     }
  147.     OUTPUT:
  148.     RETVAL
  149.  
  150. =item get OFFSET, LENGTH 
  151.  
  152. =item get OFFSET 
  153.  
  154. =item get
  155.  
  156. Return a datum which is the contents of the memory referenced by $HANDLE, 
  157. starting at $OFFSET (default zero), of length $LENGTH (default the rest
  158. of the handle).
  159.  
  160.     die unless $hs->get(5, 6) eq "string";
  161.  
  162. =cut
  163.  
  164. SV *
  165. get(hand, offset=0, length=-1)
  166.     Handle  hand
  167.     long        offset
  168.     long        length
  169.     CODE:
  170.     {
  171.         char state = HGetState(hand);
  172.         HLock(hand);
  173.         if (length < 0)
  174.             length = GetHandleSize(hand) - offset;
  175.         RETVAL = newSVpv(*hand+offset, length);
  176.         HSetState(hand, state);
  177.     }
  178.     OUTPUT:
  179.     RETVAL
  180.  
  181. =item address 
  182.  
  183. Return the address of the memory block.
  184.  
  185. =cut
  186.  
  187. RawPtr
  188. address(hand)
  189.     Handle  hand
  190.     CODE:
  191.     RETVAL = *hand;
  192.     OUTPUT:
  193.     RETVAL
  194.  
  195. =item state
  196.  
  197. =item state NEWSTATE 
  198.  
  199. Return the (locked) state of the handle, or return TRUE if the $NEWSTATE
  200. of the handle is installed.
  201.  
  202.     my $state = $h->state;
  203.     HLock($h);
  204.     # bunch of operations requiring $h to be locked
  205.     $h->state($state);  # so nested locks exit properly
  206.  
  207. More than the lock state is stored here, so restoring the actual state on leaving
  208. a scope is required.
  209.  
  210.  
  211. =cut
  212. char
  213. state(hand, state=0)
  214.     Handle  hand
  215.     char        state
  216.     CODE:
  217.     if (items == 1)
  218.         RETVAL = HGetState(hand);
  219.     else {
  220.         HSetState(hand, state);
  221.         RETVAL = 1;
  222.     }
  223.     OUTPUT:
  224.     RETVAL
  225.  
  226. =item open MODE
  227.  
  228. Open a stream to a handle and return it.
  229.  
  230. =cut
  231.  
  232. SysRet
  233. _open(hand, mode)
  234.     Handle  hand
  235.     int     mode
  236.     CODE:
  237.     RETVAL = OpenHandle(hand, mode);
  238.     OUTPUT:
  239.     RETVAL
  240.     
  241. =item dispose
  242.  
  243. Disposes of the handle.
  244. Return zero if no error was detected.
  245.  
  246. =cut
  247.  
  248. void
  249. dispose(hand)
  250.     Handle  hand
  251.     CODE:
  252.     DisposeHandle(hand);
  253.     CLEANUP:
  254.     MemErrorReturn
  255.  
  256. =back
  257.  
  258. Almost all of the memory management needs in MacPerl can be handled by the above interface
  259.  
  260. =cut
  261.  
  262. MODULE = Mac::Memory    PACKAGE = Ptr
  263. =head2 Ptr
  264.  
  265. Handle provides an object interface to do simple operations on MacOS pointers
  266. (nonrelocatable heap blocks). There are very few good reasons to create pointers
  267. like this.
  268.  
  269. =cut
  270.  
  271. PtrRet
  272. new(package,len)
  273.     SV *    package
  274.     long    len
  275.     CODE:
  276.     RETVAL = NewPtr(len);
  277.     OUTPUT:
  278.     RETVAL
  279.  
  280. =item size
  281.  
  282. Return the size of a pointer (i.e., its data portion).
  283.  
  284.     die unless $ptr->size == 40;
  285.  
  286.  
  287. =cut
  288. long
  289. size(ptr)
  290.     Ptr ptr
  291.     CODE:
  292.     RETVAL = GetPtrSize(ptr);
  293.     OUTPUT:
  294.     RETVAL
  295.  
  296. =item set OFFSET, DATA 
  297.  
  298. =cut
  299. Boolean
  300. set(ptr, offset, data)
  301.     Ptr     ptr
  302.     long        offset
  303.     SV *        data
  304.     CODE:   
  305.     {
  306.         STRLEN  len;
  307.         Ptr     p;
  308.         p = SvPV(data, len);
  309.         BlockMove(p, ptr+offset, len);
  310.         RETVAL = 1;
  311.     }
  312.     OUTPUT:
  313.     RETVAL
  314.  
  315. =item get OFFSET, LENGTH 
  316.  
  317. =item get OFFSET 
  318.  
  319. =item get
  320.  
  321. Return a datum which is the contents of the memory referenced by PTR, 
  322. starting at $OFFSET (default zero), of length $LENGTH (default the rest
  323. of the block).
  324.  
  325.     die unless $ps->get(5, 6) eq "string";
  326.  
  327.  
  328. =cut
  329. SV *
  330. get(ptr, offset=0, length=-1)
  331.     Ptr     ptr
  332.     long        offset
  333.     long        length
  334.     CODE:
  335.     {
  336.         if (length < 0)
  337.             length = GetPtrSize(ptr) - offset;
  338.         RETVAL = newSVpv(ptr+offset, length);
  339.     }
  340.     OUTPUT:
  341.     RETVAL
  342.  
  343. =item address 
  344.  
  345. Return the address of the memory block.
  346.  
  347. =cut
  348.  
  349. RawPtr
  350. address(ptr)
  351.     Ptr     ptr
  352.     CODE:
  353.     RETVAL = ptr;
  354.     OUTPUT:
  355.     RETVAL
  356.  
  357. =item dispose
  358.  
  359. Disposes of the block.
  360. Return zero if no error was detected.
  361.  
  362. =back
  363.  
  364. =cut
  365. void
  366. dispose(ptr)
  367.     Ptr ptr
  368.     CODE:
  369.     DisposePtr(ptr);
  370.     CLEANUP:
  371.     MemErrorReturn
  372.  
  373.  
  374. MODULE = Mac::Memory    PACKAGE = Mac::Memory
  375.  
  376. =head2 Functions
  377.  
  378. =over 4
  379.  
  380. =item GetApplLimit
  381.  
  382. The GetApplLimit function returns the current application heap limit.
  383.  
  384.  
  385. =cut
  386. RawPtr
  387. GetApplLimit()
  388.  
  389. =item TopMem
  390.  
  391. Return a pointer to the top of memory for the application.
  392.  
  393.  
  394.  
  395. =cut
  396. RawPtr
  397. TopMem()
  398.  
  399. =item NewHandle BYTECOUNT
  400.  
  401. =item NewHandleSys BYTECOUNT
  402.  
  403. =item NewHandleClear BYTECOUNT
  404.  
  405. =item NewHandleSysClear BYTECOUNT
  406.  
  407. Return a handle of $BYTECOUNT size.
  408.  
  409. NewHandleSys returns a handle in the system heap.
  410.  
  411. The NewHandleClear and NewHandleSysClear functions work much as the NewHandle
  412. and NewHandleSys functions do but set
  413. all bytes in the new block to 0 instead of leaving the contents of the block
  414. undefined.
  415. Currently, this is quite inefficient.
  416.  
  417.  
  418. =cut
  419. HandleRet
  420. NewHandle(byteCount)
  421.     long    byteCount
  422.  
  423. HandleRet
  424. NewHandleSys(byteCount)
  425.     long    byteCount
  426.  
  427. HandleRet
  428. NewHandleClear(byteCount)
  429.     long    byteCount
  430.  
  431. HandleRet
  432. NewHandleSysClear(byteCount)
  433.     long    byteCount
  434.  
  435. =item NewPtr BYTECOUNT
  436.  
  437. =item NewPtrSys BYTECOUNT
  438.  
  439. =item NewPtrClear BYTECOUNT
  440.  
  441. =item NewPtrSysClear BYTECOUNT
  442.  
  443. Allocate a nonrelocatable block of memory of a specified size.
  444.  
  445. NewPtrSys and NewPtrSysClear allocate blocks in the system heap.
  446.  
  447. NewPtrClear and NewPtrSysClear allocate and zero the blocks (inefficiently).
  448.  
  449.  
  450. =cut
  451. PtrRet
  452. NewPtr(byteCount)
  453.     long    byteCount
  454.     CLEANUP:
  455.     gLastMacOSErr = MemError();
  456.  
  457. PtrRet
  458. NewPtrSys(byteCount)
  459.     long    byteCount
  460.     CLEANUP:
  461.     gLastMacOSErr = MemError();
  462.  
  463. PtrRet
  464. NewPtrClear(byteCount)
  465.     long    byteCount
  466.     CLEANUP:
  467.     gLastMacOSErr = MemError();
  468.  
  469. PtrRet
  470. NewPtrSysClear(byteCount)
  471.     long    byteCount
  472.     CLEANUP:
  473.     gLastMacOSErr = MemError();
  474.  
  475. =item MaxBlock
  476.  
  477. =item MaxBlockSys
  478.  
  479. The MaxBlock function returns the maximum contiguous space, in bytes, that you
  480. could obtain after compacting the current heap zone. MaxBlock does not actually
  481. do the compaction.
  482.  
  483. MaxBlockSys does the same for the system heap.
  484.  
  485.  
  486. =cut
  487. long
  488. MaxBlock()
  489.  
  490. long
  491. MaxBlockSys()
  492.  
  493. =item StackSpace
  494.  
  495. The StackSpace function returns the current amount of stack space (in bytes)
  496. between the current stack pointer and the application heap at the instant of
  497. return from the trap.
  498.  
  499.  
  500. =cut
  501. long
  502. StackSpace()
  503.  
  504. =item NewEmptyHandle
  505.  
  506. =item NewEmptyHandleSys
  507.  
  508. The NewEmptyHandle function initializes a new handle by allocating a master
  509. pointer for it, but it does not allocate any memory for the handle to control.
  510. NewEmptyHandle
  511. sets the handle's master pointer to NIL.
  512.  
  513. NewEmptyHandleSys does the same for the system heap.
  514.  
  515.  
  516. =cut
  517. HandleRet
  518. NewEmptyHandle()
  519.  
  520. HandleRet
  521. NewEmptyHandleSys()
  522.  
  523. =item HLock HANDLE
  524.  
  525. Lock a relocatable block so that it does not move in the heap. If you plan to
  526. dereference a handle and then allocate, move, or purge memory (or call a routine
  527. that does so), then you should lock the handle before using the dereferenced
  528. handle.
  529.  
  530.  
  531. =cut
  532. void
  533. HLock(h)
  534.     Handle  h
  535.     CLEANUP:
  536.     MemErrorReturn
  537.  
  538. =item HUnlock HANDLE
  539.  
  540. Unlock a relocatable block so that it is free to move in its heap zone.
  541.  
  542.  
  543. =cut
  544. void
  545. HUnlock(h)
  546.     Handle  h
  547.     CLEANUP:
  548.     MemErrorReturn
  549.  
  550. =item HPurge HANDLE
  551.  
  552. Mark a relocatable block so that it can be purged if a memory request cannot be
  553. fulfilled after compaction.
  554.  
  555.  
  556. =cut
  557. void
  558. HPurge(h)
  559.     Handle  h
  560.     CLEANUP:
  561.     MemErrorReturn
  562.  
  563. =item HNoPurge HANDLE
  564.  
  565. Mark a relocatable block so that it cannot be purged.
  566.  
  567.  
  568. =cut
  569. void
  570. HNoPurge(h)
  571.     Handle  h
  572.     CLEANUP:
  573.     MemErrorReturn
  574.  
  575. =item HLockHi HANDLE
  576.  
  577. The HLockHi procedure attempts to move the relocatable block referenced by the
  578. handle $HANDLE upward until it reaches a nonrelocatable block, a locked relocatable
  579. block, or the top of the heap. Then HLockHi locks the block.
  580.  
  581.  
  582. =cut
  583. void
  584. HLockHi(h)
  585.     Handle  h
  586.     CLEANUP:
  587.     MemErrorReturn
  588.  
  589. =item TempNewHandle BYTECOUNT
  590.  
  591. The TempNewHandle function returns a handle to a block of size $BYTECOUNT from
  592. temporary memory. If it
  593. cannot allocate a block of that size, the function returns NIL.
  594.  
  595.  
  596. =cut
  597. Handle
  598. TempNewHandle(logicalSize)
  599.     long    logicalSize
  600.     CODE:
  601.     {
  602.         RETVAL = TempNewHandle(logicalSize, &gLastMacOSErr);
  603.         if (gLastMacOSErr) {
  604.             XSRETURN_UNDEF;
  605.         }
  606.     }
  607.     OUTPUT:
  608.     RETVAL
  609.  
  610. =item TempMaxMem
  611.  
  612. The TempMaxMem function compacts the current heap zone and returns the size of
  613. the largest contiguous block available for temporary allocation.
  614.  
  615.     $SIZE = &TempMaxMem;
  616.  
  617.  
  618. =cut
  619. long
  620. TempMaxMem()
  621.     CODE:
  622.     {
  623.         long    grow;
  624.         RETVAL = TempMaxMem(&grow);
  625.     }
  626.     OUTPUT:
  627.     RETVAL
  628.  
  629. =item TempFreeMem
  630.  
  631. The TempFreeMem function returns the total amount of free temporary memory that
  632. you could allocate by calling TempNewHandle. The returned value is the total
  633. number of free bytes. Because these bytes might be dispersed throughout memory,
  634. it is ordinarily not possible to allocate a single relocatable block of that
  635. size.
  636.  
  637.     $SIZE = &TempFreeMem;
  638.  
  639.  
  640. =cut
  641. long
  642. TempFreeMem()
  643.  
  644. =item CompactMem BYTECOUNT
  645.  
  646. =item CompactMemSys BYTECOUNT
  647.  
  648. The CompactMem function compacts the current heap zone by moving unlocked,
  649. relocatable blocks down until they encounter nonrelocatable blocks or locked,
  650. relocatable blocks, but not by purging blocks. It continues compacting until it
  651. either finds a contiguous block of at least $BYTECOUNT free bytes or has compacted
  652. the entire zone.
  653.  
  654. The CompactMem function returns the size, in bytes, of the largest contiguous
  655. free block for which it could make room, but it does not actually allocate that
  656. block.
  657.  
  658. CompactMemSys does the same for the system heap.
  659.  
  660.  
  661. =cut
  662. long
  663. CompactMem(cbNeeded)
  664.     long    cbNeeded
  665.  
  666. long
  667. CompactMemSys(cbNeeded)
  668.     long    cbNeeded
  669.  
  670. =item PurgeMem BYTECOUNT
  671.  
  672. =item PurgeMemSys BYTECOUNT
  673.  
  674. The PurgeMem procedure sequentially purges blocks from the current heap zone
  675. until it either allocates a contiguous block of at least $BYTECOUNT free bytes or
  676. has purged the entire zone. If it purges the entire zone without creating a
  677. contiguous block of at least $BYTECOUNT free bytes, PurgeMem generates a
  678. memFullErr.
  679.  
  680. The PurgeMem procedure purges only relocatable, unlocked, purgeable blocks.
  681.  
  682. The PurgeMem procedure does not actually attempt to allocate a block of  $BYTECOUNT
  683. bytes.
  684.  
  685. PurgeMemSys does the same for the system heap.
  686.  
  687.  
  688. =cut
  689. void
  690. PurgeMem(cbNeeded)
  691.     long    cbNeeded
  692.  
  693. void
  694. PurgeMemSys(cbNeeded)
  695.     long    cbNeeded
  696.  
  697. =item FreeMem
  698.  
  699. =item FreeMemSys
  700.  
  701. The FreeMem function returns the total amount of free space (in bytes) in the
  702. current heap zone. Note that it usually isn't possible to allocate a block of
  703. that size, because of heap fragmentation due to nonrelocatable or locked blocks.
  704.  
  705. FreeMemSys does the same for the system heap.
  706.  
  707.  
  708. =cut
  709. long
  710. FreeMem()
  711.  
  712. long
  713. FreeMemSys()
  714.  
  715. =item ReserveMem BYTECOUNT
  716.  
  717. =item ReserveMemSys BYTECOUNT
  718.  
  719. The ReserveMem procedure attempts to create free space for a block of $BYTECOUNT
  720. contiguous logical bytes at the lowest possible position in the current heap
  721. zone. It pursues every available means of placing the block as close as possible
  722. to the bottom of the zone, including moving other relocatable blocks upward,
  723. expanding the zone (if possible), and purging blocks from it. 
  724.  
  725. ReserveMemSys does the same for the system heap.
  726.  
  727.  
  728. =cut
  729. void
  730. ReserveMem(cbNeeded)
  731.     long    cbNeeded
  732.  
  733. void
  734. ReserveMemSys(cbNeeded)
  735.     long    cbNeeded
  736.  
  737. =item MaxMem
  738.  
  739. =item MaxMemSys
  740.  
  741. Use the MaxMem function to compact and purge the current heap zone. The values
  742. returned are the amount of memory available and the amount by which the zone can
  743. grow.
  744.  
  745.     ($SIZE, $GROW) = &MaxMem;
  746.  
  747. MaxMemSys does the purge and compact of the system heap zone, and the $GROW value
  748. is set to zero.
  749.  
  750.  
  751. =cut
  752. void
  753. MaxMem()
  754.     PPCODE:
  755.     {
  756.         long    grow;
  757.         
  758.         XS_PUSH(long, MaxMem(&grow));
  759.         if (GIMME == G_ARRAY) {
  760.             XS_PUSH(long, grow);
  761.         }
  762.     }
  763.  
  764. void
  765. MaxMemSys()
  766.     PPCODE:
  767.     {
  768.         long    grow;
  769.         
  770.         XS_PUSH(long, MaxMemSys(&grow));
  771.         if (GIMME == G_ARRAY) {
  772.             XS_PUSH(long, grow);
  773.         }
  774.     }
  775.  
  776. =item MoveHHi HANDLE
  777.  
  778. The MoveHHi procedure attempts to move the relocatable block referenced by the
  779. handle $HANDLE upward until it reaches a nonrelocatable block, a locked relocatable
  780. block, or the top of the heap.
  781.  
  782.  
  783. =cut
  784. void
  785. MoveHHi(h)
  786.     Handle  h
  787.     CLEANUP:
  788.     MemErrorReturn
  789.  
  790. =item DisposePtr PTR
  791.  
  792. Releases the memory occupied by the nonrelocatable block specified by $PTR.
  793.  
  794.  
  795. =cut
  796. void
  797. DisposePtr(p)
  798.     Ptr p
  799.     CLEANUP:
  800.     MemErrorReturn
  801.  
  802. =item GetPtrSize PTR
  803.  
  804. The GetPtrSize function returns the logical size, in bytes, of the nonrelocatable
  805. block pointed to by $PTR.
  806.  
  807.  
  808. =cut
  809. long
  810. GetPtrSize(p)
  811.     Ptr p
  812.     CLEANUP:
  813.     gLastMacOSErr = MemError();
  814.  
  815. =item SetPtrSize PTR, NEWSIZE
  816.  
  817. The SetPtrSize procedure attempts to change the logical size of the
  818. nonrelocatable block pointed to by $PTR. The new logical size is specified by
  819. $NEWSIZE.
  820. Return zero if no error was detected.
  821.  
  822.  
  823. =cut
  824. void
  825. SetPtrSize(p, newSize)
  826.     Ptr p
  827.     long    newSize
  828.     CLEANUP:
  829.     MemErrorReturn
  830.  
  831. =item DisposeHandle HANDLE
  832.  
  833. The DisposeHandle procedure releases the memory occupied by the relocatable block
  834. whose handle is $HANDLE. It also frees the handle's master pointer for other uses.
  835.  
  836.  
  837. =cut
  838. void
  839. DisposeHandle(h)
  840.     Handle  h
  841.     CLEANUP:
  842.     MemErrorReturn
  843.  
  844. =item SetHandleSize HANDLE, BYTECOUNT
  845.  
  846. The SetHandleSize procedure attempts to change the logical size of the
  847. relocatable block whose handle is $HANDLE. The new logical size is specified by
  848. $BYTECOUNT.
  849. Return zero if no error was detected.
  850.  
  851.  
  852. =cut
  853. void
  854. SetHandleSize(h, newSize)
  855.     Handle  h
  856.     long        newSize
  857.     CLEANUP:
  858.     MemErrorReturn
  859.  
  860. =item GetHandleSize HANDLE
  861.  
  862. The GetHandleSize function returns the logical size, in bytes, of the relocatable
  863. block whose handle is $HANDLE. In case of an error, GetHandleSize returns 0.
  864.  
  865.  
  866. =cut
  867. long
  868. GetHandleSize(h)
  869.     Handle  h
  870.  
  871. =item ReallocateHandle HANDLE, BYTECOUNT
  872.  
  873. Allocates a new relocatable block with a logical size of $BYTECOUNT bytes. It
  874. updates the handle $HANDLE by setting its master pointer to point to the new block. 
  875. The new block is unlocked and unpurgeable.
  876. Return zero if no error was detected.
  877.  
  878.  
  879. =cut
  880. void
  881. ReallocateHandle(h, byteCount)
  882.     Handle  h
  883.     long        byteCount
  884.     CLEANUP:
  885.     MemErrorReturn
  886.  
  887. =item EmptyHandle
  888.  
  889. Free memory taken by a relocatable block without freeing the relocatable block's
  890. master pointer for other uses.
  891.  
  892.  
  893. =cut
  894. void
  895. EmptyHandle(h)
  896.     Handle  h
  897.     CLEANUP:
  898.     MemErrorReturn
  899.  
  900. =item MoreMasters
  901.  
  902. Call the MoreMasters procedure several times at the beginning of your program to
  903. prevent the Memory Manager from running out of master pointers in the middle of
  904. application execution. If it does run out, it allocates more, possibly causing
  905. heap fragmentation.
  906.  
  907.  
  908. =cut
  909. void
  910. MoreMasters()
  911.     CLEANUP:
  912.     MemErrorReturn
  913.  
  914. =item BlockMove SOURCEPTR, DESTPTR, BYTECOUNT
  915.  
  916. =item BlockMoveData SOURCEPTR, DESTPTR, BYTECOUNT
  917.  
  918. The BlockMove/BlockMoveData procedure moves a block of $BYTECOUNT consecutive bytes from the
  919. address designated by $SOURCEPTR to that designated by $DESTPTR.
  920.  
  921.  
  922. =cut
  923. void
  924. BlockMove(srcPtr, destPtr, byteCount)
  925.     RawPtr  srcPtr
  926.     RawPtr  destPtr
  927.     long    byteCount
  928.  
  929. void
  930. BlockMoveData(srcPtr, destPtr, byteCount)
  931.     RawPtr  srcPtr
  932.     RawPtr  destPtr
  933.     long    byteCount
  934.  
  935. =item PurgeSpace
  936.  
  937. Determine the total amount of free memory and the size of the largest allocatable
  938. block after a purge of the heap.
  939.  
  940.     ($Total, $Contiguous) = &PurgeSpace;
  941.  
  942.  
  943. =cut
  944. void
  945. PurgeSpace()
  946.     PPCODE:
  947.     {
  948.         long    total;
  949.         long    contig;
  950.     
  951.         PurgeSpace(&total, &contig);
  952.         EXTEND(sp, 2);
  953.         PUSHs(sv_2mortal(newSViv(total)));
  954.         PUSHs(sv_2mortal(newSViv(contig)));
  955.     }   
  956.  
  957. =item HGetState HANDLE
  958.  
  959. Get the current properties of a relocatable block (perhaps so that you can change
  960. and then later restore those properties).
  961.  
  962.  
  963. =cut
  964. char
  965. HGetState(h)
  966.     Handle  h
  967.     CLEANUP:
  968.     if (gLastMacOSErr = MemError())
  969.         RETVAL = 0;
  970.  
  971. =item HSetState HANDLE, STATE
  972.  
  973. Restore properties of a block after a call to HGetState.
  974.  
  975.  
  976. =cut
  977. void
  978. HSetState(h, flags)
  979.     Handle  h
  980.     char        flags
  981.     CLEANUP:
  982.     MemErrorReturn
  983.  
  984. =item HandToHand HANDLE
  985.  
  986. The HandToHand function attempts to copy the information in the relocatable block
  987. to which $HANDLE is a handle.
  988. Return C<undef> if an error was detected.
  989.  
  990.  
  991. =cut
  992. Handle
  993. HandToHand(theHndl)
  994.     Handle  &theHndl
  995.     CODE:
  996.     if (gLastMacOSErr = HandToHand(&theHndl)) {
  997.         XSRETURN_UNDEF;
  998.     } else {
  999.         RETVAL = theHndl;
  1000.     }
  1001.     OUTPUT:
  1002.     RETVAL
  1003.  
  1004. =item PtrToHand PTR, BYTECOUNT
  1005.  
  1006. The PtrToHand function returns a newly created handle to a copy of
  1007. the number of bytes specified by $BYTECOUNT, beginning at the location
  1008. specified by $PTR.
  1009. Return C<undef> if an error was detected.
  1010.  
  1011.  
  1012. =cut
  1013. Handle
  1014. PtrToHand(srcPtr, size)
  1015.     Ptr     srcPtr
  1016.     long        size
  1017.     CODE:
  1018.     if (gLastMacOSErr = PtrToHand(srcPtr, &RETVAL, size)) {
  1019.         XSRETURN_UNDEF;
  1020.     }
  1021.     OUTPUT:
  1022.     RETVAL
  1023.  
  1024. =item PtrToXHand HANDLE, PTR, BYTECOUNT
  1025.  
  1026. The PtrToXHand function makes the existing handle, specified by $HANDLE, a handle
  1027. to a copy of the number of bytes specified by $BYTECOUNT, beginning at
  1028. the location specified by $PTR.
  1029. Return C<undef> if an error was detected.
  1030.  
  1031.  
  1032. =cut
  1033. MacOSRet
  1034. PtrToXHand(srcPtr, dstHndl, size)
  1035.     Ptr     srcPtr
  1036.     Handle  dstHndl
  1037.     long        size
  1038.  
  1039. =item HandAndHand AHNDLE, BHNDLE
  1040.  
  1041. The HandAndHand function concatenates the information from the relocatable block
  1042. to which $AHNDL is a handle onto the end of the relocatable block to which $BHNDL
  1043. is a handle. The $AHNDL variable remains unchanged.
  1044. Return zero if no error was detected.
  1045.  
  1046.  
  1047. =cut
  1048. MacOSRet
  1049. HandAndHand(hand1, hand2)
  1050.     Handle  hand1
  1051.     Handle  hand2
  1052.     CODE:
  1053.     {
  1054.         char    state = HGetState(hand1);
  1055.         HLock(hand1);
  1056.         RETVAL = HandAndHand(hand1, hand2);
  1057.         HSetState(hand1, state);
  1058.     }
  1059.     OUTPUT:
  1060.     RETVAL
  1061.  
  1062. =item PtrAndHand PTR, HANDLE, BYTECOUNT
  1063.  
  1064. The PtrAndHand function takes the number of bytes specified by $BYTECOUNT, 
  1065. beginning at the location specified by $PTR, and concatenates them
  1066. onto the end of the relocatable block to which $HANDLE is a handle.
  1067.  
  1068.  
  1069. =cut
  1070. MacOSRet
  1071. PtrAndHand(ptr1, hand2, size)
  1072.     Ptr     ptr1
  1073.     Handle  hand2
  1074.     long        size
  1075.  
  1076. =back
  1077.  
  1078. =cut
  1079.