home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / rpc / pickle / picklp / picklpc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-11  |  13.3 KB  |  451 lines

  1. /****************************************************************************
  2.                    Microsoft RPC Version 2.0
  3.            Copyright Microsoft Corp. 1992, 1993, 1994- 1996
  4.                       picklp Example
  5.  
  6.     FILE:       picklpc.c
  7.  
  8.     USAGE:      picklpc  -f filename  (file to write to/read from)
  9.                          -d           (serialization direction: decode)
  10.                          -e           (serialization direction: encode)
  11.                          -i           (incremental serialization on)
  12.  
  13.     PURPOSE:    The only side of RPC application
  14.  
  15.     FUNCTIONS:  main() - serializes data to or from a file
  16.  
  17.     COMMENTS:   Data procedure serialization is demonstrated here
  18.  
  19. ****************************************************************************/
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include "picklp.h"    // header file generated by MIDL compiler
  24.  
  25. #define PURPOSE \
  26. "This Microsoft RPC Version 2.0 sample program demonstrates\n\
  27. the use of the [encode,decode] attributes. For more information\n\
  28. about the attributes and RPC API functions, see the RPC programming\n\
  29. guide and reference.\n\n"
  30.  
  31. /*  Used for incremental style only. */
  32.  
  33. void __RPC_USER PicAlloc( void * pState, char ** ppBuf, unsigned int * pCount);
  34. void __RPC_USER PicWrite( void * pState, char *  pBuf,  unsigned int Count);
  35. void __RPC_USER PicRead ( void * pState, char ** pBuf,  unsigned int * pCount);
  36.  
  37. typedef struct PickleControlBlock
  38. {
  39.     unsigned char *         pMemBuffer;
  40.     unsigned char *         pBufferStart;
  41.     unsigned long           LastSize;
  42. } PickleControlBlock;
  43.  
  44. static PickleControlBlock                 UserState;
  45. static PickleControlBlock * pUserState = &UserState;
  46.  
  47. void Usage(char * pszProgramName)
  48. {
  49.     fprintf(stderr, "%s", PURPOSE);
  50.     fprintf(stderr, "Usage:  %s\n", pszProgramName);
  51.     fprintf(stderr, " -d\n");
  52.     fprintf(stderr, " -e\n");
  53.     fprintf(stderr, " -ffilename\n");
  54.     fprintf(stderr, " -i \n");
  55.     exit(1);
  56. }
  57.  
  58. void DumpData(
  59.     char * pszComment,
  60.     char * pszText,
  61.     OBJECT1 * pObject1,
  62.     OBJECT2 * pObject2 )
  63. {
  64.     int i;
  65.  
  66.     printf( "\n%s\n", pszComment );
  67.     printf( "\tString\n\t\t%s\n", pszText );
  68.  
  69.     printf( "\tObject1");
  70.     for (i=0; i < ARR_SIZE; i++)
  71.         {
  72.         if ( (i % 5) == 0 )
  73.             printf( "\n\t\t");
  74.         printf( "%08xl  ", pObject1->al[i] );
  75.         }
  76.     printf( "\n\t\t%x\n", pObject1->s );
  77.  
  78.     printf( "\tObject2");
  79.     printf( "\n\t\t%x", pObject2->sSize );
  80.     for (i=0; i < ARR_SIZE; i++)
  81.         {
  82.         if ( (i % 10) == 0 )
  83.             printf( "\n\t\t");
  84.         printf( "%04x  ", pObject2->as[i] );
  85.         }
  86.     printf( "\n" );
  87. }
  88.  
  89. void WriteDataToFile(
  90.     char *          pszFileName,
  91.     char *          pbBuffer,
  92.     unsigned long   ulSizeToWrite )
  93. {
  94.     FILE *      pFile;
  95.     size_t      Count;
  96.  
  97.     if ( pszFileName ) {
  98.  
  99.         pFile = fopen( pszFileName, "w+b" );
  100.         if ( pFile == NULL ) {
  101.             printf("Cannot open the file for writing\n");
  102.             exit(1);
  103.             }
  104.  
  105.         Count = sizeof(long);
  106.         if ( fwrite( &ulSizeToWrite, sizeof(byte), Count, pFile) != Count ) {
  107.             printf("Cannot write1 to the file\n");
  108.             exit(1);
  109.             }
  110.  
  111.         Count = (size_t) ulSizeToWrite;
  112.         if ( fwrite( pbBuffer, sizeof(byte), Count, pFile) != Count ) {
  113.             printf("Cannot write2 to the file\n");
  114.             exit(1);
  115.             }
  116.  
  117.         if ( fclose( pFile ) != 0) {
  118.             printf("Failed to close the file\n");
  119.             exit(1);
  120.             }
  121.         }
  122. }
  123.  
  124. void ReadDataFromFile(
  125.     char *          pszFileName,
  126.     char *          pbBuffer,
  127.     unsigned long   ulBufferSize )
  128. {
  129.     FILE *          pFile;
  130.     size_t          Count;
  131.     unsigned long   ulWrittenSize;
  132.  
  133.  
  134.     if ( pszFileName ) {
  135.  
  136.         pFile = fopen( pszFileName, "r+b" );
  137.         if ( pFile == NULL ) {
  138.             printf("Cannot open the file for reading\n");
  139.             exit(1);
  140.             }
  141.  
  142.         Count = sizeof(long);
  143.         if ( fread( &ulWrittenSize, sizeof(byte), Count, pFile) != Count ) {
  144.             printf("Cannot read1 from the file\n");
  145.             exit(1);
  146.             }
  147.  
  148.         Count = (size_t)ulWrittenSize;
  149.         if ( fread( pbBuffer, sizeof(byte), Count, pFile) != Count ) {
  150.             printf("Cannot read2 from the file\n");
  151.             exit(1);
  152.             }
  153.  
  154.         if ( fclose( pFile ) != 0) {
  155.             printf("Failed to close the file\n");
  156.             exit(1);
  157.             }
  158.         }
  159. }
  160.  
  161. void _CRTAPI1 main(int argc, char **argv)
  162. {
  163.     RPC_STATUS status;
  164.  
  165.     unsigned char * pbPicklingBuffer = NULL;
  166.  
  167.     char * pszStyle      = NULL;
  168.     char * pszFileName   = "pickle.dat";
  169.     int i;
  170.     int fEncode = 1;
  171.     int fFixedStyle = 1;
  172.  
  173.     /* allow the user to override settings with command line switches */
  174.     for (i = 1; i < argc; i++) {
  175.         if ((*argv[i] == '-') || (*argv[i] == '/')) {
  176.             switch (tolower(*(argv[i]+1))) {
  177.             case 'd':
  178.                 fEncode = 0;
  179.                 break;
  180.             case 'e':
  181.                 fEncode = 1;
  182.                 break;
  183.             case 'i':
  184.                 fFixedStyle = 0;
  185.                 break;
  186.             case 'f':
  187.                 pszFileName = argv[i] + 2;
  188.                 break;
  189.             case 'h':
  190.             case '?':
  191.             default:
  192.                 Usage(argv[0]);
  193.             }
  194.         }
  195.         else
  196.             Usage(argv[0]);
  197.     }
  198.  
  199.     /* Fixed buffer style: the buffer should be big enough.  */
  200.     /* Please note that the buffer has to be aligned at 8.   */
  201.  
  202.     pbPicklingBuffer = (unsigned char *)
  203.             midl_user_allocate( BUFSIZE * sizeof(unsigned char));
  204.  
  205.     if ( pbPicklingBuffer == NULL ) {
  206.         printf("Cannot allocate the pickling buffer\n");
  207.         exit(1);
  208.         }
  209.     else
  210.         memset( pbPicklingBuffer, 0xdd, BUFSIZE );
  211.  
  212.     /*
  213.         Set the pickling handle that will be used for data serialization.
  214.         The global ImplicitPicHandle is used, but it has to be set up.
  215.     */
  216.  
  217.     if ( fEncode ) {
  218.  
  219.         unsigned char * pszNameId;
  220.         OBJECT1         Object1;
  221.         OBJECT2   *     pObject2;
  222.         unsigned long   ulEncodedSize = 0;
  223.  
  224.         printf("\nEncoding run: use -d for decoding\n\n");
  225.  
  226.         if ( fFixedStyle ) {
  227.  
  228.             printf("Creating a fixed buffer encoding handle\n");
  229.             status = MesEncodeFixedBufferHandleCreate( pbPicklingBuffer,
  230.                                                        BUFSIZE,
  231.                                                        & ulEncodedSize,
  232.                                                        & ImplicitPicHandle );
  233.             printf("MesEncodeFixedBufferHandleCreate returned 0x%x\n", status);
  234.             if (status) {
  235.                 exit(status);
  236.             }
  237.         }
  238.         else {
  239.  
  240.             pUserState->LastSize = 0;
  241.             pUserState->pMemBuffer = (char *)pbPicklingBuffer;
  242.             pUserState->pBufferStart = (char *)pbPicklingBuffer;
  243.  
  244.             printf("Creating an incremental encoding handle\n");
  245.             status = MesEncodeIncrementalHandleCreate( pUserState,
  246.                                                        PicAlloc,
  247.                                                        PicWrite,
  248.                                                        & ImplicitPicHandle );
  249.             printf("MesEncodeIncrementalHandleCreate returned 0x%x\n", status);
  250.             if (status) {
  251.                 exit(status);
  252.             }
  253.         }
  254.  
  255.         /* Creating objects to manipulate */
  256.  
  257.         pszNameId = "Procedure pickling sample";
  258.  
  259.         for (i = 0; i < ARR_SIZE; i++)
  260.             Object1.al[i] = 0x37370000 + i;
  261.         Object1.s = 0x4646;
  262.  
  263.         pObject2 = midl_user_allocate( sizeof(OBJECT2) + ARR_SIZE*sizeof(short) );
  264.         if (pObject2 == NULL ) {
  265.             printf("Out of memory for Object2\n");
  266.             exit(1);
  267.         }
  268.  
  269.         pObject2->sSize = ARR_SIZE;
  270.         for (i = 0; i < ARR_SIZE; i++)
  271.             pObject2->as[i] = 0x7700 + i;
  272.  
  273.         DumpData( "Data to be encoded", pszNameId, &Object1, pObject2 );
  274.  
  275.         printf("\nEncoding all the arguments to the buffer\n\n");
  276.         ProcPickle( pszNameId, & Object1, pObject2 );
  277.  
  278.         printf("Writing the data to the file: %s\n", pszFileName);
  279.         WriteDataToFile( pszFileName,
  280.                          pbPicklingBuffer,
  281.                          fFixedStyle  ? ulEncodedSize
  282.                                       : pUserState->LastSize);
  283.  
  284.         midl_user_free( pObject2 );
  285.     }
  286.     else {
  287.         char            acNameBuffer[50];
  288.         OBJECT1         Object1;
  289.         OBJECT2   *     pObject2;
  290.  
  291.         printf("\nDecoding run: use -e for encoding\n\n");
  292.  
  293.         printf("Reading the data from the file: %s\n\n", pszFileName );
  294.         ReadDataFromFile( pszFileName,
  295.                           pbPicklingBuffer,
  296.                           BUFSIZE );
  297.  
  298.         if ( fFixedStyle ) {
  299.  
  300.             printf("Creating a decoding handle\n");
  301.             status = MesDecodeBufferHandleCreate( pbPicklingBuffer,
  302.                                                   BUFSIZE,
  303.                                                   & ImplicitPicHandle );
  304.             printf("MesDecodeFixedBufferHandleCreate returned 0x%x\n", status);
  305.             if (status) {
  306.                 exit(status);
  307.             }
  308.         }
  309.         else {
  310.  
  311.             pUserState->LastSize = 0;
  312.             pUserState->pMemBuffer = (char *)pbPicklingBuffer;
  313.             pUserState->pBufferStart = (char *)pbPicklingBuffer;
  314.  
  315.             printf("Creating an incremental decoding handle\n");
  316.             status = MesDecodeIncrementalHandleCreate( pUserState,
  317.                                                        PicRead,
  318.                                                        & ImplicitPicHandle );
  319.             printf("MesDecodeIncrementalHandleCreate returned 0x%x\n", status);
  320.             if (status) {
  321.                 exit(status);
  322.             }
  323.         }
  324.  
  325.  
  326.         /* Creating objects to manipulate */
  327.  
  328.         pObject2 = midl_user_allocate( sizeof(OBJECT2) + ARR_SIZE*sizeof(short));
  329.         if (pObject2 == NULL ) {
  330.             printf("Out of memory for Object2\n");
  331.             exit(1);
  332.         }
  333.  
  334.         printf("\nDecoding all the arguments from the buffer\n");
  335.         ProcPickle( acNameBuffer, & Object1, pObject2 );
  336.  
  337.         DumpData( "Decoded data", acNameBuffer, &Object1, pObject2 );
  338.  
  339.         midl_user_free( pObject2 );
  340.     }
  341.  
  342.     printf("\nData serialization done.\n");
  343.  
  344.     midl_user_free( pbPicklingBuffer );
  345.  
  346.     printf("\nFreeing the serialization handle.\n");
  347.     status = MesHandleFree( ImplicitPicHandle );
  348.     printf("MesHandleFree returned 0x%x\n", status);
  349.  
  350.     exit(0);
  351.  
  352. }  // end main()
  353.  
  354. /*********************************************************************/
  355. /*                 MIDL allocate and free                            */
  356. /*********************************************************************/
  357.  
  358. /* A pickling buffer has to be aligned at 8.
  359.    malloc() doesn't guarantee that, so some gimmick has to be done.
  360. */
  361.  
  362. #define ALIGN_TO8( p)   (char *)((unsigned long)((char *)p + 7) & ~7)
  363.  
  364. void __RPC_FAR * __RPC_USER  MIDL_user_allocate(size_t s)
  365. {
  366.     unsigned char * pcAllocated;
  367.     unsigned char * pcUserPtr;
  368.  
  369.     pcAllocated = (unsigned char *) malloc( s + 15 );
  370.     pcUserPtr =  ALIGN_TO8( pcAllocated );
  371.     if ( pcUserPtr == pcAllocated )
  372.         pcUserPtr = pcAllocated + 8;
  373.  
  374.     *(pcUserPtr - 1) = pcUserPtr - pcAllocated;
  375.  
  376.     return( pcUserPtr );
  377. }
  378.  
  379. void __RPC_USER  MIDL_user_free(void __RPC_FAR *f)
  380. {
  381.     unsigned char * pcAllocated;
  382.     unsigned char * pcUserPtr;
  383.  
  384.     pcUserPtr = (unsigned char *) f;
  385.     pcAllocated = pcUserPtr - *(pcUserPtr - 1);
  386.  
  387.     free( pcAllocated );
  388. }
  389.  
  390. /*********************************************************************/
  391. /*                 Incremental style helper routines                 */
  392. /*********************************************************************/
  393.  
  394. void  __RPC_USER
  395. PicAlloc(
  396.     void *          pState,
  397.     char **         ppBuf,
  398.     unsigned int  * pCount )
  399. {
  400.     /* This routines "allocates" the next part from the preallocated
  401.        buffer. It could call midl_user_allocate, too.
  402.     */
  403.  
  404.     PickleControlBlock * pPic = (PickleControlBlock *)pState;
  405.  
  406.     if ( (pPic->pMemBuffer - pPic->pBufferStart) + *pCount <= BUFSIZE )
  407.         *ppBuf = (char *)pPic->pMemBuffer;
  408.     else {
  409.         printf(" Buffer too small\n");
  410.         exit(1);
  411.     }
  412. }
  413.  
  414. void __RPC_USER
  415. PicWrite(
  416.     void *          pState,
  417.     char *          pBuf,
  418.     unsigned int    Count )
  419. {
  420.     /* This routine just marks how much of the preallocated buffer is used.
  421.     */
  422.  
  423.     PickleControlBlock * pPic = (PickleControlBlock *)pState;
  424.  
  425.  
  426.     if ( pPic->pMemBuffer != pBuf ) {
  427.         printf(" Buffer poiner corrupted\n");
  428.         exit(1);
  429.     }
  430.     pPic->pMemBuffer += Count;
  431.     pPic->LastSize += Count;
  432. }
  433.  
  434. void __RPC_USER
  435. PicRead(
  436.     void *          pState,
  437.     char **         ppBuf,
  438.     unsigned int  * pCount )
  439. {
  440.     /* This routine returns another portion of the preread buffer. */
  441.  
  442.     PickleControlBlock * pPic = (PickleControlBlock *)pState;
  443.  
  444.     *ppBuf = (char *)pPic->pMemBuffer;
  445.     pPic->pMemBuffer += *pCount;
  446. }
  447.  
  448. /* end picklpc.c */
  449.  
  450.  
  451.