home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / fontedit / typecvt.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  32KB  |  1,351 lines

  1. /*++
  2.  
  3. Copyright (c) 1993-1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     typecvt.c
  8.  
  9. Abstract:
  10.  
  11.     Routines for generically converting between structure formats without
  12.     regard to alignment boundries.
  13.  
  14.  
  15. --*/
  16.  
  17.  
  18. #include "windows.h"
  19. #include <windowsx.h>
  20. #include "typecvt.h"
  21.  
  22. // We want to assert errors for now.
  23. #define ASSERT_ERRORS
  24.  
  25. #ifdef ASSERT_ERRORS
  26. int sprintf ();
  27. #endif
  28.  
  29. //
  30. // For lack of any place better to put a general description of the type
  31. // conversion functions, The following will attempt to explain what is
  32. // needed set up for, and use, the functions.
  33. //
  34. // The main purpose of these functions is to convert non-aligned structures
  35. // to aligned structures and back again.
  36. //
  37. // In order to convert bewteen two structures it is first necessary to define
  38. // what each one looks like.  This is done most easily by statically allocating
  39. // and array of StructDefineInfo or SDI structures.  Here is an example:
  40. //
  41. //      The two structures
  42. //      struct                          struct
  43. //      {                               {
  44. //          CHAR    chElem1;                LONG    rglElem2 [10];
  45. //          WORD    rgwElem2 [5];           ULONG   ulElem1;
  46. //      } src;                          } dest;
  47. //      could be described by.
  48. //
  49. //      SDI  rgsdiSrcStructDef [] = {
  50. //          { sizeof (CHAR), sizeof (src.chElem1) },
  51. //          { sizeof (WORD), sizeof (src.rgwElem2) },
  52. //          { 0, 0 } };
  53. //
  54. //      SDI  rgsdiDestStructDef [] = {
  55. //          { sizeof (LONG), sizeof (dest.rglElem2) },
  56. //          { sizeof (ULONG), sizeof (dest.ulElem1) },
  57. //          { 0, 0 } };
  58. //
  59. // Once both structures have been defined the conversion between the structures
  60. // in different alignments and endian types can be performed with
  61. // PerformConversion ().
  62. //
  63. // For an example of how this is implemented see Fontcvt.c
  64. //
  65.  
  66.  
  67. //
  68. // An advantage of the conversions routines is that they are a portable
  69. // method of handling machines with Big Endian integer storage.  See header
  70. // file typecvt.h for complete description of big and little endian.
  71. //
  72. // The folowing variables are used to select the endian type of the source
  73. // and the destination structures.  The default is Little Endian.
  74. // Also, these are not meant to be accessed outside of this module.
  75. // Routines have been defined to access these.
  76. //
  77.  
  78. INT vfFileEndianType = CVT_FILE_ENDIAN_DEFAULT;
  79. INT vfSysEndianType  = CVT_ENDIAN_UNKNOWN;            // Set to unknown.
  80.  
  81.  
  82. LONG
  83. lCalculateStructOffsets (
  84.       PSDI    rgsdiStructDefine,
  85.       INT     fAlignmentType,
  86.        INT        cSizeOfStruct
  87.     )
  88.  
  89. /*++
  90.  
  91. Routine Description:
  92.  
  93.     This function is used to calculate the offsets of each element in the
  94.     Struct Define Info array.  These values are stored back int the SDI array
  95.     which was passed to us.  The offsets are based on the alignment type
  96.     sent to this routine.  It will also return the sizeof that structure as
  97.     it would be with the alignment or -1 if there is an error.
  98.  
  99. Arguments:
  100.  
  101.     rgsdiStruceDefine   - Definition of this structure as an array of SDI
  102.                           structures.  Note, see beginning of this file for
  103.                           a complete description of how to define this
  104.                           structure.
  105.  
  106.     fAlignmentType      - This is an optional parameter which can be used to
  107.                           request the count of bytes for a particular alignment
  108.                           CVT_ALIGN_PACKED - Return the sizeof the structure
  109.                                 if the alignment were packed.
  110.                           CVT_ALIGN_WORD   - Return the sizeof the structure
  111.                                 if the alignment were WORD aligned.
  112.                           CVT_ALIGN_DWORD  - Return the sizeof the structure
  113.                                 if the alignment were DWORD aligned.
  114.                           Zero or any other value, return 0 on success.
  115.     
  116.     cSizeOfStruct        - This value is used only for error detection.
  117.                           It should be the size of the structure you are
  118.                           converting in the current system alignment.
  119.                           (ex. sizeof (FontHeaderType)).  The function will
  120.                           compare this to it's calculate offset and return
  121.                           an error if they differ.
  122.                           Note that if this value is 0, no error checking will
  123.                           be performed.
  124.  
  125. Return Value:
  126.  
  127.     Postitive Value = The total size of the structure we are looking at.
  128.             This should be the same as if we did a sizeof (struct) in the
  129.             proper alignment.
  130.     -1 = There was an error with the definition of the structure.
  131.             Here is how errors are detected.  Along with determining all of
  132.             the offsets in the specified alignment type, it will also do it
  133.             in CVT_ALIGN_SYSTEM.  If the system alignment does not match the
  134.             initial offsets, an error is reported.
  135.  
  136. --*/
  137.  
  138.  
  139. {
  140.     LONG   oPackedOffset = 0;     // Counter for packed offset.
  141.     LONG   oWordOffset = 0;         // Counter for WORD aligned offset.
  142.     LONG   oDWordOffset = 0;      // Counter for DWORD aligned offset.
  143.  
  144.     //
  145.     // Make sure that the system endian type has been computed.
  146.     // We will probably need this for calls to PerformConversion.
  147.     //
  148.  
  149.     if (vfSysEndianType == CVT_ENDIAN_UNKNOWN) {
  150.  
  151.         vfSysEndianType = fDetermineSysEndianType ();
  152.     }
  153.  
  154.     //
  155.     // Keep looping while there are defined elements.
  156.     //
  157.  
  158.     while (rgsdiStructDefine->cTypeSize) {
  159.  
  160.         //
  161.         // Make sure we are aligned to either the type boundry or the
  162.         // alignment count, whichever is smaller.
  163.         //
  164.  
  165.         if (rgsdiStructDefine->cTypeSize >= 2) {
  166.  
  167.             oWordOffset += (oWordOffset & 1);        // Make sure both are on
  168.             oDWordOffset += (oDWordOffset & 1);        // a WORD boundry.
  169.         }
  170.         
  171.         if (rgsdiStructDefine->cTypeSize >= 4) {
  172.  
  173.             // Add 2 to the DWORD alignment if it is not on a DWORD boundry.
  174.             // Note that the previous check would already have WORD aligned it.
  175.  
  176.             oDWordOffset += (oDWordOffset & 2);
  177.                             
  178.         }
  179.  
  180.         //
  181.         // Store the offset to that element within the structure itsself.
  182.         //
  183.  
  184.         rgsdiStructDefine->oPackedAlign = oPackedOffset;
  185.         rgsdiStructDefine->oWordAlign = oWordOffset;
  186.         rgsdiStructDefine->oDWordAlign = oDWordOffset;
  187.  
  188.         //
  189.         // Increase by actual size of the element.
  190.         //
  191.  
  192.         oPackedOffset += rgsdiStructDefine->cActualSize;
  193.         oWordOffset += rgsdiStructDefine->cActualSize;
  194.         oDWordOffset += rgsdiStructDefine->cActualSize;
  195.  
  196.         rgsdiStructDefine++;
  197.     }
  198.  
  199.     //
  200.     // Be sure that the structure fits within alignement.
  201.     // Add word and DWORD padding accordingly.
  202.     //
  203.  
  204.     oWordOffset  += (oWordOffset & 1);
  205.     oDWordOffset += (oDWordOffset & 1);
  206.     oDWordOffset += (oDWordOffset & 2);
  207.  
  208.     //
  209.     // Check to see if we successfully reached the end of the structure array.
  210.     // We assume that they have sent us a sizeof(struct) in system alignment.
  211.     // If not then return an error, -1.  Otherwise, everything is fine so
  212.     // return the sizeof the structure we just got.
  213.     // Note we only do it if they have given us something to compare.
  214.     //
  215.  
  216.     if (cSizeOfStruct) {
  217.  
  218.         switch (CVT_ALIGN_SYSTEM) {
  219.  
  220.             case CVT_ALIGN_PACKED:
  221.                 if (cSizeOfStruct != oPackedOffset) {
  222.                     return (-1);
  223.                 }
  224.                 break;
  225.  
  226.             case CVT_ALIGN_WORD:
  227.                 if (cSizeOfStruct != oWordOffset) {
  228.                     return (-1);
  229.                 }
  230.                 break;
  231.  
  232.             case CVT_ALIGN_DWORD:
  233.                 if (cSizeOfStruct != oDWordOffset) {
  234.                     return (-1);
  235.                 }
  236.                 break;
  237.         }
  238.     }
  239.  
  240.     //
  241.     // Check and see what type of stucture they want us to return to
  242.     // them.  Generally on NT it will be the packed value they want.
  243.     //
  244.  
  245.     switch (fAlignmentType) {
  246.  
  247.         case CVT_ALIGN_PACKED:
  248.             return (oPackedOffset);
  249.  
  250.         case CVT_ALIGN_WORD:
  251.             return (oWordOffset);
  252.             break;
  253.  
  254.         case CVT_ALIGN_DWORD:
  255.             return (oDWordOffset);
  256.             break;
  257.  
  258.         default:
  259.             return (0);
  260.     }
  261. }
  262.  
  263.  
  264. VOID
  265. vPerformConversion (
  266.      PSDI    rgsdiStructDefine,
  267.      PBYTE   pjSrcBuffer,
  268.      INT        fSrcAlignment,
  269.      INT        fSrcEndianType,
  270.      PBYTE   pjDestBuffer,
  271.      INT        fDestAlignment,
  272.      INT        fDestEndianType
  273.     )
  274.  
  275. /*++
  276.  
  277. Routine Description:
  278.  
  279.     WARNING: CalcStructureOffsets must have previously been called with
  280.         rgsdiStructDesc as it's argument.
  281.  
  282.     This function is the heart of the generic conversion system.  It steps
  283.     through the (PSDI) structure definition array and converts each element
  284.     from the source buffer to the destination buffer.  To do this it uses the
  285.     precomputed offset information stored in the structure definition.
  286.     Also, if the source endian type is different from the destination, it
  287.     will swap all data in the transfer.
  288.  
  289. Arguments:
  290.  
  291.     rgsdiStruceDefine   - Definition of this structure as an array of SDI
  292.                           structures.  Note, see beginning of this file for
  293.                           a complete description of how to define this
  294.                           structure.
  295.  
  296.     pjSrcBuffer         - This is a pointer to the source strucure in memory.
  297.                           This structure does not need to be aligned.
  298.  
  299.     fSrcAlignment       - This is the alignment of the source structure.
  300.                           The permissible values of this field are:
  301.                             CVT_ALIGN_PACKED - structure is packed.
  302.                             CVT_ALIGN_WORD   - structure is WORD aligned.
  303.                             CVT_ALIGN_DWORD  - structure is DWORD aligned.
  304.                             CVT_ALIGN_SYSTEM - use system default alignment.
  305.  
  306.     fSrcEndianType      - This is the byte ordering of the source data.
  307.                           The permissible values of this field are:
  308.                             CVT_LITTLE_ENDIAN - data is little endian format.
  309.                             CVT_BIG_ENDIAN    - data is big endian format.
  310.                             CVT_ENDIAN_FILE   - use current file endian type.
  311.                             CVT_ENDIAN_SYSTEM - use current system endian type.
  312.  
  313.     pjDestBuffer        - This is a pointer to the destination structure.
  314.                           This structure does not need to be aligned.
  315.  
  316.     fDestAlignment      - This is the alignment of the source structure.
  317.                           The permissible values of this field: Same as above.
  318.  
  319.     fDestEndianType     - This is the byte ordering of the source data.
  320.                           The permissible values of this field: Same as above.
  321.  
  322. Return Value:
  323.  
  324.     None.  Any detectable errors would have been found in the initialization
  325.     of the SDI structure.
  326.  
  327. --*/
  328.  
  329. {
  330.     register PSDI rgsdiStrDef = rgsdiStructDefine;
  331.     INT              *poSrcAlign;
  332.     INT              *poDestAlign;
  333.     PBYTE          pjSrc;
  334.     PBYTE          pjDest;
  335.  
  336.     //
  337.     // Get the alignment pointers set to the proper offset into the
  338.     // structure.  Here is the general trick we use here.  First we set the
  339.     // offset pointer to the start of the structure array.  We then find out
  340.     // what offset into that structure will point us to the alignment type
  341.     // we want.  After that, since we have an array we just add the sizeof
  342.     // the SDI struct to the pointer and it will give us the next offset.
  343.     //
  344.  
  345.     poSrcAlign = (INT *)rgsdiStrDef;
  346.  
  347.     switch (fSrcAlignment) {
  348.         
  349.         case CVT_ALIGN_PACKED:
  350.             ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oPackedAlign -
  351.                     (CHAR *)rgsdiStrDef);
  352.             break;
  353.  
  354.         case CVT_ALIGN_WORD:
  355.             ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oWordAlign -
  356.                     (CHAR *)rgsdiStrDef);
  357.             break;
  358.  
  359.         case CVT_ALIGN_DWORD:
  360.             ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oDWordAlign -
  361.                     (CHAR *)rgsdiStrDef);
  362.             break;
  363.     }
  364.  
  365.     //
  366.     // Same with dest.
  367.     //
  368.  
  369.     poDestAlign = (INT *)rgsdiStrDef;
  370.  
  371.     switch (fDestAlignment) {
  372.         
  373.         case CVT_ALIGN_PACKED:
  374.             ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oPackedAlign -
  375.                     (CHAR *)rgsdiStrDef);
  376.             break;
  377.  
  378.         case CVT_ALIGN_WORD:
  379.             ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oWordAlign -
  380.                     (CHAR *)rgsdiStrDef);
  381.             break;
  382.  
  383.         case CVT_ALIGN_DWORD:
  384.             ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oDWordAlign -
  385.                     (CHAR *)rgsdiStrDef);
  386.             break;
  387.     }
  388.  
  389.  
  390.     if (fSrcEndianType == fDestEndianType) {
  391.  
  392.         INT        cTotalCount;
  393.  
  394.         //
  395.         // Keep converting while there exists elements with a valid convert
  396.         // structure.
  397.         //
  398.  
  399.         while (rgsdiStrDef->cTypeSize) {
  400.  
  401.             //
  402.             // Store the actual size we need to transfer.  Also, store the
  403.             // pointers to the offsets within the current structures.
  404.             //
  405.  
  406.             cTotalCount = rgsdiStrDef->cActualSize;
  407.             pjSrc = pjSrcBuffer + *poSrcAlign;
  408.             pjDest = pjDestBuffer + *poDestAlign;
  409.  
  410.             //
  411.             // MemCpy the bytes, probably faster to do it inline.
  412.             //
  413.  
  414.             while (cTotalCount--) {
  415.  
  416.                 *pjDest++ = *pjSrc++;
  417.             }
  418.  
  419.             //
  420.             // Now we step our three pointers to the next structure in
  421.             // the array.
  422.             //
  423.  
  424.             ((CHAR *)poSrcAlign) += sizeof (SDI);
  425.             ((CHAR *)poDestAlign) += sizeof (SDI);
  426.             rgsdiStrDef++;
  427.         }
  428.  
  429.     } else {
  430.  
  431.         INT        cArrayCount;
  432.         INT        cElemSize;
  433.         INT        wT;
  434.  
  435.  
  436.         //
  437.         // Keep converting while there exists elements with a valid convert
  438.         // structure.
  439.         //
  440.  
  441.         while (rgsdiStrDef->cTypeSize) {
  442.  
  443.             cArrayCount = rgsdiStrDef->cActualSize / rgsdiStrDef->cTypeSize;
  444.  
  445.             //
  446.             // Store the actual size we need to transfer.  Also, store the
  447.             // pointers to the offsets within the current structures.
  448.             //
  449.  
  450.             cElemSize = rgsdiStrDef->cActualSize;
  451.             pjSrc = pjSrcBuffer + *poSrcAlign;
  452.             pjDest = pjDestBuffer + *poDestAlign;
  453.  
  454.             //
  455.             // Handle each array element seperately.
  456.             //
  457.  
  458.             while (cArrayCount--) {
  459.  
  460.                 for (wT = 1; wT <= cElemSize; wT++) {
  461.  
  462.                     //
  463.                     // Copy in reverse order.
  464.                     //
  465.  
  466.                     *pjDest++ = *(pjSrc + (cElemSize - wT));
  467.                 }
  468.  
  469.                 pjSrc += cElemSize;
  470.             }
  471.  
  472.             //
  473.             // Now we step our three pointers to the next structure in
  474.             // the array.
  475.             //
  476.  
  477.             ((CHAR *)poSrcAlign) += sizeof (SDI);
  478.             ((CHAR *)poDestAlign) += sizeof (SDI);
  479.             rgsdiStrDef++;
  480.         }
  481.     }
  482. }
  483.  
  484.  
  485. VOID
  486. vSetFileEndianType (
  487.     BOOL     fNewEndianType
  488.     )
  489.  
  490. /*++
  491.  
  492. Routine Description:
  493.  
  494.     This routine is used to set the endian type of the disk file.  Normally
  495.     the define CVT_FILE
  496.  
  497. Arguments:
  498.  
  499.     fNewEndianType   - Endian format type to set the source to.
  500.                        The only valid types are CVT_LITTLE_ENDIAN and
  501.                        CVT_BIG_ENDIAN.
  502.                        Portable calls to this function should always
  503.                        use either CVT_ENDIAN_SYSTEM or CVT_ENDIAN_FILE.
  504.  
  505. Return Value:
  506.  
  507.     None.
  508.  
  509. --*/
  510.  
  511. {
  512.     // Set the endian type of the source data.
  513.     vfFileEndianType = fNewEndianType;
  514. }
  515.  
  516.  
  517. INT
  518. fDetermineSysEndianType (
  519.     VOID
  520.     )
  521.  
  522. /*++
  523.  
  524. Routine Description:
  525.  
  526.     This function is used to determine how the current system stores its
  527.     integers in memory.
  528.  
  529. Arguments:
  530.  
  531.     None.
  532.  
  533. Return Value:
  534.  
  535.     CVT_LITTLE_ENDIAN   - The system stores integers in little endian
  536.                               format.  (this is 80x86 default).
  537.     CVT_BIG_ENDIAN      - The system stores integers in big endian format.
  538.  
  539. --*/
  540.  
  541. {
  542.     INT        nCheckInteger;
  543.     CHAR    rgchTestBytes [sizeof (INT)];
  544.  
  545.     //
  546.     // Clear the test bytes to zero.
  547.     //
  548.  
  549.     *((INT *)rgchTestBytes) = 0;
  550.  
  551.     //
  552.     // Set first to some value.
  553.     //
  554.  
  555.     rgchTestBytes [0] = (CHAR) 0xFF;
  556.  
  557.     //
  558.     // Map it to an integer.
  559.     //
  560.  
  561.     nCheckInteger = *((INT *)rgchTestBytes);
  562.  
  563.     //
  564.     // See if value was stored in low order of integer.
  565.     // If so then system is little endian.
  566.     //
  567.  
  568.     if (nCheckInteger == 0xFF) {
  569.  
  570.         return (CVT_LITTLE_ENDIAN);
  571.     } else {
  572.  
  573.         return (CVT_LITTLE_ENDIAN);
  574.     }
  575. }
  576.  
  577.  
  578. VOID
  579. vCharToShort (
  580.              PBYTE   pjSrc,
  581.              PBYTE   pjDest
  582.     )
  583.  
  584. /*++
  585.  
  586. Routine Description:
  587.  
  588.     Copies the source CHAR to the destination SHORT.  Note that sign extension
  589.     is performed.  The destination buffer does not need to be WORD aligned.
  590.     This is generally used for transfering file mapped data.
  591.  
  592. Arguments:
  593.  
  594.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  595.     pjDest      - Returns the copied SHORT at the location pointed to.
  596.  
  597. Return Value:
  598.  
  599.     None.
  600.  
  601. --*/
  602.  
  603. {
  604.     // Get the source CHAR and use it as an argument for destination SHORT.
  605.  
  606.     vDestBuffFromSHORT (
  607.              (SHORT)*pjSrc,
  608.              pjDest
  609.             );
  610. }
  611.  
  612.  
  613. VOID
  614. vCharToUShort (
  615.              PBYTE   pjSrc,
  616.              PBYTE   pjDest
  617.     )
  618.  
  619. /*++
  620.  
  621. Routine Description:
  622.  
  623.     Copies the source CHAR to the destination USHORT.  Note that sign
  624.     extension is not perfomed.  The destination buffer does not need to be
  625.     WORD aligned. This is generally used for transfering file mapped data.
  626.  
  627. Arguments:
  628.  
  629.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  630.     pjDest      - Returns the copied SHORT at the location pointed to.
  631.  
  632. Return Value:
  633.  
  634.     None.
  635.  
  636. --*/
  637.  
  638. {
  639.     // Get the source CHAR and use it as an argument for destination USHORT.
  640.  
  641.     vDestBuffFromUSHORT (
  642.              (USHORT)*pjSrc,
  643.              pjDest
  644.             );
  645. }
  646.  
  647.  
  648. VOID
  649. vCharToLong (
  650.              PBYTE   pjSrc,
  651.              PBYTE   pjDest
  652.     )
  653.  
  654. /*++
  655.  
  656. Routine Description:
  657.  
  658.     Copies the source CHAR to the destination LONG.  Note that sign extension
  659.     is performed.  The destination buffer does not need to be DWORD aligned.
  660.     This is generally used for transfering file mapped data.
  661.  
  662. Arguments:
  663.  
  664.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  665.     pjDest      - Returns the copied LONG at the location pointed to.
  666.  
  667. Return Value:
  668.  
  669.     None.
  670.  
  671. --*/
  672.  
  673. {
  674.     // Get the source CHAR and use it as an argument for destination LONG.
  675.  
  676.     vDestBuffFromLONG (
  677.              (LONG)*pjSrc,
  678.              pjDest
  679.             );
  680. }
  681.  
  682.  
  683. VOID
  684. vCharToULong (
  685.              PBYTE   pjSrc,
  686.              PBYTE   pjDest
  687.     )
  688.  
  689. /*++
  690.  
  691. Routine Description:
  692.  
  693.     Copies the source CHAR to the destination ULONG.  Note that sign extension
  694.     is not performed.  The destination buffer does not need to be DWORD
  695.     aligned. This is generally used for transfering file mapped data.
  696.  
  697. Arguments:
  698.  
  699.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  700.     pjDest      - Returns the copied ULONG at the location pointed to.
  701.  
  702. Return Value:
  703.  
  704.     None.
  705.  
  706. --*/
  707.  
  708. {
  709.     // Get the source CHAR and use it as an argument for destination ULONG.
  710.  
  711.     vDestBuffFromULONG (
  712.              (ULONG)*pjSrc,
  713.              pjDest
  714.             );
  715. }
  716.  
  717.  
  718. VOID
  719. vShortToShort (
  720.              PBYTE   pjSrc,
  721.              PBYTE   pjDest
  722.     )
  723.  
  724. /*++
  725.  
  726. Routine Description:
  727.  
  728.     Copies the source SHORT to the destination SHORT.  Neither buffers need
  729.     to be WORD aligned.  This is generally used for transfering file mapped
  730.     data.
  731.  
  732. Arguments:
  733.  
  734.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  735.     pjDest      - Returns the copied SHORT at the location pointed to.
  736.  
  737. Return Value:
  738.  
  739.     None.
  740.  
  741. --*/
  742.  
  743. {
  744.     // Get the source SHORT and use it as an argument for destination SHORT.
  745.  
  746.     vDestBuffFromSHORT (
  747.              sSHORTFromSrcBuff (pjSrc),
  748.              pjDest
  749.             );
  750. }
  751.  
  752.  
  753. VOID
  754. vShortToLong (
  755.              PBYTE   pjSrc,
  756.              PBYTE   pjDest
  757.     )
  758.  
  759. /*++
  760.  
  761. Routine Description:
  762.  
  763.     Copies the source SHORT to the destination LONG.  Note that sign extension
  764.     is perfomed.  Neither buffers need to be WORD or DWORD aligned.
  765.     This is generally used for transfering file mapped data.
  766.  
  767. Arguments:
  768.  
  769.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  770.     pjDest      - Returns the copied LONG at the location pointed to.
  771.  
  772. Return Value:
  773.  
  774.     None.
  775.  
  776. --*/
  777.  
  778. {
  779.     // Get the source SHORT and use it as an argument for destination LONG.
  780.  
  781.     vDestBuffFromLONG (
  782.              (LONG)sSHORTFromSrcBuff (pjSrc),
  783.              pjDest
  784.             );
  785. }
  786.  
  787.  
  788. VOID
  789. vShortToULong (
  790.              PBYTE   pjSrc,
  791.              PBYTE   pjDest
  792.     )
  793.  
  794. /*++
  795.  
  796. Routine Description:
  797.  
  798.     Copies the source SHORT to the destination ULONG.  Note that sign extension
  799.     is perfomed.  Neither buffers need to be WORD or DWORD aligned.
  800.     This is generally used for transfering file mapped data.
  801.  
  802. Arguments:
  803.  
  804.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  805.     pjDest      - Returns the copied ULONG at the location pointed to.
  806.  
  807. Return Value:
  808.  
  809.     None.
  810.  
  811. --*/
  812.  
  813. {
  814.     // Get the source SHORT and use it as an argument for destination ULONG.
  815.  
  816.     vDestBuffFromULONG (
  817.              (LONG)sSHORTFromSrcBuff (pjSrc),
  818.              pjDest
  819.             );
  820. }
  821.  
  822.  
  823. VOID
  824. vLongToLong (
  825.              PBYTE   pjSrc,
  826.              PBYTE   pjDest
  827.     )
  828.  
  829. /*++
  830.  
  831. Routine Description:
  832.  
  833.     Copies the source LONG to the destination LONG.  Neither buffers need to
  834.     be WORD or DWORD aligned. This is generally used for transfering file
  835.     mapped data.
  836.  
  837. Arguments:
  838.  
  839.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  840.     pjDest      - Returns the copied LONG at the location pointed to.
  841.  
  842. Return Value:
  843.  
  844.     None.
  845.  
  846. --*/
  847.  
  848. {
  849.     // Get the source LONG and use it as an argument for destination LONG.
  850.  
  851.     vDestBuffFromLONG (
  852.              (LONG)lLONGFromSrcBuff (pjSrc),
  853.              pjDest
  854.             );
  855. }
  856.  
  857.  
  858. VOID
  859. vLongToShort (
  860.              PBYTE   pjSrc,
  861.              PBYTE   pjDest
  862.     )
  863.  
  864. /*++
  865.  
  866. Routine Description:
  867.  
  868.     Copies the source LONG to the destination SHORT.  Neither buffers need to
  869.     be WORD or DWORD aligned. This is generally used for transfering file
  870.     mapped data.
  871.  
  872. Arguments:
  873.  
  874.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  875.     pjDest      - Returns the copied SHORT at the location pointed to.
  876.  
  877. Return Value:
  878.  
  879.     None.
  880.  
  881. --*/
  882.  
  883. {
  884.     // Get the source LONG and use it as an argument for destination SHORT.
  885.  
  886.     vDestBuffFromSHORT (
  887.              (SHORT)lLONGFromSrcBuff (pjSrc),
  888.              pjDest
  889.             );
  890. }
  891.  
  892.  
  893. VOID
  894. vLongToChar (
  895.              PBYTE   pjSrc,
  896.              PBYTE   pjDest
  897.     )
  898.  
  899. /*++
  900.  
  901. Routine Description:
  902.  
  903.     Copies the source LONG to the destination CHAR.  Neither buffers need to
  904.     be WORD or DWORD aligned. This is generally used for transfering file
  905.     mapped data.
  906.  
  907. Arguments:
  908.  
  909.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  910.     pjDest      - Returns the copied CHAR at the location pointed to.
  911.  
  912. Return Value:
  913.  
  914.     None.
  915.  
  916. --*/
  917.  
  918. {
  919.     // Get the source LONG and use it as an argument for destination CHAR.
  920.  
  921.     *pjDest = (CHAR)lLONGFromSrcBuff (pjSrc);
  922. }
  923.  
  924.  
  925. VOID
  926. vShortToChar (
  927.              PBYTE   pjSrc,
  928.              PBYTE   pjDest
  929.     )
  930.  
  931. /*++
  932.  
  933. Routine Description:
  934.  
  935.     Copies the source SHORT to the destination CHAR.  Neither buffers need to
  936.     be WORD or DWORD aligned. This is generally used for transfering file
  937.     mapped data.
  938.  
  939. Arguments:
  940.  
  941.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  942.     pjDest      - Returns the copied CHAR at the location pointed to.
  943.  
  944. Return Value:
  945.  
  946.     None.
  947.  
  948. --*/
  949.  
  950. {
  951.     // Get the source SHORT and use it as an argument for destination CHAR.
  952.  
  953.     *pjDest = (CHAR)sSHORTFromSrcBuff (pjSrc);
  954. }
  955.  
  956.  
  957. SHORT
  958. sSHORTFromSrcBuff (
  959.          PBYTE   pjSrc
  960.     )
  961.  
  962. /*++
  963.  
  964. Routine Description:
  965.  
  966.     Copies two byte short from buffer into a signed short.  The buffer does
  967.     not need to be WORD aligned.  This is generally used for copying from
  968.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  969.     fSrcEndianType is checked before copy.
  970.  
  971. Arguments:
  972.  
  973.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  974.  
  975. Return Value:
  976.  
  977.     Signed short which is obtained from the buffer.
  978.  
  979. --*/
  980.  
  981.  
  982. {
  983.     SHORT   sStorage;
  984.  
  985. #ifdef CVT_BIG_ENDIAN_SUPPORT
  986.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  987. #endif
  988.         sStorage = (SHORT)          // Source is little endian, shift
  989.                 (                   // the high bytes high.
  990.                  (pjSrc [1] << 8) |
  991.                  (pjSrc [0])
  992.                 );
  993.  
  994. #ifdef CVT_BIG_ENDIAN_SUPPORT
  995.     } else {
  996.         sStorage = (SHORT)          // Source is big endian, shift
  997.                 (                   // the high bytes low.
  998.                  (pjSrc [0] << 8) |
  999.                  (pjSrc [1])
  1000.                 );
  1001.     }
  1002.  
  1003. #endif
  1004.  
  1005.     return (sStorage);
  1006. }
  1007.  
  1008.  
  1009. USHORT
  1010. usUSHORTFromSrcBuff (
  1011.          PBYTE   pjSrc
  1012.     )
  1013.  
  1014. /*++
  1015.  
  1016. Routine Description:
  1017.  
  1018.     Copies two byte short from buffer into an unsigned short.  The buffer does
  1019.     not need to be WORD aligned.  This is generally used for copying from
  1020.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  1021.     fSrcEndianType is checked before copy.
  1022.  
  1023. Arguments:
  1024.  
  1025.     pjSrc       - Supplies pointer to the source buffer containing a USHORT.
  1026.  
  1027. Return Value:
  1028.  
  1029.     Unsigned short which is obtained from the buffer.
  1030.  
  1031. --*/
  1032.  
  1033.  
  1034. {
  1035.     USHORT  usStorage;
  1036.  
  1037. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1038.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  1039. #endif
  1040.         usStorage = (USHORT)            // Source is little endian, shift
  1041.                 (                       // the high bytes high.
  1042.                  (pjSrc [1] << 8) |
  1043.                  (pjSrc [0])
  1044.                 );
  1045.  
  1046. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1047.     } else {
  1048.         usStorage = (USHORT)            // Source is big endian, shift
  1049.                 (                       // the high bytes low.
  1050.                  (pjSrc [0] << 8) |
  1051.                  (pjSrc [1])
  1052.                 );
  1053.     }
  1054.  
  1055. #endif
  1056.  
  1057.     return (usStorage);
  1058. }
  1059.  
  1060.  
  1061. LONG
  1062. lLONGFromSrcBuff (
  1063.          PBYTE   pjSrc
  1064.     )
  1065.  
  1066. /*++
  1067.  
  1068. Routine Description:
  1069.  
  1070.     Copies four byte long from buffer into a signed long.  The buffer does
  1071.     not need to be DWORD aligned.  This is generally used for copying from
  1072.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  1073.     fSrcEndianType is checked before copy.
  1074.  
  1075. Arguments:
  1076.  
  1077.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  1078.  
  1079. Return Value:
  1080.  
  1081.     Signed long which is obtained from the buffer.
  1082.  
  1083. --*/
  1084.  
  1085.  
  1086. {
  1087.     LONG    lStorage;
  1088.  
  1089. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1090.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  1091. #endif
  1092.         lStorage = (LONG)               // Source is little endian, shift
  1093.                 ((pjSrc [3] << 24) |    // the high bytes high.
  1094.                  (pjSrc [2] << 16) |
  1095.                  (pjSrc [1] << 8) |
  1096.                  (pjSrc [0])
  1097.                 );
  1098.  
  1099. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1100.     } else {
  1101.         lStorage = (LONG)               // Source is big endian, shift the
  1102.                 ((pjSrc [0] << 24) |    // high bytes low.
  1103.                  (pjSrc [1] << 16) |
  1104.                  (pjSrc [2] << 8) |
  1105.                  (pjSrc [3])
  1106.                 );
  1107.     }
  1108.  
  1109. #endif
  1110.  
  1111.     return (lStorage);
  1112. }
  1113.  
  1114.  
  1115. ULONG
  1116. ulULONGFromSrcBuff (
  1117.          PBYTE   pjSrc
  1118.     )
  1119.  
  1120. /*++
  1121.  
  1122. Routine Description:
  1123.  
  1124.     Copies four byte long from buffer into an unsigned long.  The buffer does
  1125.     not need to be DWORD aligned.  This is generally used for copying from
  1126.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  1127.     fSrcEndianType is checked before copy.
  1128.  
  1129. Arguments:
  1130.  
  1131.     pjSrc       - Supplies pointer to the source buffer containing a ULONG.
  1132.  
  1133. Return Value:
  1134.  
  1135.     Unsigned long which is obtained from the buffer.
  1136.  
  1137. --*/
  1138.  
  1139.  
  1140. {
  1141.     ULONG   ulStorage;
  1142.  
  1143. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1144.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  1145. #endif
  1146.         ulStorage = (ULONG)             // Source is little endian, shift
  1147.                 ((pjSrc [3] << 24) |    // the high bytes high.
  1148.                  (pjSrc [2] << 16) |
  1149.                  (pjSrc [1] << 8) |
  1150.                  (pjSrc [0])
  1151.                 );
  1152.  
  1153. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1154.     } else {
  1155.         ulStorage = (ULONG)             // Source is big endian, shift the
  1156.                 ((pjSrc [0] << 24) |    // high bytes low.
  1157.                  (pjSrc [1] << 16) |
  1158.                  (pjSrc [2] << 8) |
  1159.                  (pjSrc [3])
  1160.                 );
  1161.     }
  1162.  
  1163. #endif
  1164.  
  1165.     return (ulStorage);
  1166. }
  1167.  
  1168.  
  1169. VOID
  1170. vDestBuffFromSHORT (
  1171.          SHORT   sSource,
  1172.          PBYTE   pjDest
  1173.     )
  1174.  
  1175. /*++
  1176.  
  1177. Routine Description:
  1178.  
  1179.     Copies two byte signed short into a destination buffer.  The buffer does
  1180.     not need to be WORD aligned.  This is generally used for copying to
  1181.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  1182.     fDestEndianType is checked before copy.
  1183.  
  1184. Arguments:
  1185.  
  1186.     sSource     - Signed short to convert to buffer.
  1187.     pjDest      - Supplies pointer to destination buffer for the USHORT.
  1188.  
  1189. Return Value:
  1190.  
  1191.     None.
  1192.  
  1193. --*/
  1194.  
  1195.  
  1196. {
  1197. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1198.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  1199. #endif
  1200.         pjDest [0] = ((sSource) & 0xFF);
  1201.         pjDest [1] = ((sSource >> 8)  & 0xFF);
  1202.  
  1203. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1204.     } else {
  1205.         pjDest [1] = ((sSource) & 0xFF);
  1206.         pjDest [0] = ((sSource >> 8)  & 0xFF);
  1207.     }
  1208.  
  1209. #endif
  1210. }
  1211.  
  1212.  
  1213. VOID
  1214. vDestBuffFromUSHORT (
  1215.          USHORT  usSource,
  1216.          PBYTE   pjDest
  1217.     )
  1218.  
  1219. /*++
  1220.  
  1221. Routine Description:
  1222.  
  1223.     Copies two byte unsigned short into a destination buffer.  The buffer
  1224.     does not need to be WORD aligned.  This is generally used for copying to
  1225.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  1226.     fDestEndianType is checked before copy.
  1227.  
  1228. Arguments:
  1229.  
  1230.     usSource    - Unsigned short to convert to buffer.
  1231.     pjDest      - Supplies pointer to destination buffer for the USHORT.
  1232.  
  1233. Return Value:
  1234.  
  1235.     None.
  1236.  
  1237. --*/
  1238.  
  1239.  
  1240. {
  1241. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1242.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  1243. #endif
  1244.         pjDest [0] = ((usSource) & 0xFF);
  1245.         pjDest [1] = ((usSource >> 8)  & 0xFF);
  1246.  
  1247. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1248.     } else {
  1249.         pjDest [1] = ((usSource) & 0xFF);
  1250.         pjDest [0] = ((usSource >> 8)  & 0xFF);
  1251.     }
  1252.  
  1253. #endif
  1254. }
  1255.  
  1256.  
  1257. VOID
  1258. vDestBuffFromLONG (
  1259.          LONG    lSource,
  1260.          PBYTE   pjDest
  1261.     )
  1262.  
  1263. /*++
  1264.  
  1265. Routine Description:
  1266.  
  1267.     Copies four byte long into a destination buffer.  The buffer does not
  1268.     need to be DWORD aligned.  This is generally used for copying to
  1269.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  1270.     fDestEndianType is checked before copy.
  1271.  
  1272. Arguments:
  1273.  
  1274.     lSource     - Signed long to convert to buffer.
  1275.     pjDest      - Supplies pointer to destination buffer for the LONG.
  1276.  
  1277. Return Value:
  1278.  
  1279.     None.
  1280.  
  1281. --*/
  1282.  
  1283.  
  1284. {
  1285. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1286.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  1287. #endif
  1288.         pjDest [0] = ((lSource) & 0xFF);
  1289.         pjDest [1] = ((lSource >> 8)  & 0xFF);
  1290.         pjDest [2] = ((lSource >> 16) & 0xFF);
  1291.         pjDest [3] = ((lSource >> 24) & 0xFF);
  1292.  
  1293. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1294.     } else {
  1295.         pjDest [3] = ((lSource) & 0xFF);
  1296.         pjDest [2] = ((lSource >> 8)  & 0xFF);
  1297.         pjDest [1] = ((lSource >> 16) & 0xFF);
  1298.         pjDest [0] = ((lSource >> 24) & 0xFF);
  1299.     }
  1300.  
  1301. #endif
  1302. }
  1303.  
  1304.  
  1305. VOID
  1306. vDestBuffFromULONG (
  1307.          ULONG   ulSource,
  1308.          PBYTE   pjDest
  1309.     )
  1310.  
  1311. /*++
  1312.  
  1313. Routine Description:
  1314.  
  1315.     Copies four byte long into a destination buffer.  The buffer does not
  1316.     need to be DWORD aligned.  This is generally used for copying to
  1317.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  1318.     fDestEndianType is checked before copy.
  1319.  
  1320. Arguments:
  1321.  
  1322.     ulSource    - Unsigned long to convert to buffer.
  1323.     pjDest      - Supplies pointer to destination buffer for the ULONG.
  1324.  
  1325. Return Value:
  1326.  
  1327.     None.
  1328.  
  1329. --*/
  1330.  
  1331.  
  1332. {
  1333. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1334.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  1335. #endif
  1336.         pjDest [0] = (BYTE)((ulSource) & (ULONG)0xFF);
  1337.         pjDest [1] = (BYTE)((ulSource >> 8)  & (ULONG)0xFF);
  1338.         pjDest [2] = (BYTE)((ulSource >> 16) & (ULONG)0xFF);
  1339.         pjDest [3] = (BYTE)((ulSource >> 24) & (ULONG)0xFF);
  1340.  
  1341. #ifdef CVT_BIG_ENDIAN_SUPPORT
  1342.     } else {
  1343.         pjDest [3] = (BYTE)((ulSource) & (ULONG)0xFF);
  1344.         pjDest [2] = (BYTE)((ulSource >> 8)  & (ULONG)0xFF);
  1345.         pjDest [1] = (BYTE)((ulSource >> 16) & (ULONG)0xFF);
  1346.         pjDest [0] = (BYTE)((ulSource >> 24) & (ULONG)0xFF);
  1347.     }
  1348.  
  1349. #endif
  1350. }
  1351.