home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_16 / EMF / OutPipe.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  7.4 KB  |  357 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : outpipe.cpp                                                         //
  10. //  Description: KTextPipe: text-based output with formating                         //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define WIN32_LEAN_AND_MEAN
  15.  
  16. #define STRICT
  17.  
  18. #include <windows.h>
  19. #include <tchar.h>
  20. #include <assert.h>
  21. #include <stdio.h>
  22. #include <math.h>
  23.  
  24. #include "OutPipe.h"
  25.  
  26.  
  27. void KTextPipe::Newline(void)
  28. {
  29.     Put('\n');
  30.  
  31.     for (long i=0; i<m_indent; i++)
  32.         Put('\t');
  33.  
  34.     m_linelen = 0;
  35. }
  36.  
  37.     
  38. void KTextPipe::Write(const char * str, long size)
  39. {
  40.     if ( str == NULL)
  41.         return;
  42.  
  43.     while ( (size!=0) && (* str) )
  44.     {
  45.         Put(* str++);
  46.         size --;
  47.     }
  48. }
  49.  
  50.  
  51. void KTextPipe::Write(const WCHAR * str, long size)
  52. {
  53.     if ( str == NULL)
  54.         return;
  55.  
  56.     while ( (size!=0) && (* str) )
  57.     {
  58.         Put((char)(* str ++));
  59.         size --;
  60.     }
  61. }
  62.  
  63.  
  64. void KTextPipe::PutQuote(char ch)
  65. {
  66.     switch (ch)
  67.     {
  68.         case '\\':
  69.         case '\"': Put('\\'); Put(ch);    break;
  70.         case '\n': Put('\\'); Put('n'); break;
  71.         case '\r': Put('\\'); Put('r'); break;
  72.         case '\t': Put('\\'); Put('t'); break; 
  73.         default  : Put(ch);
  74.     }
  75. }
  76.  
  77.  
  78. void KTextPipe::WriteString(const void * str, long size, bool unicode)
  79. {
  80.     if ( str == NULL )
  81.     {
  82.         Write("NULL");
  83.         return;
  84.     }
  85.  
  86.     Put('\"');
  87.  
  88.     if ( unicode )
  89.     {
  90.         const WCHAR * s = (const WCHAR * ) str;
  91.  
  92.         while ( (size != 0) && (*s) )
  93.         {
  94.             PutQuote((char)(*s++));
  95.             size --;
  96.         }
  97.     }
  98.     else
  99.     {
  100.         const char * s = (const char * ) str;
  101.  
  102.         while ( (size != 0) && (*s) )
  103.         {
  104.             PutQuote(*s++);
  105.             size --;
  106.         }
  107.     }
  108.  
  109.     Put('\"');
  110. }
  111.  
  112.  
  113. void KTextPipe::WriteDec(unsigned long data)
  114. {
  115.     TCHAR temp[16];
  116.     
  117.     long len = 0;
  118.     do 
  119.     {
  120.         temp[len++] = (char) ('0' + data % 10);
  121.         data = data/10;
  122.     }
  123.     while (data!=0);
  124.  
  125.     while (len)
  126.     {
  127.         len --;
  128.         Put(temp[len]);
  129.     }
  130. }
  131.  
  132.  
  133. void KTextPipe::WriteDec(long data)
  134. {
  135.     if (data < 0)
  136.     {
  137.         Put('-');
  138.         WriteDec((unsigned long) (0 - data));
  139.     }
  140.     else
  141.         WriteDec((unsigned long) data);
  142. }
  143.  
  144.  
  145. void KTextPipe::WriteHex(unsigned long data)
  146. {
  147.     TCHAR temp[10];
  148.  
  149.     if (data<=9)
  150.         Put((char)('0' + data));
  151.     else
  152.     {
  153.         long len = 0;
  154.         do
  155.         {
  156.             temp[len] = (char)('0' + data % 16);
  157.         
  158.             if (temp[len] > '9')
  159.                 temp[len]+= 'A' - '0' - 10;
  160.  
  161.             len ++;
  162.             data /= 16;
  163.         }
  164.         while (data);
  165.  
  166.         Put('0');
  167.         Put('x');
  168.         while (len)
  169.         {
  170.             len --;
  171.             Put(temp[len]);
  172.         }
  173.     }
  174. }
  175.  
  176.  
  177. void KTextPipe::WriteArray(const void * Array, long count, long elmsize, bool decimal)
  178. {
  179.     if ( ! m_bOpened )
  180.         return;
  181.  
  182.     assert(Array);
  183.  
  184.     const char  * bArray = (const char *)  Array;
  185.     const short * sArray = (const short *) Array;
  186.     const long  * lArray = (const long *)  Array;
  187.     const RECT  * rArray = (const RECT *)  Array;
  188.     
  189.     Put('{'); Put(' ');
  190.     for (long i=0; i<count; i++)
  191.     {
  192.         if ( i )
  193.         {
  194.             Put(','); 
  195.             
  196.             if ( m_linelen > 78 )
  197.                 Newline();
  198.             else
  199.                 Put(' ');
  200.         }
  201.  
  202.         switch ( elmsize )
  203.         {
  204.             case 1:  
  205.                 if (decimal) 
  206.                     WriteDec((long) bArray[i]); 
  207.                 else 
  208.                     WriteHex(bArray[i] & 0xFF); 
  209.                 break;
  210.             
  211.             case 2:  
  212.                 if (decimal) 
  213.                     WriteDec((long) sArray[i]); 
  214.                 else 
  215.                     WriteHex(sArray[i] & 0xFFFF); 
  216.                 break;
  217.  
  218.             case 4:  
  219.                 if (decimal) 
  220.                     WriteDec(lArray[i]); 
  221.                 else 
  222.                     WriteHex(lArray[i]); 
  223.                 break;
  224.  
  225.             case sizeof(RECT):
  226.                 Write("{ "); WriteDec(rArray[i].left);
  227.                 Put(',');    WriteDec(rArray[i].top);
  228.                 Put(',');    WriteDec(rArray[i].right);
  229.                 Put(',');    WriteDec(rArray[i].bottom);
  230.                 Write(" }");
  231.                 break;
  232.  
  233.             default: assert(FALSE);
  234.         }
  235.  
  236.     }
  237.  
  238.     Put(' '); Put('}');
  239. }
  240.  
  241.  
  242. void KTextPipe::Write(unsigned index, const DicItem *dic)
  243. {
  244.     Write(Lookup(index, dic));
  245. }
  246.  
  247.  
  248. const long * KTextPipe::Percent(TCHAR tag, const long * data, const DicItem * dic)
  249. {
  250.     static double dummy = sin(0.0); // just to link-in floating point support
  251.  
  252.     int len = 0;
  253.  
  254.     switch ( tag )
  255.     {
  256.         case '_': len = 4; break;            // skip 4 bytes
  257.  
  258.         case '0': WriteDec(data[0]); break; // decimal signed long
  259.         case '1': WriteDec(data[1]); break;    // decimal signed long
  260.         case '2': WriteDec(data[2]); break;    // decimal signed long
  261.         case '3': WriteDec(data[3]); break;    // decimal signed long
  262.         case '4': WriteDec(data[4]); break;    // decimal signed long
  263.         case '5': WriteDec(data[5]); break;    // decimal signed long
  264.         case '6': WriteDec(data[6]); break;    // decimal signed long
  265.         case '7': WriteDec(data[7]); break;    // decimal signed long
  266.         case '8': WriteDec(data[8]); break;    // decimal signed long
  267.         case '9': WriteDec(data[9]); break;    // decimal signed long
  268.  
  269.         case 'b': WriteDec((long)(* ((unsigned char *) data)));    // signed char
  270.                   len = 1;
  271.                   break;
  272.  
  273.         case 'c': 
  274.             {
  275.                 char ch = * data & 0xFF;
  276.  
  277.                 if ( (ch>=' ') && (ch<=0x7F) )
  278.                     Put(ch);
  279.                 else
  280.                     Put('.');
  281.                 len = 1;
  282.             }
  283.             break;
  284.  
  285.         case 'd': WriteDec(                data[0]); len=4; break;  // decimal   signed long
  286.         case 'u': WriteDec((unsigned long) data[0]); len=4; break;  // decimal unsigned long
  287.         case 'x': WriteHex(                data[0]); len=4; break;  // hex     unsigned long
  288.  
  289.         case 'D': WriteDec((long)         (* ((short *)          data))); len=2; break; // signed short
  290.         case 'U': WriteDec((unsigned long)(* ((unsigned short *) data))); len=2; break; // signed short
  291.         case 'X': WriteHex(                * ((unsigned short *) data));  len=2; break; // unsigned short
  292.  
  293.         case 'S': WriteString(data, -1, true);   break; // wide string
  294.         case 's': WriteString(data, -1, false);     break; // ascii string
  295.  
  296.         case 'f': { TCHAR t[32]; float f = * (float *) data; _stprintf(t, _T("%8.5f"), f); Write(t); } // float
  297.                   len = 4;
  298.                   break;
  299.                               
  300.         case 'n': m_nCount++;                    // sequence count: 1 1 2 2 ...
  301.                   WriteDec((long)(m_nCount/2));
  302.                   break;
  303.     
  304.         case 'm': m_mCount++;                    // sequence count: 1 1 2 2 ...
  305.                   WriteDec((long)(m_mCount/2));
  306.                   break;
  307.                                                             
  308.         case 'L': Write(data[0], dic); len = 4; // dic
  309.                   break;
  310.  
  311.         default : assert(false);
  312.     }
  313.  
  314.     return (const long *) ( (const char *) data + len);
  315. }
  316.  
  317.  
  318. const long * KTextPipe::Pound(TCHAR tag, const long * data, const DicItem * dic)
  319. {
  320.     assert(false);
  321.  
  322.     return data;
  323. }
  324.  
  325.  
  326. void KTextPipe::Format(const TCHAR * pattern, const void * vdata, const DicItem * dic)
  327. {
  328.     if ( pattern == NULL )
  329.         return;
  330.  
  331.     while ( * pattern )
  332.     {
  333.         switch ( * pattern )
  334.         {
  335.             case '\n':    
  336.                 Newline();        
  337.                 break;
  338.  
  339.             case '#' :
  340.                 pattern ++;
  341.                 vdata = Pound( * pattern, (const long *) vdata, dic);
  342.                 break;
  343.  
  344.             case '%' : 
  345.                 pattern ++;
  346.                 
  347.                 vdata = Percent( * pattern, (const long *) vdata, dic);
  348.                 break;
  349.  
  350.             default  :
  351.                 Put(* pattern);
  352.         }
  353.  
  354.         pattern ++;
  355.     }
  356. }
  357.