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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
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 ***************************************************************************/
27 #include "jk_connect.h"
29 #include "jk_sockbuf.h"
30 #include "jk_msg_buff.h"
31 #include "jk_logger.h"
33 static char *jk_HEX = "0123456789ABCDEFX";
36 * Simple marshaling code.
39 void jk_b_reset(jk_msg_buf_t *msg)
43 if (msg->buf && msg->maxlen) {
44 /* Clear the message buffer */
45 memset(msg->buf, 0, msg->maxlen);
49 int jk_b_append_long(jk_msg_buf_t *msg, unsigned long val)
51 if (msg->len + 4 > msg->maxlen) {
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);
64 int jk_b_append_int(jk_msg_buf_t *msg, unsigned short val)
66 if (msg->len + 2 > msg->maxlen) {
70 msg->buf[msg->len++] = (unsigned char)((val >> 8) & 0xFF);
71 msg->buf[msg->len++] = (unsigned char)((val) & 0xFF);
77 int jk_b_append_byte(jk_msg_buf_t *msg, unsigned char val)
79 if (msg->len + 1 > msg->maxlen) {
83 msg->buf[msg->len++] = val;
89 void jk_b_end(jk_msg_buf_t *msg, int protoh)
92 * Ugly way to set the size in the right position
94 int hlen = msg->len - 4;
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);
104 jk_msg_buf_t *jk_b_new(jk_pool_t *p)
107 (jk_msg_buf_t *)jk_pool_alloc(p, sizeof(jk_msg_buf_t));
112 memset(msg, 0, sizeof(jk_msg_buf_t));
118 int jk_b_set_buffer(jk_msg_buf_t *msg, unsigned char *data, int buffSize)
126 msg->maxlen = buffSize;
132 int jk_b_set_buffer_size(jk_msg_buf_t *msg, int buffSize)
134 unsigned char *data = (unsigned char *)jk_pool_alloc(msg->pool, buffSize);
140 jk_b_set_buffer(msg, data, buffSize);
144 #if defined(AS400) && !defined(AS400_UTF8)
145 int jk_b_append_asciistring(jk_msg_buf_t *msg, const char *param)
150 jk_b_append_int(msg, 0xFFFF);
155 if (msg->len + len + 2 > msg->maxlen) {
159 /* ignore error - we checked once */
160 jk_b_append_int(msg, (unsigned short)len);
162 /* We checked for space !! */
163 strncpy((char *)msg->buf + msg->len, param, len + 1); /* including \0 */
170 int jk_b_append_string(jk_msg_buf_t *msg, const char *param)
175 jk_b_append_int(msg, 0xFFFF);
179 len = (unsigned short)strlen(param);
180 if (msg->len + len + 3 > msg->maxlen) {
184 /* ignore error - we checked once */
185 jk_b_append_int(msg, len);
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);
199 int jk_b_append_bytes(jk_msg_buf_t *msg, const unsigned char *param, int len)
205 if (msg->len + len > msg->maxlen) {
209 /* We checked for space !! */
210 memcpy((char *)msg->buf + msg->len, param, len);
216 unsigned long jk_b_get_long(jk_msg_buf_t *msg)
219 if (msg->pos + 3 > msg->len) {
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));
229 unsigned long jk_b_pget_long(jk_msg_buf_t *msg, int pos)
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));
240 unsigned short jk_b_get_int(jk_msg_buf_t *msg)
243 if (msg->pos + 1 > msg->len) {
246 i = ((msg->buf[(msg->pos++)] & 0xFF) << 8);
247 i += ((msg->buf[(msg->pos++)] & 0xFF));
251 unsigned short jk_b_pget_int(jk_msg_buf_t *msg, int pos)
254 i = ((msg->buf[pos++] & 0xFF) << 8);
255 i += ((msg->buf[pos] & 0xFF));
259 unsigned char jk_b_get_byte(jk_msg_buf_t *msg)
262 if (msg->pos > msg->len) {
265 rc = msg->buf[msg->pos++];
270 unsigned char jk_b_pget_byte(jk_msg_buf_t *msg, int pos)
272 return msg->buf[pos];
276 unsigned char *jk_b_get_string(jk_msg_buf_t *msg)
278 unsigned short size = jk_b_get_int(msg);
279 int start = msg->pos;
281 if ((size == 0xFFFF) || (size + start > msg->maxlen)) {
282 /* Error of overflow in AJP packet.
283 * The complete message is probably invalid.
289 msg->pos++; /* terminating NULL */
291 return (unsigned char *)(msg->buf + start);
294 int jk_b_get_bytes(jk_msg_buf_t *msg, unsigned char *buf, int len)
296 int start = msg->pos;
298 if ((len < 0) || (len + start > msg->maxlen)) {
302 memcpy(buf, msg->buf + start, len);
309 /** Helpie dump function
311 void jk_dump_buff(jk_logger_t *l,
313 int line, const char *funcname,
314 int level, char *what, jk_msg_buf_t *msg)
324 if (l->level != JK_LOG_TRACE_LEVEL && len > 1024)
327 jk_log(l, file, line, funcname, level,
328 "%s pos=%d len=%d max=%d",
329 what, msg->pos, msg->len, msg->maxlen);
331 for (i = 0; i < len; i += 16) {
334 for (j = 0; j < 16; j++) {
335 unsigned char x = (msg->buf[i + j]);
338 *current++ = jk_HEX[x >> 4];
339 *current++ = jk_HEX[x & 0x0f];
345 for (j = 0; j < 16; j++) {
346 unsigned char x = msg->buf[i + j];
349 if (x > 0x20 && x < 0x7F) {
350 #ifdef USE_CHARSET_EBCDIC
352 jk_xlate_from_ascii(current, 1);
364 jk_log(l, file, line, funcname, level,
370 int jk_b_copy(jk_msg_buf_t *smsg, jk_msg_buf_t *dmsg)
372 if (smsg == NULL || dmsg == NULL)
375 if (dmsg->maxlen < smsg->len)
378 memcpy(dmsg->buf, smsg->buf, smsg->len);
379 dmsg->len = smsg->len;