bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / tomcat-connectors-1.2.32-src / native / common / jk_msg_buff.c
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17
18 /***************************************************************************
19  * Description: Data marshaling. XDR like                                  *
20  * Author:      Costin <costin@costin.dnt.ro>                              *
21  * Author:      Gal Shachor <shachor@il.ibm.com>                           *
22  * Author:      Henri Gomez <hgomez@apache.org>                            *
23  * Version:     $Revision: 705882 $                                          *
24  ***************************************************************************/
25
26 #include "jk_pool.h"
27 #include "jk_connect.h"
28 #include "jk_util.h"
29 #include "jk_sockbuf.h"
30 #include "jk_msg_buff.h"
31 #include "jk_logger.h"
32
33 static char *jk_HEX = "0123456789ABCDEFX";
34
35 /*
36  * Simple marshaling code.
37  */
38
39 void jk_b_reset(jk_msg_buf_t *msg)
40 {
41     msg->len = 4;
42     msg->pos = 4;
43     if (msg->buf && msg->maxlen) {
44         /* Clear the message buffer */
45         memset(msg->buf, 0, msg->maxlen);
46     }
47 }
48
49 int jk_b_append_long(jk_msg_buf_t *msg, unsigned long val)
50 {
51     if (msg->len + 4 > msg->maxlen) {
52         return -1;
53     }
54
55     msg->buf[msg->len++] = (unsigned char)((val >> 24) & 0xFF);
56     msg->buf[msg->len++] = (unsigned char)((val >> 16) & 0xFF);
57     msg->buf[msg->len++] = (unsigned char)((val >> 8) & 0xFF);
58     msg->buf[msg->len++] = (unsigned char)((val) & 0xFF);
59
60     return 0;
61 }
62
63
64 int jk_b_append_int(jk_msg_buf_t *msg, unsigned short val)
65 {
66     if (msg->len + 2 > msg->maxlen) {
67         return -1;
68     }
69
70     msg->buf[msg->len++] = (unsigned char)((val >> 8) & 0xFF);
71     msg->buf[msg->len++] = (unsigned char)((val) & 0xFF);
72
73     return 0;
74 }
75
76
77 int jk_b_append_byte(jk_msg_buf_t *msg, unsigned char val)
78 {
79     if (msg->len + 1 > msg->maxlen) {
80         return -1;
81     }
82
83     msg->buf[msg->len++] = val;
84
85     return 0;
86 }
87
88
89 void jk_b_end(jk_msg_buf_t *msg, int protoh)
90 {
91     /*
92      * Ugly way to set the size in the right position
93      */
94     int hlen = msg->len - 4;
95
96     msg->buf[0] = (unsigned char)((protoh >> 8) & 0xFF);
97     msg->buf[1] = (unsigned char)((protoh) & 0xFF);
98     msg->buf[2] = (unsigned char)((hlen >> 8) & 0xFF);
99     msg->buf[3] = (unsigned char)((hlen) & 0xFF);
100
101 }
102
103
104 jk_msg_buf_t *jk_b_new(jk_pool_t *p)
105 {
106     jk_msg_buf_t *msg =
107         (jk_msg_buf_t *)jk_pool_alloc(p, sizeof(jk_msg_buf_t));
108
109     if (!msg) {
110         return NULL;
111     }
112     memset(msg, 0, sizeof(jk_msg_buf_t));
113     msg->pool = p;
114
115     return msg;
116 }
117
118 int jk_b_set_buffer(jk_msg_buf_t *msg, unsigned char *data, int buffSize)
119 {
120     if (!msg) {
121         return -1;
122     }
123
124     msg->len = 0;
125     msg->buf = data;
126     msg->maxlen = buffSize;
127
128     return 0;
129 }
130
131
132 int jk_b_set_buffer_size(jk_msg_buf_t *msg, int buffSize)
133 {
134     unsigned char *data = (unsigned char *)jk_pool_alloc(msg->pool, buffSize);
135
136     if (!data) {
137         return -1;
138     }
139
140     jk_b_set_buffer(msg, data, buffSize);
141     return 0;
142 }
143
144 #if defined(AS400) && !defined(AS400_UTF8)
145 int jk_b_append_asciistring(jk_msg_buf_t *msg, const char *param)
146 {
147     int len;
148
149     if (!param) {
150         jk_b_append_int(msg, 0xFFFF);
151         return 0;
152     }
153
154     len = strlen(param);
155     if (msg->len + len + 2 > msg->maxlen) {
156         return -1;
157     }
158
159     /* ignore error - we checked once */
160     jk_b_append_int(msg, (unsigned short)len);
161
162     /* We checked for space !!  */
163     strncpy((char *)msg->buf + msg->len, param, len + 1);       /* including \0 */
164     msg->len += len + 1;
165
166     return 0;
167 }
168 #endif
169
170 int jk_b_append_string(jk_msg_buf_t *msg, const char *param)
171 {
172     unsigned short len;
173
174     if (!param) {
175         jk_b_append_int(msg, 0xFFFF);
176         return 0;
177     }
178
179     len = (unsigned short)strlen(param);
180     if (msg->len + len + 3 > msg->maxlen) {
181         return -1;
182     }
183
184     /* ignore error - we checked once */
185     jk_b_append_int(msg, len);
186
187     /* We checked for space !!  */
188     memcpy(msg->buf + msg->len, param, len + 1); /* including \0 */
189 #if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX)
190     /* convert from EBCDIC if needed */
191     jk_xlate_to_ascii((char *)msg->buf + msg->len, len + 1);
192 #endif
193     msg->len += len + 1;
194
195     return 0;
196 }
197
198
199 int jk_b_append_bytes(jk_msg_buf_t *msg, const unsigned char *param, int len)
200 {
201     if (!len) {
202         return 0;
203     }
204
205     if (msg->len + len > msg->maxlen) {
206         return -1;
207     }
208
209     /* We checked for space !!  */
210     memcpy((char *)msg->buf + msg->len, param, len);
211     msg->len += len;
212
213     return 0;
214 }
215
216 unsigned long jk_b_get_long(jk_msg_buf_t *msg)
217 {
218     unsigned long i;
219     if (msg->pos + 3 > msg->len) {
220         return 0xFFFFFFFF;
221     }
222     i = ((msg->buf[(msg->pos++)] & 0xFF) << 24);
223     i |= ((msg->buf[(msg->pos++)] & 0xFF) << 16);
224     i |= ((msg->buf[(msg->pos++)] & 0xFF) << 8);
225     i |= ((msg->buf[(msg->pos++)] & 0xFF));
226     return i;
227 }
228
229 unsigned long jk_b_pget_long(jk_msg_buf_t *msg, int pos)
230 {
231     unsigned long i;
232     i = ((msg->buf[(pos++)] & 0xFF) << 24);
233     i |= ((msg->buf[(pos++)] & 0xFF) << 16);
234     i |= ((msg->buf[(pos++)] & 0xFF) << 8);
235     i |= ((msg->buf[(pos)] & 0xFF));
236     return i;
237 }
238
239
240 unsigned short jk_b_get_int(jk_msg_buf_t *msg)
241 {
242     unsigned short i;
243     if (msg->pos + 1 > msg->len) {
244         return 0xFFFF;
245     }
246     i = ((msg->buf[(msg->pos++)] & 0xFF) << 8);
247     i += ((msg->buf[(msg->pos++)] & 0xFF));
248     return i;
249 }
250
251 unsigned short jk_b_pget_int(jk_msg_buf_t *msg, int pos)
252 {
253     unsigned short i;
254     i = ((msg->buf[pos++] & 0xFF) << 8);
255     i += ((msg->buf[pos] & 0xFF));
256     return i;
257 }
258
259 unsigned char jk_b_get_byte(jk_msg_buf_t *msg)
260 {
261     unsigned char rc;
262     if (msg->pos > msg->len) {
263         return 0xFF;
264     }
265     rc = msg->buf[msg->pos++];
266
267     return rc;
268 }
269
270 unsigned char jk_b_pget_byte(jk_msg_buf_t *msg, int pos)
271 {
272     return msg->buf[pos];
273 }
274
275
276 unsigned char *jk_b_get_string(jk_msg_buf_t *msg)
277 {
278     unsigned short size = jk_b_get_int(msg);
279     int start = msg->pos;
280
281     if ((size == 0xFFFF) || (size + start > msg->maxlen)) {
282         /* Error of overflow in AJP packet.
283          * The complete message is probably invalid.
284          */
285         return NULL;
286     }
287
288     msg->pos += size;
289     msg->pos++;                 /* terminating NULL */
290
291     return (unsigned char *)(msg->buf + start);
292 }
293
294 int jk_b_get_bytes(jk_msg_buf_t *msg, unsigned char *buf, int len)
295 {
296     int start = msg->pos;
297
298     if ((len < 0) || (len + start > msg->maxlen)) {
299         return (-1);
300     }
301
302     memcpy(buf, msg->buf + start, len);
303     msg->pos += len;
304     return (len);
305 }
306
307
308
309 /** Helpie dump function
310  */
311 void jk_dump_buff(jk_logger_t *l,
312                   const char *file,
313                   int line, const char *funcname,
314                   int level, char *what, jk_msg_buf_t *msg)
315 {
316     int i = 0;
317     char lb[80];
318     char *current;
319     int j;
320     int len = msg->len;
321
322     if (l == NULL)
323         return;
324     if (l->level != JK_LOG_TRACE_LEVEL && len > 1024)
325         len = 1024;
326
327     jk_log(l, file, line, funcname, level,
328            "%s pos=%d len=%d max=%d",
329            what, msg->pos, msg->len, msg->maxlen);
330
331     for (i = 0; i < len; i += 16) {
332         current = &lb[0];
333
334         for (j = 0; j < 16; j++) {
335             unsigned char x = (msg->buf[i + j]);
336             if ((i + j) >= len)
337                 x = 0;
338             *current++ = jk_HEX[x >> 4];
339             *current++ = jk_HEX[x & 0x0f];
340             *current++ = ' ';
341         }
342         *current++ = ' ';
343         *current++ = '-';
344         *current++ = ' ';
345         for (j = 0; j < 16; j++) {
346             unsigned char x = msg->buf[i + j];
347             if ((i + j) >= len)
348                 x = 0;
349             if (x > 0x20 && x < 0x7F) {
350 #ifdef USE_CHARSET_EBCDIC
351                *current = x;
352                jk_xlate_from_ascii(current, 1);
353                current++;
354 #else
355               *current++ = x;
356 #endif
357             }
358             else {
359                 *current++ = '.';
360             }
361         }
362         *current++ = '\0';
363
364             jk_log(l, file, line, funcname, level,
365                    "%.4x    %s", i, lb);
366     }
367 }
368
369
370 int jk_b_copy(jk_msg_buf_t *smsg, jk_msg_buf_t *dmsg)
371 {
372     if (smsg == NULL || dmsg == NULL)
373         return (-1);
374
375     if (dmsg->maxlen < smsg->len)
376         return (-2);
377
378     memcpy(dmsg->buf, smsg->buf, smsg->len);
379     dmsg->len = smsg->len;
380
381     return (smsg->len);
382 }