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
);
126 binary_scan_number_slurpy(PARROT_INTERP, char field, char *binstr, int *_pos, int length)>
128 Scan the binary string for all remaining occurences of a number of the type
129 of the field. Returns a TclList PMC of the number PMCs.
135 binary_scan_number_slurpy(PARROT_INTERP
, char field
, char *binstr
, int *_pos
, int length
)
138 PMC
*values
= pmc_new(interp
, class_TclList
);
140 while ((elem
= binary_scan_number_field(interp
, field
, binstr
, _pos
, length
)))
141 VTABLE_push_pmc(interp
, values
, elem
);
149 binary_scan_number(PARROT_INTERP, char field,
150 char *format, int *formatpos, int formatlen,
151 char *binstr, int *binstrpos, int binstrlen)>
153 Scan the binary string for a number field. There may be a width following
160 binary_scan_number(PARROT_INTERP
, char field
,
161 char *format
, int *formatpos
, int formatlen
,
162 char *binstr
, int *binstrpos
, int binstrlen
)
166 if ((*formatpos
) < formatlen
&& format
[*formatpos
] == '*')
169 value
= binary_scan_number_slurpy(interp
, field
, binstr
, binstrpos
, binstrlen
);
172 value
= binary_scan_number_field(interp
, field
, binstr
, binstrpos
, binstrlen
);
179 =item C<static STRING *
180 binary_scan_string_field(PARROT_INTERP, char field,
181 char *binstr, int *_binstrpos, int binstrlen,
182 STRING *value, int length)>
184 Scan the binary string for a string field. Returns the value of the extracted
185 string (concatenated to its previous value).
191 binary_scan_string_field(PARROT_INTERP
, char field
,
192 char *binstr
, int *_binstrpos
, int binstrlen
,
193 STRING
*value
, int length
)
195 int binstrpos
= *_binstrpos
;
201 if (binstrpos
+ length
> binstrlen
)
203 c
= binstr
+ binstrpos
;
204 value
= string_concat(interp
, value
, string_from_cstring(interp
, c
, length
), 0);
208 if (binstrpos
+ length
> binstrlen
)
210 c
= binstr
+ binstrpos
;
211 value
= string_concat(interp
, value
, string_from_cstring(interp
, c
, length
), 0);
218 *_binstrpos
= binstrpos
;
224 =item C<static STRING *
225 binary_scan_string_slurpy(PARROT_INTERP, char field,
226 char *binstr, int *_binstrpos, int binstrlen, STRING *value)>
228 Scan the binary string for all remaining matches of the field. Returns the
229 new value of the STRING value passed in.
235 binary_scan_string_slurpy(PARROT_INTERP
, char field
,
236 char *binstr
, int *_binstrpos
, int binstrlen
, STRING
*value
)
238 int length
= string_length(interp
, value
);
239 value
= binary_scan_string_field(interp
, field
,
240 binstr
, _binstrpos
, binstrlen
,
249 binary_scan_string(PARROT_INTERP, char field,
250 char *format, int *formatpos, int formatlen,
251 char *binstr, int *binstrpos, int binstrlen)>
253 Scan the binary string for a string field. Returns a TclString PMC with the
260 binary_scan_string(PARROT_INTERP
, char field
,
261 char *format
, int *formatpos
, int formatlen
,
262 char *binstr
, int *binstrpos
, int binstrlen
)
264 STRING
*value
= string_make_empty(interp
, enum_stringrep_one
, 128);
265 PMC
*pmcval
= pmc_new(interp
, class_TclString
);
267 if ((*formatpos
) < formatlen
&& format
[*formatpos
] == '*')
270 value
= binary_scan_string_slurpy(interp
, field
, binstr
, binstrpos
, binstrlen
, value
);
274 int n
= extract_int(format
, formatpos
, formatlen
);
275 value
= binary_scan_string_field(interp
, field
,
276 binstr
, binstrpos
, binstrlen
,
280 VTABLE_set_string_native(interp
, pmcval
, value
);
286 =item C<PMC *ParTcl_binary_scan(PARROT_INTERP, STRING *BINSTR, STRING *FORMAT)>
288 Scan a binary string according to a format string and return a TclList of
289 the extracted values.
291 Assumes, in order to prevent entering another PIR runloop, that the format
292 has been checked to contain valid fields.
294 String and number field code has been separated in an effort to reduce code.
299 PMC
*ParTcl_binary_scan(PARROT_INTERP
, STRING
*BINSTR
, STRING
*FORMAT
)
301 char *binstr
= string_to_cstring(interp
, BINSTR
);
302 int binstrlen
= (int)string_length(interp
, BINSTR
);
304 char *format
= string_to_cstring(interp
, FORMAT
);
305 int formatlen
= string_length(interp
, FORMAT
);
309 /* make sure we've found the type numbers for the PMCs we want to create */
312 class_TclFloat
= pmc_type(interp
, string_from_literal(interp
, "TclFloat"));
313 class_TclInt
= pmc_type(interp
, string_from_literal(interp
, "TclInt"));
314 class_TclList
= pmc_type(interp
, string_from_literal(interp
, "TclList"));
315 class_TclString
= pmc_type(interp
, string_from_literal(interp
, "TclString"));
318 values
= pmc_new(interp
, class_TclList
);
319 while (formatpos
< formatlen
)
321 char field
= format
[formatpos
++];
324 /* figure out if this is a number or a string field */
331 value
= binary_scan_number(interp
, field
,
332 format
, &formatpos
, formatlen
,
333 binstr
, &binstrpos
, binstrlen
);
337 value
= binary_scan_string(interp
, field
,
338 format
, &formatpos
, formatlen
,
339 binstr
, &binstrpos
, binstrlen
);
346 VTABLE_push_pmc(interp
, values
, value
);
349 /* don't forget to free the strings we allocated */
350 string_cstring_free(binstr
);
351 string_cstring_free(format
);
358 =item C<static STRING *
359 binary_format_number_field(PARROT_INTERP, char field, STRING *binstr, PMC *value)>
361 RT#48164: Not yet documented!!!
368 binary_format_number_field(PARROT_INTERP
, char field
, STRING
*binstr
, PMC
*value
)
381 c
= (char)VTABLE_get_integer(interp
, value
);
382 binstr
= string_concat(interp
, binstr
, string_from_cstring(interp
, &c
, 1), 0);
386 d
= (double)VTABLE_get_number(interp
, value
);
387 len
= sizeof (double)/sizeof (char);
388 binstr
= string_concat(interp
, binstr
, string_from_num(interp
, (float)d
), 0);
392 f
= (float)VTABLE_get_number(interp
, value
);
393 len
= sizeof (float)/sizeof (char);
394 binstr
= string_concat(interp
, binstr
, string_from_num(interp
, f
), 0);
396 /* a native integer */
398 n
= (int)VTABLE_get_integer(interp
, value
);
399 len
= sizeof (int)/sizeof (char);
400 binstr
= string_concat(interp
, binstr
, string_from_int(interp
, n
), 0);
409 =item C<static STRING *
410 binary_format_number(PARROT_INTERP, char field, STRING *binstr, PMC *value,
411 char *format, int *formatpos, int formatlen)>
413 RT#48164: Not yet documented!!!
420 binary_format_number(PARROT_INTERP
, char field
, STRING
*binstr
, PMC
*value
,
421 char *format
, int *formatpos
, int formatlen
)
423 binstr
= binary_format_number_field(interp
, field
, binstr
, value
);
430 =item C<static STRING *
431 binary_format_string_field(PARROT_INTERP, char field, STRING *binstr,
432 STRING *strval, int length)>
434 RT#48164: Not yet documented!!!
441 binary_format_string_field(PARROT_INTERP
, char field
, STRING
*binstr
,
442 STRING
*strval
, int length
)
444 int strlen
= string_length(interp
, strval
);
450 string_chopn_inplace(interp
, strval
, strlen
- length
);
451 binstr
= string_concat(interp
, binstr
, strval
, 0);
452 /* pad with nulls if necessary */
453 while (length
-- > strlen
)
454 binstr
= string_concat(interp
, binstr
, string_from_cstring(interp
, "", 1), 0);
458 string_chopn_inplace(interp
, strval
, strlen
- length
);
459 binstr
= string_concat(interp
, binstr
, strval
, 0);
460 /* pad with spaces if necessary */
461 while (length
-- > strlen
)
462 binstr
= string_concat(interp
, binstr
, string_from_cstring(interp
, " ", 1), 0);
471 =item C<static STRING *
472 binary_format_string(PARROT_INTERP, char field, STRING *binstr, PMC *value,
473 char *format, int *formatpos, int formatlen)>
475 RT#48164: Not yet documented!!!
482 binary_format_string(PARROT_INTERP
, char field
, STRING
*binstr
, PMC
*value
,
483 char *format
, int *formatpos
, int formatlen
)
485 STRING
*strval
= VTABLE_get_string(interp
, value
);
487 if ((*formatpos
) < formatlen
&& format
[*formatpos
] == '*')
489 int len
= string_length(interp
, strval
);
490 binstr
= binary_format_string_field(interp
, field
, binstr
, strval
, len
);
495 int len
= extract_int(format
, formatpos
, formatlen
);
496 binstr
= binary_format_string_field(interp
, field
, binstr
, strval
, len
);
504 =item C<STRING *ParTcl_binary_format(PARROT_INTERP, STRING *FORMAT, PMC *values)>
506 RT#48164: Not yet documented!!!
512 STRING
*ParTcl_binary_format(PARROT_INTERP
, STRING
*FORMAT
, PMC
*values
)
514 char *format
= string_to_cstring(interp
, FORMAT
);
515 int formatlen
= string_length(interp
, FORMAT
);
518 STRING
*binstr
= string_make_empty(interp
, enum_stringrep_one
, 128);
520 while (formatpos
< formatlen
)
522 char field
= format
[formatpos
++];
523 PMC
*value
= VTABLE_get_pmc_keyed_int(interp
, values
, valueidx
++);
525 /* figure out if this is a number or a string field */
532 binstr
= binary_format_number(interp
, field
, binstr
, value
,
533 format
, &formatpos
, formatlen
);
537 binstr
= binary_format_string(interp
, field
, binstr
, value
,
538 format
, &formatpos
, formatlen
);
543 string_cstring_free(format
);
558 * c-file-style: "parrot"
560 * vim: expandtab shiftwidth=4: