home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / NSL 1.1 SDK / Sample Code / SamplePlugin.cp < prev    next >
Encoding:
Text File  |  1999-10-12  |  8.6 KB  |  316 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        SamplePlugin.cp
  3.  
  4.     Contains:    Interface between NSL Manager and an extremely simple plugin.
  5.  
  6.     Written by:    Kevin Arnold
  7.  
  8.     Copyright:    ©1998 - 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     <13>    07/07/99    sns        no longer use MemMgr.h; cleanup
  13.     <12>    06/14/99    KA        no longer use NSLUtility.h
  14.     <11>    05/18/99    KA        fixed small mem leak
  15.     <10>    04/29/99    KA        make local copies of search data
  16.     <09>    04/14/99    KA        converting to UPP callbacks to manager
  17.     <08>    03/24/99    KA        converting to new headers
  18.     <07>    03/22/99    KA        converting to new data type names (ie NSLXXX)
  19.     <06>    03/11/99    KA        oops, we weren't closing our resource fork after doing a lookup
  20.     <05>    02/23/99    KA        took out call to GetPluginInfo as that is no longer called in 1.1 (NSLI resource)
  21.     <04>    01/12/99    KA        using new parsing calls
  22.     <03>    12/16/98    KA        added code to use the NSL PluginResource Info stuff
  23.     <02>    11/02/98    KA        added some more neighborhoodlookup code and fixed the plugin info stuff
  24.     <01>    10/12/98    KA        initial checkin
  25.     <00>    10/09/98    KA        created
  26.  
  27. */
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <Threads.h>
  31.  
  32. #include "NSL.h"
  33. #include "NSLPluginModule.h"
  34.  
  35. static Boolean            gsPluginInitialized = false;
  36. static NSLPluginDataPtr    gPluginInfoPtr = NULL;
  37.  
  38. #define kDefaultNeighborhood    "Test Neighborhood"
  39. #define kTestURLStringsID        128
  40.  
  41. // shared lib init routine
  42. extern "C" OSStatus __initialize( CFragInitBlockPtr initBlock );
  43.  
  44. // our library init routine
  45. extern "C" OSStatus Initialize( CFragInitBlockPtr initBlock );
  46.  
  47. // internal prototype
  48. OSStatus DoLookupOnService( char* service, NSLNeighborhood neighborhood, NSLMgrNotifyUPP notifier, NSLPluginAsyncInfoPtr pluginInfo );
  49.  
  50. /********
  51.  * Init *
  52.  ********
  53.  
  54.  The library init routine that gets called when this library is loaded.  Its primary function is
  55.  to grab and remember the FSSpec so we can find our resource fork later.
  56.  
  57. */
  58. static FSSpec            sSLPLibSpec;
  59. static FSSpec*            sLibSpecPtr = NULL;
  60.  
  61. OSStatus Initialize( CFragInitBlockPtr initBlock )
  62. {
  63.  
  64.     OSStatus    initStatus=noErr;
  65.     
  66.     initStatus = __initialize( initBlock );            // the CW init routine - we must call!!!    // KA 7/15/98
  67.     
  68.     if ( !initStatus && !sLibSpecPtr )            // only call us once
  69.     {
  70.         sLibSpecPtr = &sSLPLibSpec;
  71.         sSLPLibSpec = *(initBlock->fragLocator.u.onDisk.fileSpec);
  72.         gsPluginInitialized = true;
  73.     }    
  74.     
  75.     return initStatus;
  76.     
  77. }
  78.  
  79. #pragma export on
  80. OSStatus InitPlugin( void )
  81. {
  82.     OSStatus status = noErr;
  83.     
  84.     // do any intialization code here.  This will be called once per instance
  85.     
  86.     return status;
  87. }
  88.  
  89. OSStatus KillPlugin( Boolean forceQuit )
  90. {
  91.     OSStatus status = noErr;
  92.     
  93.     // do any clean up here as this instance of the plugin will be unloaded shortly
  94.     
  95.     return status;
  96. }
  97.  
  98. OSStatus Register( NSLTypedDataPtr dataPtr )
  99. {
  100.     OSStatus        status = noErr;
  101.  
  102.     return status;
  103. }        
  104.  
  105. OSStatus Deregister( NSLTypedDataPtr dataPtr )
  106. {
  107.     return noErr;
  108. }
  109.  
  110. OSStatus StartNeighborhoodLookup( NSLNeighborhood neighborhood, NSLMgrNotifyUPP notifier, NSLPluginAsyncInfoPtr pluginInfo )
  111. {
  112.     OSStatus            status = noErr;
  113.     char*                nPtr = NULL;
  114.     long                nLength;
  115.     
  116.     if ( neighborhood && notifier && pluginInfo )
  117.     {
  118.         // we want to do our lookup here.  This can be a seperately created thread or have
  119.         // some async behavior with our own async callback routines.  For this example we
  120.         // are just performing sync.
  121.         
  122.         // for the sample we will just notify the manager with a bogus Neighborhood
  123.         // if the neighborhood name is empty.  If not, then just append a dash and a number
  124.         
  125.         NSLGetNameFromNeighborhood( neighborhood, &nPtr, &nLength );
  126.         
  127.         if ( nPtr && *nPtr == '\0' )
  128.         {
  129.             pluginInfo->searchState = kNSLSearchStateOnGoing;
  130.             pluginInfo->searchResult = status;
  131.             pluginInfo->resultBuffer = kDefaultNeighborhood; 
  132.             pluginInfo->bufferLen = strlen( pluginInfo->resultBuffer )+1;
  133.             InvokeNSLMgrNotifyUPP( pluginInfo, notifier );
  134.         }
  135.         else if ( nPtr == NULL )
  136.         {
  137.             status = memFullErr;
  138.         }
  139.         else
  140.         {
  141.             char*    tempBuf = ::NewPtr( nLength + 2 );
  142.             
  143.             pluginInfo->searchState = kNSLSearchStateOnGoing;
  144.             pluginInfo->searchResult = status;
  145.             pluginInfo->resultBuffer =  tempBuf;
  146.             ::strcpy( pluginInfo->resultBuffer, nPtr );
  147.             ::strcat( pluginInfo->resultBuffer, "-1" );
  148.             pluginInfo->bufferLen = nLength + 2;
  149.             InvokeNSLMgrNotifyUPP( pluginInfo, notifier );
  150.  
  151.             pluginInfo->searchState = kNSLSearchStateOnGoing;
  152.             pluginInfo->searchResult = status;
  153.             pluginInfo->resultBuffer = tempBuf; 
  154.             ::strcpy( pluginInfo->resultBuffer, nPtr );
  155.             ::strcat( pluginInfo->resultBuffer, "-2" );
  156.             pluginInfo->bufferLen = nLength + 2;
  157.             InvokeNSLMgrNotifyUPP( pluginInfo, notifier );
  158.         
  159.             ::DisposePtr( tempBuf );
  160.         }
  161.         
  162.         
  163.         pluginInfo->searchState = kNSLSearchStateComplete;
  164.         pluginInfo->searchResult = status;
  165.         pluginInfo->resultBuffer = NULL; 
  166.         pluginInfo->bufferLen = 0;
  167.         InvokeNSLMgrNotifyUPP( pluginInfo, notifier );
  168.     
  169.         if ( nPtr )
  170.             ::DisposePtr( nPtr );
  171.     }
  172.     else
  173.         status = kNSLErrNullPtrError;
  174.         
  175.     return status;
  176. }
  177.  
  178. OSStatus StartServicesLookup( NSLNeighborhood neighborhood, NSLTypedDataPtr dataPtr, NSLMgrNotifyUPP notifier, NSLPluginAsyncInfoPtr pluginInfo )
  179. {
  180.     OSStatus             status = noErr;
  181.     char                service[256];
  182.     char*                serviceListPtr;
  183.     char*                localServiceListCopy;
  184.     NSLNeighborhood        localNeighborhoodCopy;
  185.     UInt16                listLen;
  186.     char*                curPtr;
  187.     
  188.     if ( neighborhood && dataPtr && notifier && pluginInfo )
  189.     {
  190.         status = NSLParseServicesRequestPB(    dataPtr, 
  191.                                             &serviceListPtr, 
  192.                                             &listLen);
  193.         
  194.         localNeighborhoodCopy = NSLCopyNeighborhood( neighborhood );
  195.         localServiceListCopy = ::NewPtr( listLen );
  196.         ::BlockMove( serviceListPtr, localServiceListCopy, listLen );        // can't guarantee that dataPtr data will still be around after notification to the manager
  197.         
  198.         curPtr = localServiceListCopy;    
  199.         UInt32 numSvcs = ( (NSLServicesListHeaderPtr) serviceListPtr)->numServices;
  200.                                     
  201.         curPtr += sizeof(NSLServicesListHeader) ;    // we are now pointing at the first services which is a pascal style string
  202.         
  203.         for ( UInt32 i=1; i <= numSvcs && status == noErr; i++ )
  204.         {
  205.             memcpy( service, curPtr, curPtr[0]+1 );
  206.             p2cstr( (unsigned char*)service );            // convert to cstring
  207.             
  208.             status = DoLookupOnService( service, localNeighborhoodCopy, notifier, pluginInfo );    // this will handle a search
  209.             
  210.             curPtr += curPtr[0]+1;    // advance to the next service
  211.         }
  212.         
  213.         // since we are handling these lookups in a sync fashion, we know that we are done when we get here...
  214.         
  215.         pluginInfo->searchState = kNSLSearchStateComplete;
  216.         pluginInfo->searchResult = status;
  217.         pluginInfo->resultBuffer = NULL; 
  218.         pluginInfo->bufferLen = 0;
  219.         InvokeNSLMgrNotifyUPP( pluginInfo, notifier );
  220.     
  221.         ::DisposePtr( localServiceListCopy );
  222.         NSLFreeNeighborhood( localNeighborhoodCopy );
  223.     }
  224.     else
  225.         status = kNSLErrNullPtrError;
  226.         
  227.     return status;
  228. }
  229.  
  230. OSStatus ContinueLookup( NSLMgrNotifyUPP notifier, NSLPluginAsyncInfoPtr pluginInfo )
  231. {
  232.     OSStatus            status = noErr;
  233.     
  234.     return status;
  235. }
  236.  
  237. OSStatus CancelLookup( NSLPluginAsyncInfoPtr pluginInfo )
  238. {
  239.     OSStatus            status = noErr;
  240.     
  241.     return status;
  242. }
  243.  
  244. OSStatus ErrNumToString( OSStatus theErr, char* errorString, char* solutionString )
  245. {
  246.     OSStatus    status = noErr;
  247.     
  248.     return status;
  249. }
  250. #pragma export off
  251.  
  252.  
  253. OSStatus DoLookupOnService( char* service, NSLNeighborhood neighborhood, NSLMgrNotifyUPP notifier, NSLPluginAsyncInfoPtr pluginInfo )
  254. {
  255.     OSStatus    status = noErr;
  256.     char*        nPtr = NULL;
  257.     long        nLength;
  258.  
  259.     NSLGetNameFromNeighborhood( neighborhood, &nPtr, &nLength );
  260.     
  261.     if ( !status && nPtr && strcmp( nPtr, kDefaultNeighborhood ) == 0 )
  262.     {
  263.         Str255        url;
  264.         short         pluginRefNum, index = 1;
  265.         Boolean        done = false;
  266.         
  267.         // we are going to get our results from a resource for easy testing
  268.         
  269.         pluginRefNum = ::FSpOpenResFile( sLibSpecPtr, fsCurPerm );
  270.         
  271.         if ( pluginRefNum != -1 )
  272.         {
  273.             while ( !done )
  274.             {
  275.                 YieldToAnyThread();                // in case we are in a multithread aware situation
  276.                 SystemTask();                    // be friendly to other tasks...
  277.                 
  278.                 ::GetIndString( url, kTestURLStringsID, index++ );
  279.             
  280.                 if ( url[0] > 0 )
  281.                 {
  282.                     p2cstr( url );        // convert to c-style string
  283.                     
  284.                     long serviceLenOfURL = strstr( (char*)url, ":/" ) - (char*)url;
  285.                     long serviceLenOfService = strlen(service);
  286.                     
  287.                     if ( memcmp( service, url, serviceLenOfService ) == 0 && ( serviceLenOfURL == serviceLenOfService ))
  288.                     {
  289.                         pluginInfo->searchState = kNSLSearchStateOnGoing;
  290.                         pluginInfo->searchResult = status;
  291.                         pluginInfo->resultBuffer = (char*)url; 
  292.                         pluginInfo->bufferLen = strlen( pluginInfo->resultBuffer )+1;
  293.                         InvokeNSLMgrNotifyUPP( pluginInfo, notifier );
  294.                     }
  295.                 }
  296.                 else
  297.                     done = true;
  298.             }
  299.         
  300.             ::CloseResFile( pluginRefNum );
  301.         }
  302.         else
  303.             status = resNotFound;
  304.     }
  305.     else if ( nPtr == NULL )
  306.     {
  307.         status = memFullErr;
  308.     }
  309.     
  310.     if ( nPtr )
  311.         ::DisposePtr( nPtr );
  312.     
  313.     return status;    
  314. }
  315.  
  316.