title: How to convert a complex data type from host byte order to network order
body: <p>I want to translate a message from host byte order to network order using htonl() and htos(). In this message, there are some complex defined data type slike structure, enum, union and union in union.</p>
  
  <ol>
  <li>Shall I have to htonl(s) on every structure's members, and members in member, including the union's member that are multi-byte?</li>
  <li>For an union, can I just translate the largest one?</li>
  <li>For enum, can I just translate it just as a long?</li>
  <li>Can I just write one function that is using htonl(s) for both sending and receiving message? Or do I have to come up with another one that is using ntohl(s) for receiving the same message?</li>
  </ol>
  
  <h3>Structures</h3>
  
  <pre><code>typedef struct {
      unsigned short un1_s;
      unsigned char  un1_c;
  
      union {
          unsigned short un1_u_s;        
          unsigned long  un1_u_l;    
      }u;
  }UN1;
  
  typedef struct {
      unsigned short    un2_s1;
      unsigned short    un2_s2;
  } UN2;
  
  typedef enum {
      ONE,
      TWO,
      TRHEE,
      FOUR
  } ENUM_ID;
  
  typedef struct {
      unsigned short  s_sid;
      unsigned int    i_sid;
      unsigned char   u_char;
      ENUM_ID         i_enum;
  
      union {
              UN1     un1;
              UN2     un2;
      }               u;
  } MSG;
  </code></pre>
  
  <h3>Code</h3>
  
  <pre><code>void msgTranslate (MSG* in_msg, MSG* out_msg){
  
  /* ignore the code validating pointer ... */
  
  *out_msg = *in_msg;
  
  #ifdef LITLE_ENDIAN
  
  /* translating messeage */
  out_msg-&gt;s_sid = htons( in_msg-&gt;s_sid );  /* short */
  out_msg-&gt;i_sid = htonl( in_msg-&gt;i_sid );  /* int */
  
  /* Can I simply leave out_msg-&gt;u_char not to translate, 
   * because it is a single byte? */
  
  out_msg-&gt;i_enum = htonl(in_msg-&gt;i_enum);  
  /* Can I simply translate a enum this way,? */
  
  /* For an union whose 1st member is largest one in size than 
   * others, can I just translate the 1st one, 
   * leaving the others not to convert? */
  
  out_msg-&gt;u.un1.un1_s = htons(in_msg-&gt;u.un1.un1_s);  
  
  
  /* for out_msg-&gt;u_char, can I simply leave it 
   * not to be converted, because it is a single byte? */
  
  /* for an union whose 2nd member is largest one, 
   * can I just convert the 2nd one, leaving others 
   * not to be converted? */
  
  out_msg-&gt;u.un1.u.un1_u_s = htos(in_msg-&gt;u.un1.u.un1_u_s ); /* short */
  
  /* As above question, the following line can be removed? 
   * just because the u.un1.u.un2_u_i is smaller 
   * than u.un1.u.un1 in size ? */
  
  out_msg-&gt;u.un1.u.un2_u_i = htol(in_msg-&gt;u.un1.u.un2_u_l );  /* long */
  
  /* Since un1 is largest than un2, the coding translation un2 can be ignored? */
      ...
  
  #endif
  
      return;
  }
  </code></pre>