dtinfo: remove register keyword
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / cgm / cgmio.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: cgmio.c /main/5 1996/07/01 15:34:30 cde-hal $ */
24 /* this is the I/O module for the CGM interpreter */
25 /* we will do all of our I/O with non-specific calls, e.g., fread */
26 /* this should not be too slow since we intend to no random I/O */
27 #include "cgm.h"                /* our standard defs */
28 #include "GraphicsP.h"
29
30 /* necessary globals for the input file */
31
32 /* we'll get our records BUFSIZ bytes at a time */
33 #define CGMB_SIZE BUFSIZ                /* might change later */
34 static unsigned char cgm_buffer[CGMB_SIZE];
35 /* pointers into the input buffer */
36 static unsigned char *begin_ptr, *endin_ptr, *in_ptr;
37 static int io_debug = 0, recs_got, bytes_read;
38
39 /* function to get an input record, return no of bytes read */
40 static int get_cgm_rec(unsigned char *start_ptr,
41                        int buffer_size,
42                        _DtGrStream *cgmptr)
43 {
44   int bytes_got;
45   
46   bytes_got = _DtGrRead(start_ptr, 1, buffer_size, cgmptr);
47   ++recs_got;
48   bytes_read += bytes_got;
49   /* printf("bytes_got %d\n",bytes_got);  [PLA] */
50   return(bytes_got);
51 }
52 /* function to open the CGM file */
53 /* stream is a file stream */
54 int open_cgm_file(_DtGrStream *stream)
55 {
56   int bytes_got;
57   fprintf(stderr, "Attempting to open file, %s\n", stream->source.file.filename);
58   /* no uncompress supported */
59   if (!(stream->source.file.fileptr = 
60         fopen(stream->source.file.filename, "r"))) {
61     burp(stderr, "couldn't open %s for input\n", stream->source.file.filename);
62     return(0);
63   } else if (io_debug) burp(stderr, "opened %s for input\n",
64                             stream->source.file.filename);
65   
66   /* get the first record */
67   begin_ptr = cgm_buffer;
68   if ((bytes_got = get_cgm_rec(begin_ptr, CGMB_SIZE, stream)) < 1) {
69     burp(stderr, "empty file %s ?\n", stream->source.file.filename);
70     return(0);
71   }
72   endin_ptr = begin_ptr + bytes_got;
73   in_ptr = begin_ptr;
74   return(1);
75 }
76
77 /* function to prepare the CGM buffer */
78 /* stream is a buffer stream */
79 int open_cgm_buffer(_DtGrStream *stream)
80 {
81   int bytes_got;
82
83   /* get the first record */
84   begin_ptr = cgm_buffer;
85   if ((bytes_got = get_cgm_rec(begin_ptr, CGMB_SIZE, stream)) < 1) {
86     burp(stderr, "empty file %s ?\n", stream->source.file.filename);
87     return(0);
88   }
89   endin_ptr = begin_ptr + bytes_got;
90   in_ptr = begin_ptr;
91   return(1);
92 }
93
94 /* function to get a number of binary format bytes */
95 static int get_b_bytes(unsigned char *out_ptr,
96                        int bytes_wanted, _DtGrStream *stream)
97 {
98   int bytes_got, i;
99   if (!begin_ptr) {
100     burp(stderr, "haven't opened file yet !\n");
101     return 0;
102   }
103   /* check for legitimacy */
104   if (bytes_wanted < 0) {
105     burp(stderr, "negative no of bytes requested (%d) ?\n", 
106          bytes_wanted);
107     return(0);
108   }
109   if (bytes_wanted % 2) burp(stderr, "odd %d bytes ?\n", bytes_wanted);
110   
111   /* move over bytes from input buffer */
112   for (i=0; (bytes_wanted > 0) && (in_ptr < endin_ptr); ++i) {
113     *out_ptr++ = *in_ptr++;
114     --bytes_wanted;
115   }
116   if (!bytes_wanted) return(1);         /* finished */
117   
118   /* get some more */
119   while (bytes_wanted >= CGMB_SIZE) {   /* read 'em straight in */
120     if ((bytes_got = get_cgm_rec(out_ptr, CGMB_SIZE, stream)) < 1) {
121       burp(stderr, "couldn't get bytes in get_b_bytes\n");
122       return(0);
123     }
124     out_ptr += bytes_got;
125     bytes_wanted -= bytes_got;
126   }
127   /* buffer the rest */
128   while (bytes_wanted > 0) {
129     if ((bytes_got = get_cgm_rec(begin_ptr, CGMB_SIZE, stream)) < 1) {
130       burp(stderr, "couldn't get buffered bytes in get_b_bytes\n");
131       return(0);
132     }
133     /* realign the pointers */
134     endin_ptr = begin_ptr + bytes_got;
135     in_ptr = begin_ptr;
136     /* move over bytes from input buffer */
137     for (i=0; (bytes_wanted > 0) && (in_ptr < endin_ptr); ++i) {
138       *out_ptr++ = *in_ptr++;
139       --bytes_wanted;
140     }
141   }
142   
143   
144   return(1);
145 }
146
147 /* function to input a complete CGM Binary command */
148 unsigned char *get_b_cmd(struct cmd_info_s *cmd_ptr, _DtGrStream *stream)
149 {
150 #define INIT_MEM (50 * 1024)    /* initial allocation */
151   static unsigned char *mem_ptr = NULL;
152   static int mem_allocated;
153   int data_left, new_len;
154   
155   /* if first time in, get the initial memory allocation */
156   if ((!mem_ptr) && (!(mem_ptr = (unsigned char *) malloc(INIT_MEM)))) {
157     burp(stderr, "couldn't allocate initial memory for get_b_cmd\n");
158     return(NULL);
159   } else mem_allocated = INIT_MEM;
160   
161   /* get the next two bytes */
162   if (!get_b_bytes(mem_ptr, 2, stream)) {
163     burp(stderr, "trouble getting first 2 bytes of command\n");
164     return(NULL);
165   }
166   /* mark the position */
167   cmd_ptr->byte_no = bytes_read - (endin_ptr - in_ptr) - 2;
168   
169   /* now decipher the command header (lots of magic numbers !)*/
170   cmd_ptr->Class = (int) ((mem_ptr[0] >> 4) & 15);
171   cmd_ptr->element = (int) (((mem_ptr[0] << 3) & 127) |
172                             ((mem_ptr[1] >> 5) & 7));
173   cmd_ptr->p_len = (int) (mem_ptr[1] & 31);
174
175   /* is this a short form command ? */
176   if (cmd_ptr->p_len < 31) {
177     if (!get_b_bytes(mem_ptr, (cmd_ptr->p_len % 2) ? 
178                      cmd_ptr->p_len + 1 : cmd_ptr->p_len, stream)) {
179       burp(stderr, "trouble with get_b_bytes\n");
180       return(NULL);
181     } else return(mem_ptr);     /* all done */
182   } else {                              /* long form */
183     data_left = 1;
184     cmd_ptr->p_len = 0;                 /* start fresh */
185     while (data_left) {         /* some data still to get */
186       /* need the next two bytes */
187       if (!get_b_bytes(mem_ptr + cmd_ptr->p_len, 2, stream)) {
188         burp(stderr, "trouble with get_b_bytes\n");
189         return(NULL);
190       }
191       /* how much to come ? */
192       new_len = (int) (((mem_ptr[cmd_ptr->p_len] & 127) << 8) | 
193                        mem_ptr[cmd_ptr->p_len + 1]);
194       if (new_len % 2) ++new_len;       /* round up */
195       /* any more to come ? */
196       data_left = (mem_ptr[cmd_ptr->p_len] >> 7) & 1;
197       /* do we have enough room ? */
198       if ((cmd_ptr->p_len + new_len) > mem_allocated) {
199         if (!(mem_ptr = (unsigned char *)
200               realloc(mem_ptr,  mem_allocated = cmd_ptr->p_len + new_len))) {
201           burp(stderr, "couldn't get %d bytes in get_b_cmd\n",
202                mem_allocated);
203           return(NULL);
204         } else if (io_debug)
205           burp(stderr, "increasing to %d bytes allocated\n", mem_allocated);
206       }
207       /* get the bytes needed */
208       if (!get_b_bytes(mem_ptr + cmd_ptr->p_len, new_len, stream)) {
209         burp(stderr, "couldn't get next %d bytes in get_b_cmd\n",
210              new_len);
211         return(NULL);
212       }
213       cmd_ptr->p_len += new_len;
214     }
215   }
216   return(mem_ptr);              /* all done */
217 #undef INIT_MEM
218 }