Author: mdiep
Date: Sat Jan 6 21:11:19 2007
New Revision: 16454
Modified:
trunk/languages/tcl/src/binary.c
Log:
[tcl]: [binary] opcodes - add support for * and use Tcl types
Modified: trunk/languages/tcl/src/binary.c
==============================================================================
--- trunk/languages/tcl/src/binary.c (original)
+++ trunk/languages/tcl/src/binary.c Sat Jan 6 21:11:19 2007
@@ -4,6 +4,10 @@
#include "binary.h"
#include <stdio.h>
+static int class_TclFloat = 0;
+static int class_TclInt = 0;
+static int class_TclList = 0;
+
static PMC *
binary_scan_field(Interp *interp, char field, char *binstr, int *_pos, int
length)
{
@@ -18,7 +22,7 @@
if (pos >= length)
break;
c = (char *)(binstr + pos);
- value = pmc_new(interp, enum_class_Integer);
+ value = pmc_new(interp, class_TclInt);
VTABLE_set_integer_native(interp, value, (INTVAL)*c);
pos += 1;
break;
@@ -27,7 +31,7 @@
if (pos + len > length)
break;
d = (double *)(binstr + pos);
- value = pmc_new(interp, enum_class_Float);
+ value = pmc_new(interp, class_TclFloat);
VTABLE_set_number_native(interp, value, *d);
pos += len;
break;
@@ -36,6 +40,18 @@
return value;
}
+static PMC *
+binary_scan_slurpy(Interp *interp, char field, char *binstr, int *_pos, int
length)
+{
+ PMC *elem;
+ PMC *values = pmc_new(interp, class_TclList);
+
+ while ((elem = binary_scan_field(interp, field, binstr, _pos, length)) !=
PMCNULL)
+ VTABLE_push_pmc(interp, values, elem);
+
+ return values;
+}
+
PMC *ParTcl_binary_scan(Interp *interp, STRING *BINSTR, STRING *FORMAT)
{
char *binstr = string_to_cstring(interp, BINSTR);
@@ -45,12 +61,29 @@
INTVAL formatlen = string_length(interp, FORMAT);
INTVAL formatpos = 0;
INTVAL value = 0;
- PMC *values = pmc_new(interp, enum_class_ResizablePMCArray);
-
+ PMC *values;
+
+ if (!class_TclFloat)
+ {
+ class_TclFloat = pmc_type(interp, string_from_const_cstring(interp,
"TclFloat", 0));
+ class_TclInt = pmc_type(interp, string_from_const_cstring(interp,
"TclInt", 0));
+ class_TclList = pmc_type(interp, string_from_const_cstring(interp,
"TclList", 0));
+ }
+
+ values = pmc_new(interp, class_TclList);
while (formatpos < formatlen)
{
- PMC *value = binary_scan_field(interp, format[formatpos++],
- binstr, &binstrpos, binstrlen);
+ char field = format[formatpos++];
+ PMC *value;
+
+ if (formatpos < formatlen && format[formatpos] == '*')
+ {
+ formatpos++;
+ value = binary_scan_slurpy(interp, field, binstr, &binstrpos,
binstrlen);
+ }
+ else
+ value = binary_scan_field(interp, field, binstr, &binstrpos,
binstrlen);
+
VTABLE_push_pmc(interp, values, value);
}
@@ -66,10 +99,12 @@
switch (field)
{
+ /* a char */
case 'c':
c = (char)VTABLE_get_integer(interp, value);
binstr = string_concat(interp, binstr, string_from_cstring(interp,
&c, 1), 1);
break;
+ /* a double */
case 'd':
d = (double)VTABLE_get_number(interp, value);
len = sizeof(double)/sizeof(char);