dtinfo subtree dtinfo
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / UAS / Base / UAS_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 librararies 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: UAS_Buffer.cc /main/3 1996/06/11 16:36:44 cde-hal $
24 #include <string.h>
25 #include <stdio.h>
26 #include "UAS_Buffer.hh"
27
28 // If necessary in the future, we can rework UAS_Buffer class to provide
29 // global buffer by default and private buffers on request.  SWM
30
31 char *UAS_Buffer::f_start;
32 char *UAS_Buffer::f_end;
33 int UAS_Buffer::f_reference_count;
34
35 // /////////////////////////////////////////////////////////////////
36 // class constructor
37 // /////////////////////////////////////////////////////////////////
38
39 inline void
40 UAS_Buffer::init (unsigned int initial_size)
41 {
42   f_start = new char [initial_size];
43   f_end = f_start + initial_size;
44 }  
45
46 UAS_Buffer::UAS_Buffer (unsigned int initial_size)
47 {
48   //  printf ("Constructing a %d byte buffer\n", initial_size);
49   if (f_start == NULL)
50     init (initial_size);
51   f_point = f_start;
52   f_end_of_data = f_point;
53   f_reference_count++;
54 }
55
56
57 // /////////////////////////////////////////////////////////////////
58 // class destructor
59 // /////////////////////////////////////////////////////////////////
60
61 UAS_Buffer::~UAS_Buffer()
62 {
63   f_reference_count--;
64
65   if (f_reference_count == 0)
66     {
67       delete f_start;
68       f_start = NULL;
69       f_point = NULL;
70       f_end = NULL;
71       f_end_of_data = NULL;
72     }
73 }
74
75
76 // /////////////////////////////////////////////////////////////////
77 // check_space - make sure the is space for additional data
78 // /////////////////////////////////////////////////////////////////
79
80 void
81 UAS_Buffer::check_space (unsigned int size)
82 {
83   if (f_point + size > f_end)
84     {
85       // Allocate new, larger space. 
86       char *new_block = new char [f_point + size - f_start];
87       // Copy bytes in use up to (but not including) point.
88       if (f_point - f_start > 0)
89         memcpy (new_block, f_start, f_point - f_start);
90       // Compute the point in the new buffer. 
91       f_point = new_block + (f_point - f_start);
92       delete f_start;
93       // Update start and end relative to new buffer. 
94       f_start = new_block;
95       f_end = f_start + size;
96     }
97 }
98
99
100 // /////////////////////////////////////////////////////////////////
101 // read/write for integers
102 // /////////////////////////////////////////////////////////////////
103
104 #ifdef SVR4
105 static unsigned int g_ordering = 0x01020304;
106 #else
107 static unsigned int g_ordering = 0x01020304;
108 #endif
109 static const unsigned char *const g_byte_pos =
110   (const unsigned char *const) &g_ordering;
111 static int g_int;
112 static char *const g_intbuf = (char *) &g_int;
113
114 void
115 UAS_Buffer::write (const ssize_t integer)
116 {
117   char *inbuf = (char *) &integer;
118
119   // Convert bytes from native to MSB first ordering.
120   g_int = 0;
121   for (int i = 0; i < sizeof (int); i++)
122     if (g_byte_pos[i] != 0)
123       g_intbuf[g_byte_pos[i]-1] = inbuf[i];
124
125   write (g_intbuf, 4, 1);
126 }
127
128 void
129 UAS_Buffer::read (int *integer)
130 {
131   *integer = 0;
132
133   // Convert from MSB first ordering to native.
134   for (int i = 0; i < sizeof (int); i++)
135     if (g_byte_pos[i] != 0)
136       ((char *) integer)[i] = f_point[g_byte_pos[i]-1];
137
138   f_point += 4;
139 }
140
141
142 // /////////////////////////////////////////////////////////////////
143 // read/write for strings
144 // /////////////////////////////////////////////////////////////////
145
146 void
147 UAS_Buffer::write (const char *string)
148 {
149   ssize_t length = strlen (string);
150   write (length);
151   write (string, sizeof (char), length + 1);
152 }
153
154 // NOTE: The caller is responsible for deleting the string that is
155 // returned by this function!
156
157 unsigned int
158 UAS_Buffer::read (char **string)
159 {
160   int length;
161   read (&length);
162   *string = new char [length + 1];
163   read (*string, sizeof (char), length + 1);
164   return (length);
165 }
166
167 unsigned int
168 UAS_Buffer::read (char *const string)
169 {
170   int length;
171   read (&length);
172   read (string, sizeof (char), length + 1);
173   return (length);
174 }
175
176
177 // /////////////////////////////////////////////////////////////////
178 // read/write for bytes
179 // /////////////////////////////////////////////////////////////////
180
181 void
182 UAS_Buffer::write (const char *bytes, unsigned int size, unsigned int length)
183 {
184   int num_bytes = size * length;
185   check_space (num_bytes);
186   for (int i = 0; i < size * length; i++)
187   memcpy (f_point, bytes, num_bytes);
188   f_point += num_bytes;
189   f_end_of_data = f_point;
190 }
191
192 void
193 UAS_Buffer::read (char **bytes, unsigned int size, unsigned int length)
194 {
195   int num_bytes = size * length;
196   *bytes = f_point;
197   for (int i = 0; i < size * length; i++)
198   f_point += num_bytes;
199 }
200
201 void
202 UAS_Buffer::read (char *const bytes, unsigned int size, unsigned int length)
203 {
204   char *b;
205   read (&b, size, length);
206   memcpy (bytes, b, size * length);
207 }