dtinfo: remove register keyword
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / Basic / Buffer.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 /*
24  * $XConsortium: Buffer.C /main/5 1996/10/04 11:25:25 drk $
25  *
26  * Copyright (c) 1992 HaL Computer Systems, Inc.  All rights reserved.
27  * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
28  * States.  Use of a copyright notice is precautionary only and does not
29  * imply publication or disclosure.
30  * 
31  * This software contains confidential information and trade secrets of HaL
32  * Computer Systems, Inc.  Use, disclosure, or reproduction is prohibited
33  * without the prior express written permission of HaL Computer Systems, Inc.
34  * 
35  *                         RESTRICTED RIGHTS LEGEND
36  * Use, duplication, or disclosure by the Government is subject to
37  * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
38  * Technical Data and Computer Software clause at DFARS 252.227-7013.
39  *                        HaL Computer Systems, Inc.
40  *                  1315 Dell Avenue, Campbell, CA  95008
41  * 
42  */
43
44 #define C_Buffer
45 #define L_Basic
46
47 #include "Prelude.h"
48
49 #include <string.h>
50
51 // If necessary in the future, we can rework Buffer class to provide
52 // global buffer by default and private buffers on request.  DJB 
53
54 char *Buffer::f_start;
55 char *Buffer::f_end;
56 int Buffer::f_reference_count;
57
58 // /////////////////////////////////////////////////////////////////
59 // class constructor
60 // /////////////////////////////////////////////////////////////////
61
62 inline void
63 Buffer::init (u_int initial_size)
64 {
65   f_start = new char [initial_size];
66   f_end = f_start + initial_size;
67 }  
68
69 Buffer::Buffer (u_int initial_size)
70 {
71   //  printf ("Constructing a %d byte buffer\n", initial_size);
72   if (f_start == NULL)
73     init (initial_size);
74   f_point = f_start;
75   f_end_of_data = f_point;
76   f_reference_count++;
77 }
78
79
80 // /////////////////////////////////////////////////////////////////
81 // class destructor
82 // /////////////////////////////////////////////////////////////////
83
84 Buffer::~Buffer()
85 {
86   f_reference_count--;
87
88   if (f_reference_count == 0)
89     {
90       delete[] f_start;
91       f_start = NULL;
92       f_point = NULL;
93       f_end = NULL;
94       f_end_of_data = NULL;
95     }
96 }
97
98
99 // /////////////////////////////////////////////////////////////////
100 // check_space - make sure the is space for additional data
101 // /////////////////////////////////////////////////////////////////
102
103 void
104 Buffer::check_space (u_int size)
105 {
106   assert (f_start != NULL);
107   assert (f_point != NULL);
108   assert (f_end != NULL);
109   assert (f_end_of_data != NULL);
110   if (f_point + size > f_end)
111     {
112       // Allocate new, larger space. 
113       char *new_block = new char [f_point + size - f_start];
114       // Copy bytes in use up to (but not including) point.
115       if (f_point - f_start > 0)
116         memcpy (new_block, f_start, f_point - f_start);
117       // Compute the point in the new buffer. 
118       f_point = new_block + (f_point - f_start);
119       delete f_start;
120       // Update start and end relative to new buffer. 
121       f_start = new_block;
122       f_end = f_start + size;
123     }
124 }
125
126
127 // /////////////////////////////////////////////////////////////////
128 // read/write for integers
129 // /////////////////////////////////////////////////////////////////
130
131 #ifdef SVR4
132 static u_int g_ordering = 0x01020304;
133 #else
134 static u_int g_ordering = 0x01020304;
135 #endif
136 static const unsigned char *const g_byte_pos =
137   (const unsigned char *const) &g_ordering;
138 static int g_int;
139 static char *const g_intbuf = (char *) &g_int;
140
141 void
142 Buffer::write (const int integer)
143 {
144   char *inbuf = (char *) &integer;
145
146   // Convert bytes from native to MSB first ordering.
147   g_int = 0;
148   for (unsigned int i = 0; i < sizeof (int); i++)
149     if (g_byte_pos[i] != 0)
150       g_intbuf[g_byte_pos[i]-1] = inbuf[i];
151
152   write (g_intbuf, 4, 1);
153 }
154
155 void
156 Buffer::read (int *integer)
157 {
158   *integer = 0;
159
160   // Convert from MSB first ordering to native.
161   for (unsigned int i = 0; i < sizeof (int); i++)
162     if (g_byte_pos[i] != 0)
163       ((char *) integer)[i] = f_point[g_byte_pos[i]-1];
164
165   f_point += 4;
166   assert (f_point <= f_end_of_data);
167 }
168
169
170 // /////////////////////////////////////////////////////////////////
171 // read/write for strings
172 // /////////////////////////////////////////////////////////////////
173
174 void
175 Buffer::write (const char *string)
176 {
177   int length = strlen (string);
178   write (length);
179   write (string, sizeof (char), length + 1);
180 }
181
182 // NOTE: The caller is responsible for deleting the string that is
183 // returned by this function!
184
185 u_int
186 Buffer::read (char **string)
187 {
188   int length;
189   read (&length);
190   ON_DEBUG(printf ("Reading a %d byte string\n", length));
191   *string = new char [length + 1];
192   read (*string, sizeof (char), length + 1);
193   ON_DEBUG(printf ("String read is actually %ld bytes\n", (long)strlen(*string)));
194   assert (length == strlen (*string));
195   ON_DEBUG(printf ("Read string <%s>\n", *string));
196   return (length);
197 }
198
199 u_int
200 Buffer::read (char *const string)
201 {
202   int length;
203   read (&length);
204   read (string, sizeof (char), length + 1);
205   assert (length == strlen (string));
206   return (length);
207 }
208
209
210 // /////////////////////////////////////////////////////////////////
211 // read/write for bytes
212 // /////////////////////////////////////////////////////////////////
213
214 void
215 Buffer::write (const char *bytes, u_int size, u_int length)
216 {
217   ON_DEBUG(printf ("Writing %d bytes to buffer @ %p\n", size * length, f_point));
218   int num_bytes = size * length;
219   check_space (num_bytes);
220   for (unsigned int i = 0; i < size * length; i++)
221     ON_DEBUG(printf ("%02X ", (unsigned char) bytes[i]));
222   ON_DEBUG(printf ("\n"));
223   memcpy (f_point, bytes, num_bytes);
224   f_point += num_bytes;
225   f_end_of_data = f_point;
226 }
227
228 void
229 Buffer::read (char **bytes, u_int size, u_int length)
230 {
231   int num_bytes = size * length;
232   ON_DEBUG(printf ("Reading %d bytes from buffer @ %p\n", num_bytes, f_point));
233   assert (f_point + num_bytes <= f_end_of_data);
234   *bytes = f_point;
235   for (unsigned int i = 0; i < size * length; i++)
236     ON_DEBUG(printf ("%02X ", (unsigned int) (*bytes)[i]));
237   ON_DEBUG(printf ("\n"));
238   f_point += num_bytes;
239 }
240
241 void
242 Buffer::read (char *const bytes, u_int size, u_int length)
243 {
244   char *b;
245   read (&b, size, length);
246   memcpy (bytes, b, size * length);
247 }