3 * Copyright (C) 2007, The Perl Foundation.
7 #include "parrot/parrot.h"
12 static int class_TclFloat
= 0;
13 static int class_TclInt
= 0;
14 static int class_TclList
= 0;
15 static int class_TclString
= 0;
21 languages/tcl/src/binary.c
32 extract_int(char *str, int *pos, int length)>
34 Extract an integer from the string at the position given. Return the integer
35 and update the position. Returns 1 if no digit is found or if the int is
42 extract_int(char *str
, int *pos
, int length
)
46 while (*pos
< length
&& isdigit((unsigned char)str
[*pos
]))
47 n
= 10*n
+ (str
[(*pos
)++] - '0');
58 binary_scan_number_field(PARROT_INTERP, char field, char *binstr, int *_pos, int length)>
60 Scan and remove a number from a binary string. Return a PMC representing
67 binary_scan_number_field(PARROT_INTERP
, char field
, char *binstr
, int *_pos
, int length
)
83 c
= (char *)(binstr
+ pos
);
84 value
= pmc_new(interp
, class_TclInt
);
85 VTABLE_set_integer_native(interp
, value
, (INTVAL
)*c
);
90 len
= sizeof (double)/sizeof (char);
91 if (pos
+ len
> length
)
93 d
= (double *)(binstr
+ pos
);
94 value
= pmc_new(interp
, class_TclFloat
);
95 VTABLE_set_number_native(interp
, value
, *d
);
100 len
= sizeof (float)/sizeof (char);
101 if (pos
+ len
> length
)
103 f
= (float *)(binstr
+ pos
);
104 value
= pmc_new(interp
, class_TclFloat
);
105 VTABLE_set_number_native(interp
, value
, *f
);
110 len
= sizeof (int)/sizeof (char);
111 if (pos
+ len
> length
)
113 n
= (int *)(binstr
+ pos
);
114 value
= pmc_new(interp
, class_TclInt
);
115 VTABLE_set_integer_native(interp
, value
, *n
);
128 binary_scan_number_slurpy(PARROT_INTERP, char field, char *binstr, int *_pos, int length)>
130 Scan the binary string for all remaining occurences of a number of the type
131 of the field. Returns a TclList PMC of the number PMCs.
137 binary_scan_number_slurpy(PARROT_INTERP
, char field
, char *binstr
, int *_pos
, int length
)
140 PMC
*values
= pmc_new(interp
, class_TclList
);
142 while ((elem
= binary_scan_number_field(interp
, field
, binstr
, _pos
, length
)))
143 VTABLE_push_pmc(interp
, values
, elem
);
151 binary_scan_number(PARROT_INTERP, char field,
152 char *format, int *formatpos, int formatlen,
153 char *binstr, int *binstrpos, int binstrlen)>
155 Scan the binary string for a number field. There may be a width following
162 binary_scan_number(PARROT_INTERP
, char field
,
163 char *format
, int *formatpos
, int formatlen
,
164 char *binstr
, int *binstrpos
, int binstrlen
)
168 if ((*formatpos
) < formatlen
&& format
[*formatpos
] == '*')
171 value
= binary_scan_number_slurpy(interp
, field
, binstr
, binstrpos
, binstrlen
);
174 value
= binary_scan_number_field(interp
, field
, binstr
, binstrpos
, binstrlen
);
181 =item C<static STRING *
182 binary_scan_string_field(PARROT_INTERP, char field,
183 char *binstr, int *_binstrpos, int binstrlen,
184 STRING *value, int length)>
186 Scan the binary string for a string field. Returns the value of the extracted
187 string (concatenated to its previous value).
193 binary_scan_string_field(PARROT_INTERP
, char field
,
194 char *binstr
, int *_binstrpos
, int binstrlen
,
195 STRING
*value
, int length
)
197 int binstrpos
= *_binstrpos
;
203 if (binstrpos
+ length
> binstrlen
)
205 c
= binstr
+ binstrpos
;
206 value
= string_concat(interp
, value
, string_from_cstring(interp
, c
, length
), 0);
210 if (binstrpos
+ length
> binstrlen
)
212 c
= binstr
+ binstrpos
;
213 value
= string_concat(interp
, value
, string_from_cstring(interp
, c
, length
), 0);
220 *_binstrpos
= binstrpos
;
226 =item C<static STRING *
227 binary_scan_string_slurpy(PARROT_INTERP, char field,
228 char *binstr, int *_binstrpos, int binstrlen, STRING *value)>
230 Scan the binary string for all remaining matches of the field. Returns the
231 new value of the STRING value passed in.
237 binary_scan_string_slurpy(PARROT_INTERP
, char field
,
238 char *binstr
, int *_binstrpos
, int binstrlen
, STRING
*value
)
240 int length
= string_length(interp
, value
);
241 value
= binary_scan_string_field(interp
, field
,
242 binstr
, _binstrpos
, binstrlen
,
251 binary_scan_string(PARROT_INTERP, char field,
252 char *format, int *formatpos, int formatlen,
253 char *binstr, int *binstrpos, int binstrlen)>
255 Scan the binary string for a string field. Returns a TclString PMC with the
262 binary_scan_string(PARROT_INTERP
, char field
,
263 char *format
, int *formatpos
, int formatlen
,
264 char *binstr
, int *binstrpos
, int binstrlen
)
266 STRING
*value
= string_make_empty(interp
, enum_stringrep_one
, 128);
267 PMC
*pmcval
= pmc_new(interp
, class_TclString
);
269 if ((*formatpos
) < formatlen
&& format
[*formatpos
] == '*')
272 value
= binary_scan_string_slurpy(interp
, field
, binstr
, binstrpos
, binstrlen
, value
);
276 int n
= extract_int(format
, formatpos
, formatlen
);
277 value
= binary_scan_string_field(interp
, field
,
278 binstr
, binstrpos
, binstrlen
,
282 VTABLE_set_string_native(interp
, pmcval
, value
);
288 =item C<PMC *ParTcl_binary_scan(PARROT_INTERP, STRING *BINSTR, STRING *FORMAT)>
290 Scan a binary string according to a format string and return a TclList of
291 the extracted values.
293 Assumes, in order to prevent entering another PIR runloop, that the format
294 has been checked to contain valid fields.
296 String and number field code has been separated in an effort to reduce code.
301 PMC
*ParTcl_binary_scan(PARROT_INTERP
, STRING
*BINSTR
, STRING
*FORMAT
)
303 char *binstr
= string_to_cstring(interp
, BINSTR
);
304 int binstrlen
= (int)string_length(interp
, BINSTR
);
306 char *format
= string_to_cstring(interp
, FORMAT
);
307 int formatlen
= string_length(interp
, FORMAT
);
311 /* make sure we've found the type numbers for the PMCs we want to create */
314 class_TclFloat
= pmc_type(interp
, string_from_literal(interp
, "TclFloat"));
315 class_TclInt
= pmc_type(interp
, string_from_literal(interp
, "TclInt"));
316 class_TclList
= pmc_type(interp
, string_from_literal(interp
, "TclList"));
317 class_TclString
= pmc_type(interp
, string_from_literal(interp
, "TclString"));
320 values
= pmc_new(interp
, class_TclList
);
321 while (formatpos
< formatlen
)
323 char field
= format
[formatpos
++];
326 /* figure out if this is a number or a string field */
333 value
= binary_scan_number(interp
, field
,
334 format
, &formatpos
, formatlen
,
335 binstr
, &binstrpos
, binstrlen
);
339 value
= binary_scan_string(interp
, field
,
340 format
, &formatpos
, formatlen
,
341 binstr
, &binstrpos
, binstrlen
);
348 VTABLE_push_pmc(interp
, values
, value
);
351 /* don't forget to free the strings we allocated */
352 string_cstring_free(binstr
);
353 string_cstring_free(format
);
360 =item C<static STRING *
361 binary_format_number_field(PARROT_INTERP, char field, STRING *binstr, PMC *value)>
363 RT#48164: Not yet documented!!!
370 binary_format_number_field(PARROT_INTERP
, char field
, STRING
*binstr
, PMC
*value
)
383 c
= (char)VTABLE_get_integer(interp
, value
);
384 binstr
= string_concat(interp
, binstr
, string_from_cstring(interp
, &c
, 1), 0);
388 d
= (double)VTABLE_get_number(interp
, value
);
389 len
= sizeof (double)/sizeof (char);
390 binstr
= string_concat(interp
, binstr
, string_from_num(interp
, (float)d
), 0);
394 f
= (float)VTABLE_get_number(interp
, value
);
395 len
= sizeof (float)/sizeof (char);
396 binstr
= string_concat(interp
, binstr
, string_from_num(interp
, f
), 0);
398 /* a native integer */
400 n
= (int)VTABLE_get_integer(interp
, value
);
401 len
= sizeof (int)/sizeof (char);
402 binstr
= string_concat(interp
, binstr
, string_from_int(interp
, n
), 0);
413 =item C<static STRING *
414 binary_format_number(PARROT_INTERP, char field, STRING *binstr, PMC *value,
415 char *format, int *formatpos, int formatlen)>
417 RT#48164: Not yet documented!!!
424 binary_format_number(PARROT_INTERP
, char field
, STRING
*binstr
, PMC
*value
,
425 char *format
, int *formatpos
, int formatlen
)
427 binstr
= binary_format_number_field(interp
, field
, binstr
, value
);
434 =item C<static STRING *
435 binary_format_string_field(PARROT_INTERP, char field, STRING *binstr,
436 STRING *strval, int length)>
438 RT#48164: Not yet documented!!!
445 binary_format_string_field(PARROT_INTERP
, char field
, STRING
*binstr
,
446 STRING
*strval
, int length
)
448 int strlen
= string_length(interp
, strval
);
454 string_chopn_inplace(interp
, strval
, strlen
- length
);
455 binstr
= string_concat(interp
, binstr
, strval
, 0);
456 /* pad with nulls if necessary */
457 while (length
-- > strlen
)
458 binstr
= string_concat(interp
, binstr
, string_from_cstring(interp
, "", 1), 0);
462 string_chopn_inplace(interp
, strval
, strlen
- length
);
463 binstr
= string_concat(interp
, binstr
, strval
, 0);
464 /* pad with spaces if necessary */
465 while (length
-- > strlen
)
466 binstr
= string_concat(interp
, binstr
, string_from_cstring(interp
, " ", 1), 0);
477 =item C<static STRING *
478 binary_format_string(PARROT_INTERP, char field, STRING *binstr, PMC *value,
479 char *format, int *formatpos, int formatlen)>
481 RT#48164: Not yet documented!!!
488 binary_format_string(PARROT_INTERP
, char field
, STRING
*binstr
, PMC
*value
,
489 char *format
, int *formatpos
, int formatlen
)
491 STRING
*strval
= VTABLE_get_string(interp
, value
);
493 if ((*formatpos
) < formatlen
&& format
[*formatpos
] == '*')
495 int len
= string_length(interp
, strval
);
496 binstr
= binary_format_string_field(interp
, field
, binstr
, strval
, len
);
501 int len
= extract_int(format
, formatpos
, formatlen
);
502 binstr
= binary_format_string_field(interp
, field
, binstr
, strval
, len
);
510 =item C<STRING *ParTcl_binary_format(PARROT_INTERP, STRING *FORMAT, PMC *values)>
512 RT#48164: Not yet documented!!!
518 STRING
*ParTcl_binary_format(PARROT_INTERP
, STRING
*FORMAT
, PMC
*values
)
520 char *format
= string_to_cstring(interp
, FORMAT
);
521 int formatlen
= string_length(interp
, FORMAT
);
524 STRING
*binstr
= string_make_empty(interp
, enum_stringrep_one
, 128);
526 while (formatpos
< formatlen
)
528 char field
= format
[formatpos
++];
529 PMC
*value
= VTABLE_get_pmc_keyed_int(interp
, values
, valueidx
++);
531 /* figure out if this is a number or a string field */
538 binstr
= binary_format_number(interp
, field
, binstr
, value
,
539 format
, &formatpos
, formatlen
);
543 binstr
= binary_format_string(interp
, field
, binstr
, value
,
544 format
, &formatpos
, formatlen
);
551 string_cstring_free(format
);
566 * c-file-style: "parrot"
568 * vim: expandtab shiftwidth=4: