Kannel: Open Source WAP and SMS gateway  svn-r5335
wsbc.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2018 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  *
59  * wsbc.c
60  *
61  * Author: Markku Rossi <mtr@iki.fi>
62  *
63  * Copyright (c) 1999-2000 WAPIT OY LTD.
64  * All rights reserved.
65  *
66  * Byte-code handling functions.
67  *
68  */
69 
70 #include "wsint.h"
71 #include "wsbc.h"
72 
73 /********************* Prototypes for static functions ******************/
74 
75 /* Add a new pragma of type `type' to the byte-code `bc'. The
76  * function returns a pointer to an internal pragma structure that
77  * must not be freed by the caller. It is freed when the byte-code
78  * `bc' is freed. The function returns NULL if the pragma structure
79  * could not be allocated. */
81 
82 /********************* Manipulating byte-code structure *****************/
83 
85 {
86  WsBc *bc = ws_calloc(1, sizeof(WsBc));
87 
88  if (bc == NULL)
89  return NULL;
90 
91  bc->string_encoding = string_encoding;
92 
93  return bc;
94 }
95 
96 
97 void ws_bc_free(WsBc *bc)
98 {
99  WsUInt16 i;
100  WsUInt8 j;
101 
102  if (bc == NULL)
103  return;
104 
105  /* Free constants. */
106  for (i = 0; i < bc->num_constants; i++) {
107  WsBcConstant *c = &bc->constants[i];
108 
110  ws_free(c->u.v_string.data);
111  }
112  ws_free(bc->constants);
113 
114  /* Free pragmas. */
115  ws_free(bc->pragmas);
116 
117  /* Free function names. */
118  for (j = 0; j < bc->num_function_names; j++)
119  ws_free(bc->function_names[j].name);
120  ws_free(bc->function_names);
121 
122  /* Free functions. */
123  for (j = 0; j < bc->num_functions; j++)
124  ws_free(bc->functions[j].code);
125  ws_free(bc->functions);
126 
127  /* Free the byte-code structure. */
128  ws_free(bc);
129 }
130 
131 
132 WsBool ws_bc_encode(WsBc *bc, unsigned char **data_return,
133  size_t *data_len_return)
134 {
135  WsBuffer buffer;
136  WsUInt32 ui;
137  unsigned char data[64];
138  unsigned char *p, *mb;
139  size_t len;
140 
141  ws_buffer_init(&buffer);
142 
143  /* Append space for the header. We do not know yet the size of the
144  resulting byte-code. */
145  if (!ws_buffer_append_space(&buffer, NULL, WS_BC_MAX_HEADER_LEN))
146  goto error;
147 
148 
149  /* Constants. */
150 
151  if (!ws_encode_buffer(&buffer,
154  WS_ENC_END))
155  goto error;
156 
157  for (ui = 0 ; ui < bc->num_constants; ui++) {
158  switch (bc->constants[ui].type) {
160  if (WS_INT8_MIN <= bc->constants[ui].u.v_int
161  && bc->constants[ui].u.v_int <= WS_INT8_MAX) {
162  if (!ws_encode_buffer(&buffer,
164  WS_ENC_INT8,
165  (WsInt8) bc->constants[ui].u.v_int,
166  WS_ENC_END))
167  goto error;
168  } else if (WS_INT16_MIN <= bc->constants[ui].u.v_int
169  && bc->constants[ui].u.v_int <= WS_INT16_MAX) {
170  if (!ws_encode_buffer(&buffer,
172  WS_ENC_INT16,
173  (WsInt16) bc->constants[ui].u.v_int,
174  WS_ENC_END))
175  goto error;
176  } else {
177  if (!ws_encode_buffer(&buffer,
179  WS_ENC_INT32, bc->constants[ui].u.v_int,
180  WS_ENC_END))
181  goto error;
182  }
183  break;
184 
189  switch (bc->constants[ui].type) {
192  p = data;
193  break;
194 
196  p = ws_ieee754_nan;
197  break;
198 
201  break;
202 
205  break;
206 
207  default:
208  ws_fatal("ws_bc_encode(): internal inconsistency");
209  /* NOTREACHED */
210  p = NULL; /* Initialized to keep compiler quiet. */
211  break;
212  }
213 
214  if (!ws_encode_buffer(&buffer,
216  WS_ENC_DATA, p, 4,
217  WS_ENC_END))
218  goto error;
219  break;
220 
221  break;
222 
224  /* Encode the strings as requested. */
225  switch (bc->string_encoding) {
227  {
228  WsUtf8String *string = ws_utf8_alloc();
229  unsigned char *latin1;
230  size_t latin1_len;
231  WsBool success;
232 
233  if (string == NULL)
234  goto error;
235 
236  /* Create an UTF-8 string. */
237  if (!ws_utf8_set_data(string,
238  bc->constants[ui].u.v_string.data,
239  bc->constants[ui].u.v_string.len)) {
240  ws_utf8_free(string);
241  goto error;
242  }
243 
244  /* Convert it to latin1. */
245  latin1 = ws_utf8_to_latin1(string, '?', &latin1_len);
246 
247  /* We'r done with the UTF-8 string. */
248  ws_utf8_free(string);
249 
250  if (latin1 == NULL)
251  goto error;
252 
253  /* Encode it. */
254  success = ws_encode_buffer(
255  &buffer,
256  WS_ENC_UINT8,
258 
259  WS_ENC_MB_UINT32, (WsUInt32) latin1_len,
260  WS_ENC_DATA, latin1, latin1_len,
261 
262  WS_ENC_END);
264 
265  if (!success)
266  goto error;
267  }
268  break;
269 
271  if (!ws_encode_buffer(
272  &buffer,
273  WS_ENC_UINT8,
275 
277  (WsUInt32) bc->constants[ui].u.v_string.len,
278 
279  WS_ENC_DATA,
280  bc->constants[ui].u.v_string.data,
281  bc->constants[ui].u.v_string.len,
282 
283  WS_ENC_END))
284  goto error;
285  break;
286  }
287  break;
288 
290  if (!ws_encode_buffer(&buffer,
291  WS_ENC_UINT8,
293  WS_ENC_END))
294  goto error;
295  break;
296  }
297  }
298 
299 
300  /* Pragmas. */
301 
302  if (!ws_encode_buffer(&buffer,
304  WS_ENC_END))
305  goto error;
306 
307  for (ui = 0; ui < bc->num_pragmas; ui++) {
308  switch (bc->pragmas[ui].type) {
310  if (!ws_encode_buffer(&buffer,
311  WS_ENC_UINT8,
313 
315  WS_ENC_END))
316  goto error;
317  break;
318 
320  if (!ws_encode_buffer(&buffer,
321  WS_ENC_UINT8,
324  WS_ENC_END))
325  goto error;
326  break;
327 
329  if (!ws_encode_buffer(&buffer,
330  WS_ENC_UINT8,
334  WS_ENC_END))
335  goto error;
336  break;
337 
339  if (!ws_encode_buffer(
340  &buffer,
341  WS_ENC_UINT8,
346  WS_ENC_END))
347  goto error;
348  break;
349  }
350  }
351 
352 
353  /* Function pool. */
354 
355  if (!ws_encode_buffer(&buffer,
357  WS_ENC_END))
358  goto error;
359 
360  /* Function names. */
361 
362  if (!ws_encode_buffer(&buffer,
364  WS_ENC_END))
365  goto error;
366 
367  for (ui = 0; ui < bc->num_function_names; ui++) {
368  size_t name_len = strlen(bc->function_names[ui].name);
369 
370  if (!ws_encode_buffer(&buffer,
374  WS_ENC_END))
375  goto error;
376  }
377 
378  /* Functions. */
379 
380  for (ui = 0; ui < bc->num_functions; ui++) {
381  if (!ws_encode_buffer(&buffer,
385  WS_ENC_DATA, bc->functions[ui].code,
386  (size_t) bc->functions[ui].code_size,
387  WS_ENC_END))
388  goto error;
389  }
390 
391 
392  /* Fix the byte-code header. */
393 
394  p = ws_buffer_ptr(&buffer);
395 
396  /* Encode the size of the byte-code excluding the byte-code header. */
398  data, &len);
399  memcpy(p + WS_BC_MAX_HEADER_LEN - len, mb, len);
400 
401  /* Set the byte-code file version information. */
403 
404  /* Calculate the beginning of the bc-array and its size. */
405  *data_return = p + WS_BC_MAX_HEADER_LEN - len - 1;
406  *data_len_return = ws_buffer_len(&buffer) - WS_BC_MAX_HEADER_LEN + len + 1;
407 
408  /* All done. */
409  return WS_TRUE;
410 
411 
412  /*
413  * Error handling.
414  */
415 
416 error:
417 
418  ws_buffer_uninit(&buffer);
419  *data_return = NULL;
420  *data_len_return = 0;
421 
422  return WS_FALSE;
423 }
424 
425 
426 void ws_bc_data_free(unsigned char *data)
427 {
428  size_t len = WS_MB_UINT32_MAX_ENCODED_LEN;
429 
430  if (data == NULL)
431  return;
432 
433  /* Decode the mb-encoded length so we know how much space it uses. */
434  (void) ws_decode_mb_uint32(data + 1, &len);
435 
436  /* Now we can compute the beginning of the array `data'. */
437  ws_free(data - (WS_MB_UINT32_MAX_ENCODED_LEN - len));
438 }
439 
440 
441 /* A helper macro to update the data pointers during the decoding of
442  byte-code data. */
443 #define WS_UPDATE_DATA \
444  data += decoded; \
445  data_len -= decoded
446 
447 /* A helper macro to check the validity of the constant string index
448  `idx'. */
449 #define WS_CHECK_STRING(idx) \
450  if ((idx) >= bc->num_constants \
451  || ((bc->constants[(idx)].type \
452  != WS_BC_CONST_TYPE_UTF8_STRING) \
453  && (bc->constants[(idx)].type \
454  != WS_BC_CONST_TYPE_EMPTY_STRING))) \
455  goto error;
456 
457 WsBc *ws_bc_decode(const unsigned char *data, size_t data_len)
458 {
460  WsByte b;
461  WsUInt32 ui32;
462  WsUInt16 ui16, j;
463  WsUInt16 ui16b;
464  WsUInt8 ui8, num_functions, k, l;
465  WsInt8 i8;
466  WsInt16 i16;
467  WsInt32 i32;
468  WsIeee754Result ieee754;
469  unsigned char *ucp;
470  size_t decoded;
471 
472  /* Decode the byte-code header. */
473  decoded = ws_decode_buffer(data, data_len,
474  WS_ENC_BYTE, &b,
475  WS_ENC_MB_UINT32, &ui32,
476  WS_ENC_END);
477 
478  if (!decoded
479  || b != WS_BC_VERSION
480  || ui32 != data_len - decoded)
481  /* This is not a valid (or supported) byte-code header. */
482  goto error;
483 
485 
486  /* Constant pool. */
487 
488  decoded = ws_decode_buffer(data, data_len,
489  WS_ENC_MB_UINT16, &ui16,
490  WS_ENC_MB_UINT16, &ui16b,
491  WS_ENC_END);
492  if (!decoded)
493  goto error;
494 
495  bc->string_encoding = ui16b;
496 
497  bc->constants = ws_calloc(ui16, sizeof(WsBcConstant));
498  if (bc->constants == NULL)
499  goto error;
500  bc->num_constants = ui16;
501 
503 
504  for (j = 0; j < bc->num_constants; j++) {
505  WsBcConstant *c = &bc->constants[j];
506 
507  decoded = ws_decode_buffer(data, data_len,
508  WS_ENC_UINT8, &ui8,
509  WS_ENC_END);
510  if (decoded != 1)
511  goto error;
512 
514 
515  switch (ui8) {
516  case WS_BC_CONST_INT8:
517  decoded = ws_decode_buffer(data, data_len,
518  WS_ENC_INT8, &i8,
519  WS_ENC_END);
520  if (decoded != 1)
521  goto error;
522 
524 
526  c->u.v_int = i8;
527  break;
528 
529  case WS_BC_CONST_INT16:
530  decoded = ws_decode_buffer(data, data_len,
531  WS_ENC_INT16, &i16,
532  WS_ENC_END);
533  if (decoded != 2)
534  goto error;
535 
537 
539  c->u.v_int = i16;
540  break;
541 
542  case WS_BC_CONST_INT32:
543  decoded = ws_decode_buffer(data, data_len,
544  WS_ENC_INT32, &i32,
545  WS_ENC_END);
546  if (decoded != 4)
547  goto error;
548 
550 
552  c->u.v_int = i32;
553  break;
554 
555  case WS_BC_CONST_FLOAT32:
556  decoded = ws_decode_buffer(data, data_len,
557  WS_ENC_DATA, &ucp, (size_t) 4,
558  WS_ENC_END);
559  if (decoded != 4)
560  goto error;
561 
563 
564  ieee754 = ws_ieee754_decode_single(ucp, &c->u.v_float);
565 
566  switch (ieee754) {
567  case WS_IEEE754_OK:
569  break;
570 
571  case WS_IEEE754_NAN:
573  break;
574 
577  break;
578 
581  break;
582  }
583 
584  break;
585 
587  decoded = ws_decode_buffer(data, data_len,
588  WS_ENC_MB_UINT32, &ui32,
589  WS_ENC_END);
590  if (decoded == 0)
591  goto error;
592 
594 
596  c->u.v_string.len = ui32;
597 
598  decoded = ws_decode_buffer(data, data_len,
599  WS_ENC_DATA, &ucp, c->u.v_string.len,
600  WS_ENC_END);
601  if (decoded != ui32)
602  goto error;
603 
605 
606  c->u.v_string.data = ws_memdup(ucp, ui32);
607  if (c->u.v_string.data == NULL)
608  goto error;
609 
610  /* Check the validity of the data. */
611  if (!ws_utf8_verify(c->u.v_string.data, c->u.v_string.len,
612  &c->u.v_string.num_chars))
613  goto error;
614  break;
615 
618  break;
619 
621  ws_fatal("external character encoding not implemented yet");
622  break;
623 
624  default:
625  /* Reserved. */
626  goto error;
627  break;
628  }
629  }
630 
631  /* Pragma pool. */
632 
633  decoded = ws_decode_buffer(data, data_len,
634  WS_ENC_MB_UINT16, &ui16,
635  WS_ENC_END);
636  if (!decoded)
637  goto error;
638 
639  bc->pragmas = ws_calloc(ui16, sizeof(WsBcPragma));
640  if (bc->pragmas == NULL)
641  goto error;
642  bc->num_pragmas = ui16;
643 
645 
646  for (j = 0; j < bc->num_pragmas; j++) {
647  WsBcPragma *p = &bc->pragmas[j];
648 
649  decoded = ws_decode_buffer(data, data_len,
650  WS_ENC_UINT8, &ui8,
651  WS_ENC_END);
652  if (decoded != 1)
653  goto error;
654 
656 
657  p->type = ui8;
658 
659  switch (ui8) {
661  decoded = ws_decode_buffer(data, data_len,
663  WS_ENC_END);
664  if (!decoded)
665  goto error;
666 
668  break;
669 
671  decoded = ws_decode_buffer(data, data_len,
673  WS_ENC_END);
674  if (!decoded)
675  goto error;
676 
678  break;
679 
681  decoded = ws_decode_buffer(data, data_len,
684  WS_ENC_END);
685  if (!decoded)
686  goto error;
687 
690  break;
691 
693  decoded = ws_decode_buffer(data, data_len,
697  WS_ENC_END);
698  if (!decoded)
699  goto error;
700 
704  break;
705 
706  default:
707  goto error;
708  break;
709  }
710 
712  }
713 
714  /* Function pool. */
715 
716  decoded = ws_decode_buffer(data, data_len,
717  WS_ENC_UINT8, &num_functions,
718  WS_ENC_END);
719  if (decoded != 1)
720  goto error;
721 
723 
724  /* Function names. */
725 
726  decoded = ws_decode_buffer(data, data_len,
727  WS_ENC_UINT8, &ui8,
728  WS_ENC_END);
729  if (decoded != 1)
730  goto error;
731 
733 
734  if (ui8) {
735  /* We have function names. */
736  bc->function_names = ws_calloc(ui8, sizeof(WsBcFunctionName));
737  if (bc->function_names == NULL)
738  goto error;
739  bc->num_function_names = ui8;
740 
741  for (k = 0; k < bc->num_function_names; k++) {
742  WsBcFunctionName *n = &bc->function_names[k];
743 
744  decoded = ws_decode_buffer(data, data_len,
745  WS_ENC_UINT8, &n->index,
746  WS_ENC_UINT8, &ui8,
747  WS_ENC_END);
748  if (decoded != 2)
749  goto error;
750 
752 
753  decoded = ws_decode_buffer(data, data_len,
754  WS_ENC_DATA, &ucp, (size_t) ui8,
755  WS_ENC_END);
756  if (decoded != ui8)
757  goto error;
758 
760 
761  n->name = ws_memdup(ucp, ui8);
762  if (n->name == NULL)
763  goto error;
764 
765  /* Check the validity of the name. */
766 
767  if (!ws_utf8_verify((unsigned char *) n->name, ui8, NULL))
768  goto error;
769 
770  /* Just check that the data contains only valid characters. */
771  for (l = 0; l < ui8; l++) {
772  unsigned int ch = (unsigned char) n->name[l];
773 
774  if (('a' <= ch && ch <= 'z')
775  || ('A' <= ch && ch <= 'Z')
776  || ch == '_'
777  || (l > 0 && ('0' <= ch && ch <= '9')))
778  /* Ok. */
779  continue;
780 
781  /* Invalid character in the function name. */
782  goto error;
783  }
784 
785  /* Is the index valid? */
786  if (n->index >= num_functions)
787  goto error;
788  }
789  }
790 
791  /* Functions. */
792 
793  if (num_functions) {
794  /* We have functions. */
795  bc->functions = ws_calloc(num_functions, sizeof(WsBcFunction));
796  if (bc->functions == NULL)
797  goto error;
798  bc->num_functions = num_functions;
799 
800  for (k = 0; k < bc->num_functions; k++) {
801  WsBcFunction *f = &bc->functions[k];
802 
803  decoded = ws_decode_buffer(data, data_len,
807  WS_ENC_END);
808  if (!decoded)
809  goto error;
810 
812 
813  decoded = ws_decode_buffer(data, data_len,
814  WS_ENC_DATA, &ucp, f->code_size,
815  WS_ENC_END);
816  if (decoded != f->code_size)
817  goto error;
818 
820 
821  if (f->code_size) {
822  /* It is not an empty function. */
823  f->code = ws_memdup(ucp, f->code_size);
824  if (f->code == NULL)
825  goto error;
826  }
827  }
828  }
829 
830  /* Did we process it all? */
831  if (data_len != 0)
832  goto error;
833 
834  /* All done. */
835  return bc;
836 
837  /*
838  * Error handling.
839  */
840 
841 error:
842 
843  ws_bc_free(bc);
844 
845  return NULL;
846 }
847 
848 /********************* Adding constant elements *************************/
849 
850 WsBool ws_bc_add_const_int(WsBc *bc, WsUInt16 *index_return, WsInt32 value)
851 {
852  WsUInt16 i;
853  WsBcConstant *nc;
854 
855  /* Do we already have a suitable integer constant? */
856  for (i = 0; i < bc->num_constants; i++) {
857  if (bc->constants[i].type == WS_BC_CONST_TYPE_INT
858  && bc->constants[i].u.v_int == value) {
859  *index_return = i;
860  return WS_TRUE;
861  }
862  }
863 
864  /* Must add a new constant. */
865 
866  nc = ws_realloc(bc->constants,
867  (bc->num_constants + 1) * sizeof(WsBcConstant));
868  if (nc == NULL)
869  return WS_FALSE;
870 
871  bc->constants = nc;
873  bc->constants[bc->num_constants].u.v_int = value;
874 
875  *index_return = bc->num_constants++;
876 
877  return WS_TRUE;
878 }
879 
880 
882 {
883  WsUInt16 i;
884  WsBcConstant *nc;
885 
886  /* Do we already have a suitable float32 constant? */
887  for (i = 0; i < bc->num_constants; i++) {
889  && bc->constants[i].u.v_float == value) {
890  *index_return = i;
891  return WS_TRUE;
892  }
893  }
894 
895  /* Must add a new constant. */
896 
897  nc = ws_realloc(bc->constants,
898  (bc->num_constants + 1) * sizeof(WsBcConstant));
899  if (nc == NULL)
900  return WS_FALSE;
901 
902  bc->constants = nc;
904  bc->constants[bc->num_constants].u.v_float = value;
905 
906  *index_return = bc->num_constants++;
907 
908  return WS_TRUE;
909 }
910 
911 
913  const unsigned char *data, size_t len)
914 {
915  WsUInt16 i;
916  WsBcConstant *nc;
917 
918  /* Do we already have a suitable UFT-8 constant? */
919  for (i = 0; i < bc->num_constants; i++) {
921  && bc->constants[i].u.v_string.len == len
922  && memcmp(bc->constants[i].u.v_string.data,
923  data, len) == 0) {
924  *index_return = i;
925  return WS_TRUE;
926  }
927  }
928 
929  /* Must add a new constant. */
930 
931  nc = ws_realloc(bc->constants,
932  (bc->num_constants + 1) * sizeof(WsBcConstant));
933  if (nc == NULL)
934  return WS_FALSE;
935 
936  bc->constants = nc;
938  bc->constants[bc->num_constants].u.v_string.len = len;
940  = ws_memdup(data, len);
941  if (bc->constants[bc->num_constants].u.v_string.data == NULL)
942  return WS_FALSE;
943 
944  *index_return = bc->num_constants++;
945 
946  return WS_TRUE;
947 }
948 
949 
950 
952 {
953  WsUInt16 i;
954  WsBcConstant *nc;
955 
956  /* Do we already have a suitable empty string constant? */
957  for (i = 0; i < bc->num_constants; i++) {
959  *index_return = i;
960  return WS_TRUE;
961  }
962  }
963 
964  /* Must add a new constant. */
965 
966  nc = ws_realloc(bc->constants,
967  (bc->num_constants + 1) * sizeof(WsBcConstant));
968  if (nc == NULL)
969  return WS_FALSE;
970 
971  bc->constants = nc;
973 
974  *index_return = bc->num_constants++;
975 
976  return WS_TRUE;
977 }
978 
979 /********************* Adding pragmas ***********************************/
980 
981 WsBool ws_bc_add_pragma_access_domain(WsBc *bc, const unsigned char *domain,
982  size_t domain_len)
983 {
985 
986  if (p == NULL)
987  return WS_FALSE;
988 
989  if (!ws_bc_add_const_utf8_string(bc, &p->index_1, domain, domain_len))
990  return WS_FALSE;
991 
992  return WS_TRUE;
993 }
994 
995 
996 WsBool ws_bc_add_pragma_access_path(WsBc *bc, const unsigned char *path,
997  size_t path_len)
998 {
1000 
1001  if (p == NULL)
1002  return WS_FALSE;
1003 
1004  if (!ws_bc_add_const_utf8_string(bc, &p->index_1, path, path_len))
1005  return WS_FALSE;
1006 
1007  return WS_TRUE;
1008 }
1009 
1010 
1012  const unsigned char *name,
1013  size_t name_len,
1014  const unsigned char *property,
1015  size_t property_len)
1016 {
1018 
1019  if (p == NULL)
1020  return WS_FALSE;
1021 
1023  || !ws_bc_add_const_utf8_string(bc, &p->index_2, property, property_len))
1024  return WS_FALSE;
1025 
1026  return WS_TRUE;
1027 }
1028 
1029 
1031  WsBc *bc,
1032  const unsigned char *name,
1033  size_t name_len,
1034  const unsigned char *property,
1035  size_t property_len,
1036  const unsigned char *scheme,
1037  size_t scheme_len)
1038 {
1039  WsBcPragma *p;
1040 
1042 
1043  if (p == NULL)
1044  return WS_FALSE;
1045 
1047  || !ws_bc_add_const_utf8_string(bc, &p->index_2, property, property_len)
1048  || !ws_bc_add_const_utf8_string(bc, &p->index_3, scheme, scheme_len))
1049  return WS_FALSE;
1050 
1051  return WS_TRUE;
1052 }
1053 
1054 /********************* Adding functions *********************************/
1055 
1056 WsBool ws_bc_add_function(WsBc *bc, WsUInt8 *index_return, char *name,
1057  WsUInt8 num_arguments, WsUInt8 num_locals,
1058  WsUInt32 code_size, unsigned char *code)
1059 {
1060  WsBcFunction *nf;
1061 
1062  /* First, add the function to the function pool. */
1063 
1064  nf = ws_realloc(bc->functions,
1065  (bc->num_functions + 1) * sizeof(WsBcFunction));
1066  if (nf == NULL)
1067  return WS_FALSE;
1068 
1069  bc->functions = nf;
1070  bc->functions[bc->num_functions].num_arguments = num_arguments;
1071  bc->functions[bc->num_functions].num_locals = num_locals;
1072  bc->functions[bc->num_functions].code_size = code_size;
1073  bc->functions[bc->num_functions].code = ws_memdup(code, code_size);
1074 
1075  if (bc->functions[bc->num_functions].code == NULL)
1076  return WS_FALSE;
1077 
1078  /* Save the index of the function. */
1079  *index_return = bc->num_functions++;
1080 
1081  /* For external functions (which have name), add a name entry to the
1082  function name pool. */
1083  if (name) {
1084  WsBcFunctionName *nfn;
1085 
1086  nfn = ws_realloc(bc->function_names,
1087  ((bc->num_function_names + 1)
1088  * sizeof(WsBcFunctionName)));
1089  if (nfn == NULL)
1090  return WS_FALSE;
1091 
1092  bc->function_names = nfn;
1093  bc->function_names[bc->num_function_names].index = *index_return;
1095 
1096  if (bc->function_names[bc->num_function_names].name == NULL)
1097  return WS_FALSE;
1098 
1099  bc->num_function_names++;
1100  }
1101 
1102  /* All done. */
1103  return WS_TRUE;
1104 }
1105 
1106 /********************* Static functions *********************************/
1107 
1109 {
1110  WsBcPragma *np;
1111 
1112  /* Add a new pragma slot. */
1113  np = ws_realloc(bc->pragmas, (bc->num_pragmas + 1) * sizeof(WsBcPragma));
1114  if (np == NULL)
1115  return NULL;
1116 
1117  bc->pragmas = np;
1118  bc->pragmas[bc->num_pragmas].type = type;
1119 
1120  return &bc->pragmas[bc->num_pragmas++];
1121 }
unsigned char ws_ieee754_nan[4]
Definition: wsieee754.c:86
void error(int err, const char *fmt,...)
Definition: log.c:648
void ws_fatal(char *fmt,...)
Definition: wserror.c:91
void * ws_calloc(size_t num, size_t size)
Definition: wsalloc.c:83
#define WS_PUT_UINT8(buf, val)
Definition: wsencode.h:78
WsBcConstantType type
Definition: wsbc.h:121
#define WS_BC_CONST_EMPTY_STRING
Definition: wsbc.h:102
size_t name_len
Definition: wslexer.c:158
WsUInt32 ws_decode_mb_uint32(const unsigned char *buffer, size_t *len)
Definition: wsencode.c:104
WsUInt16 num_constants
Definition: wsbc.h:194
Definition: wsint.h:131
WsIeee754Result ws_ieee754_decode_single(unsigned char *buf, double *value_return)
Definition: wsieee754.c:199
size_t len
Definition: wsutf8.h:81
#define WS_BC_CONST_UTF8_STRING
Definition: wsbc.h:101
unsigned long WsUInt32
Definition: wsint.h:122
WsBcStringEncoding string_encoding
Definition: wsbc.h:189
void ws_free(void *ptr)
Definition: wsalloc.c:139
WsBool ws_bc_add_pragma_access_domain(WsBc *bc, const unsigned char *domain, size_t domain_len)
Definition: wsbc.c:981
#define WS_BC_PRAGMA_ACCESS_DOMAIN
Definition: wsbc.h:134
WsBc * ws_bc_alloc(WsBcStringEncoding string_encoding)
Definition: wsbc.c:84
double WsFloat
Definition: wsint.h:126
unsigned char * data
Definition: wsutf8.h:84
#define WS_BC_VERSION
Definition: wsbc.h:80
WsBcFunction * functions
Definition: wsbc.h:207
int code
Definition: smsc_cimd2.c:346
WsInt32 v_int
Definition: wsbc.h:125
int type
Definition: smsc_cimd2.c:215
#define WS_BC_CONST_INT32
Definition: wsbc.h:99
#define WS_BC_CONST_FLOAT32
Definition: wsbc.h:100
WsUInt8 num_functions
Definition: wsbc.h:206
size_t ws_buffer_len(WsBuffer *buffer)
Definition: wsbuffer.c:139
#define WS_MB_UINT32_MAX_ENCODED_LEN
Definition: wsencode.h:133
WsBool ws_bc_add_pragma_access_path(WsBc *bc, const unsigned char *path, size_t path_len)
Definition: wsbc.c:996
#define WS_BC_CONST_INT8
Definition: wsbc.h:97
void * ws_realloc(void *ptr, size_t size)
Definition: wsalloc.c:89
WsIeee754Result ws_ieee754_encode_single(double value, unsigned char *buf)
Definition: wsieee754.c:94
WsIeee754Result
Definition: wsieee754.h:77
size_t ws_decode_buffer(const unsigned char *buffer, size_t buffer_len,...)
Definition: wsencode.c:222
void ws_utf8_free(WsUtf8String *string)
Definition: wsutf8.c:188
WsBcConstant * constants
Definition: wsbc.h:195
#define WS_BC_CONST_EXT_ENC_STRING
Definition: wsbc.h:103
WsBcFunctionName * function_names
Definition: wsbc.h:204
#define WS_BC_PRAGMA_USER_AGENT_PROPERTY_AND_SCHEME
Definition: wsbc.h:137
unsigned char ws_ieee754_positive_inf[4]
Definition: wsieee754.c:88
WsUtf8String v_string
Definition: wsbc.h:127
signed short WsInt16
Definition: wsint.h:118
#define WS_BC_CONST_INT16
Definition: wsbc.h:98
WsBool ws_bc_encode(WsBc *bc, unsigned char **data_return, size_t *data_len_return)
Definition: wsbc.c:132
WsFloat v_float
Definition: wsbc.h:126
unsigned char * ws_encode_mb_uint32(WsUInt32 value, unsigned char *buffer, size_t *len_return)
Definition: wsencode.c:79
#define WS_BC_PRAGMA_ACCESS_PATH
Definition: wsbc.h:135
unsigned char WsUInt8
Definition: wsint.h:116
static WsBcPragma * add_pragma(WsBc *bc, WsBcPragmaType type)
Definition: wsbc.c:1108
union WsAsmInsRec::@113 u
WsUInt8 num_function_names
Definition: wsbc.h:203
WsUtf8String * ws_utf8_alloc()
Definition: wsutf8.c:182
int ws_utf8_set_data(WsUtf8String *string, const unsigned char *data, size_t len)
Definition: wsutf8.c:266
WsBcStringEncoding
Definition: wsbc.h:90
unsigned short WsUInt16
Definition: wsint.h:119
void ws_bc_free(WsBc *bc)
Definition: wsbc.c:97
WsUInt32 code_size
Definition: wsbc.h:179
void ws_utf8_free_data(unsigned char *data)
Definition: wsutf8.c:368
WsBcPragma * pragmas
Definition: wsbc.h:199
WsBcPragmaType
Definition: wsbc.h:142
WsBool ws_bc_add_const_empty_string(WsBc *bc, WsUInt16 *index_return)
Definition: wsbc.c:951
void ws_buffer_init(WsBuffer *buffer)
Definition: wsbuffer.c:74
int latin1
Definition: charset.c:85
void * ws_memdup(const void *ptr, size_t size)
Definition: wsalloc.c:105
WsUInt16 index_2
Definition: wsbc.h:155
#define WS_CHECK_STRING(idx)
Definition: wsbc.c:449
char * name
Definition: smsc_cimd2.c:212
WsBool ws_bc_add_const_float(WsBc *bc, WsUInt16 *index_return, WsFloat value)
Definition: wsbc.c:881
void ws_bc_data_free(unsigned char *data)
Definition: wsbc.c:426
void ws_buffer_uninit(WsBuffer *buffer)
Definition: wsbuffer.c:81
WsBool ws_encode_buffer(WsBuffer *buffer,...)
Definition: wsencode.c:123
WsUInt16 index_1
Definition: wsbc.h:154
#define WS_BC_MAX_HEADER_LEN
Definition: wsbc.h:84
WsBool ws_bc_add_const_int(WsBc *bc, WsUInt16 *index_return, WsInt32 value)
Definition: wsbc.c:850
signed char WsInt8
Definition: wsint.h:115
int ws_utf8_verify(const unsigned char *data, size_t len, size_t *strlen_return)
Definition: wsutf8.c:233
WsBool
Definition: wsint.h:128
WsBool ws_bc_add_pragma_user_agent_property(WsBc *bc, const unsigned char *name, size_t name_len, const unsigned char *property, size_t property_len)
Definition: wsbc.c:1011
#define WS_BC_PRAGMA_USER_AGENT_PROPERTY
Definition: wsbc.h:136
WsBool ws_bc_add_const_utf8_string(WsBc *bc, WsUInt16 *index_return, const unsigned char *data, size_t len)
Definition: wsbc.c:912
WsUInt16 num_pragmas
Definition: wsbc.h:198
WsBool ws_buffer_append_space(WsBuffer *buffer, unsigned char **p, size_t size)
Definition: wsbuffer.c:115
union WsBcConstantRec::@116 u
WsUInt8 num_locals
Definition: wsbc.h:178
void * ws_strdup(const char *str)
Definition: wsalloc.c:119
#define WS_INT8_MAX
Definition: wsint.h:103
size_t num_chars
Definition: wsutf8.h:87
signed long WsInt32
Definition: wsint.h:121
unsigned char * code
Definition: wsbc.h:180
WsUInt16 index_3
Definition: wsbc.h:156
Definition: wsbc.h:186
WsUInt8 num_arguments
Definition: wsbc.h:177
unsigned char WsByte
Definition: wsint.h:113
WsBool ws_bc_add_pragma_user_agent_property_and_scheme(WsBc *bc, const unsigned char *name, size_t name_len, const unsigned char *property, size_t property_len, const unsigned char *scheme, size_t scheme_len)
Definition: wsbc.c:1030
WsBool ws_bc_add_function(WsBc *bc, WsUInt8 *index_return, char *name, WsUInt8 num_arguments, WsUInt8 num_locals, WsUInt32 code_size, unsigned char *code)
Definition: wsbc.c:1056
WsBc * ws_bc_decode(const unsigned char *data, size_t data_len)
Definition: wsbc.c:457
WsUInt8 index
Definition: wsbc.h:165
unsigned char * ws_buffer_ptr(WsBuffer *buffer)
Definition: wsbuffer.c:133
unsigned char ws_ieee754_negative_inf[4]
Definition: wsieee754.c:90
unsigned char * ws_utf8_to_latin1(const WsUtf8String *string, unsigned char unknown_char, size_t *len_return)
Definition: wsutf8.c:332
#define WS_UPDATE_DATA
Definition: wsbc.c:443
WsBcPragmaType type
Definition: wsbc.h:152
#define WS_INT16_MAX
Definition: wsint.h:106
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.