(root)/
libredwg-0.13/
examples/
bits.c
       1  /*****************************************************************************/
       2  /*  LibreDWG - free implementation of the DWG file format                    */
       3  /*                                                                           */
       4  /*  Copyright (C) 2018-2019 Free Software Foundation, Inc.                   */
       5  /*                                                                           */
       6  /*  This library is free software, licensed under the terms of the GNU       */
       7  /*  General Public License as published by the Free Software Foundation,     */
       8  /*  either version 3 of the License, or (at your option) any later version.  */
       9  /*  You should have received a copy of the GNU General Public License        */
      10  /*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
      11  /*****************************************************************************/
      12  
      13  /*
      14   * bits.c: print all possible type/values of given bits
      15   * written by Reini Urban
      16   */
      17  
      18  #include "../src/config.h"
      19  #include <stdio.h>
      20  #include <stdlib.h>
      21  #include <string.h>
      22  #include <ctype.h>
      23  
      24  #include "dwg.h"
      25  #include "../src/bits.h"
      26  static int maxoff = 0;
      27  
      28  static int
      29  decode (Bit_Chain *dat, int off, const int size)
      30  {
      31    int pos = 0;
      32    BITCODE_BS bs = 0;
      33    printf ("decode offset:%d, size:%d\n", off, size);
      34    if (off >= size)
      35      return 0;
      36  
      37    bit_set_position (dat, off);
      38    if (size - off >= 66)
      39      {
      40        double d = bit_read_BD (dat);
      41        int p = (int)bit_position (dat);
      42        if (d != bit_nan ())
      43          {
      44            printf ("%.15f BD @%d (%d)\n", d, p, size);
      45            pos = p;
      46          }
      47        bit_set_position (dat, off);
      48      }
      49    if (size - off >= 64)
      50      {
      51        double d = bit_read_RD (dat);
      52        int p = (int)bit_position (dat);
      53        if (d != bit_nan ())
      54          {
      55            printf ("%.15f RD @%d (%d)\n", d, p, size);
      56            pos = p;
      57          }
      58        bit_set_position (dat, off);
      59      }
      60    if (size - off >= 34)
      61      {
      62        BITCODE_BL l = (long)bit_read_BL (dat);
      63        int p = (int)bit_position (dat);
      64        if (p <= size - off)
      65          {
      66            printf ("%u BL @%d (%d)\n", l, p, size);
      67            pos = p;
      68          }
      69        bit_set_position (dat, off);
      70      }
      71    if (size - off >= 32)
      72      {
      73        BITCODE_BL l = (long)bit_read_RL (dat);
      74        pos = (int)bit_position (dat);
      75        printf ("%u RL @%d (%d)\n", l, pos, size);
      76        bit_set_position (dat, off);
      77      }
      78    if (size - off >= 16)
      79      {
      80        BITCODE_RS l = (int)bit_read_RS (dat);
      81        pos = (int)bit_position (dat);
      82        printf ("%d RS @%d (%d)\n", l, pos, size);
      83        bit_set_position (dat, off);
      84      }
      85    if (size - off >= 10)
      86      {
      87        int p;
      88        bs = bit_read_BS (dat);
      89        p = (int)bit_position (dat);
      90        if (p <= size - off)
      91          {
      92            printf ("%d BS @%d (%d)\n", bs, p, size);
      93            pos = p;
      94          }
      95        bit_set_position (dat, off);
      96      }
      97    if (size - off >= 8)
      98      {
      99        int l = bit_read_RC (dat);
     100        pos = (int)bit_position (dat);
     101        printf ("%d RC @%d (%d)\n", l, pos, size);
     102        bit_set_position (dat, off);
     103      }
     104    if (size - off >= 8)
     105      {
     106        Dwg_Handle h;
     107        int err, p;
     108        err = bit_read_H (dat, &h);
     109        p = (int)bit_position (dat);
     110        if (!err && h.size == 1 && p <= size - off)
     111          {
     112            printf ("%x.%d.%lX H @%d (%d)\n", h.code, h.size, h.value, p, size);
     113            pos = p;
     114          }
     115        bit_set_position (dat, off);
     116      }
     117    if (size - off >= 4)
     118      {
     119        Dwg_Color c;
     120        int p;
     121        bit_read_CMC (dat, dat, &c);
     122        p = (int)bit_position (dat);
     123        if (c.index < 257 && p <= size - off)
     124          {
     125            printf ("%d 0x%06X 0x%x CMC @%d (%d)\n", c.index, c.rgb, c.flag, p,
     126                    size);
     127            pos = p;
     128          }
     129        free (c.name);
     130        free (c.book_name);
     131        bit_set_position (dat, off);
     132      }
     133    if (size - off >= 2)
     134      {
     135        int i = bit_read_BB (dat);
     136        pos = (int)bit_position (dat);
     137        printf ("%d BB @%d (%d)\n", i, pos, size);
     138        if (i == 2)
     139          printf ("%d BS/BL @%d (%d)\n", 0, pos, size);
     140        else if (i == 3)
     141          printf ("%d BS @%d (%d)\n", 256, pos, size);
     142        bit_set_position (dat, off);
     143      }
     144    // if BS is a valid length try TV also
     145    if (bs > 0 && bs < size - off - pos)
     146      {
     147        int i;
     148        char *s = bit_read_TV (dat);
     149        int p = (int)bit_position (dat);
     150        if (s)
     151          {
     152            for (i = 0; i < bs; i++)
     153              if (!isprint (s[i]))
     154                break;
     155            if (i == bs)
     156              {
     157                printf ("%s TV @%d (%d)\n", s, pos, size);
     158                pos = p;
     159              }
     160            free (s);
     161          }
     162      }
     163  
     164    while (pos < size)
     165      {
     166        if (pos <= off)
     167          pos++;
     168        if (maxoff < pos)
     169          maxoff = pos;
     170        // printf ("offset %d\n", pos);
     171        return decode (dat, off + 1, size);
     172      }
     173    return 0;
     174  }
     175  
     176  int
     177  main (int argc, char *argv[])
     178  {
     179    int hex = 0;
     180    int i;
     181    int pos;
     182    Bit_Chain dat = EMPTY_CHAIN (0);
     183  
     184    if (argc < 2)
     185      {
     186        printf ("usage: examples/bits "
     187                "001100000000000000000000000000011000000000000000100000001010010"
     188                "00\n");
     189        printf (
     190            "or examples/bits -x '8055 40f9 3284 d222 3e40 7436 e0d9 23fd'\n");
     191        return 1;
     192      }
     193    if (argc > 2 && !strcmp (argv[1], "-x"))
     194      {
     195        hex = 1;
     196        i = 2;
     197      }
     198    else
     199      {
     200        i = 1;
     201      }
     202  
     203    // dat.chain = malloc (size + 1);
     204    // dat.size = size;
     205    dat.version = R_2004;
     206    do
     207      {
     208        char *input = argv[i];
     209        int bits = strlen (input);
     210        if (hex)
     211          dat.size += bits;
     212        else
     213          dat.size += bits / 8;
     214        dat.chain = realloc (dat.chain, dat.size + 1);
     215        if (hex)
     216          {
     217            int size = bit_write_hexbits (&dat, input);
     218            dat.size -= dat.size - size;
     219          }
     220        else
     221          bit_write_bits (&dat, input);
     222        i++;
     223      }
     224    while (i < argc);
     225  
     226    pos = (int)bit_position (&dat);
     227    // accept all types, like CMC, BS, BL, HANDLE and print all possible variants
     228    pos = decode (&dat, 0, (int)pos);
     229  
     230    free (dat.chain);
     231    return 0;
     232  }