diff options
author | Satoshi Asami <asami@FreeBSD.org> | 1998-09-05 12:33:01 +0000 |
---|---|---|
committer | Satoshi Asami <asami@FreeBSD.org> | 1998-09-05 12:33:01 +0000 |
commit | 140a040ae3b3a71ffcb0d4d8aaaa47caa804c9f9 (patch) | |
tree | a1a1d04ba696d76d5a4446cb4875ae7f0dd36f86 /contrib/tcl/generic/tclBinary.c | |
parent | ff5fcc93d41b91987f974b2afeb857e5bb7400c6 (diff) |
Remove tcl from src/contrib.
Notes
Notes:
svn path=/head/; revision=38858
Diffstat (limited to 'contrib/tcl/generic/tclBinary.c')
-rw-r--r-- | contrib/tcl/generic/tclBinary.c | 1013 |
1 files changed, 0 insertions, 1013 deletions
diff --git a/contrib/tcl/generic/tclBinary.c b/contrib/tcl/generic/tclBinary.c deleted file mode 100644 index e15fe4c7f51b..000000000000 --- a/contrib/tcl/generic/tclBinary.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* - * tclBinary.c -- - * - * This file contains the implementation of the "binary" Tcl built-in - * command . - * - * Copyright (c) 1997 by Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * SCCS: @(#) tclBinary.c 1.26 97/11/05 13:02:05 - */ - -#include <math.h> -#include "tclInt.h" -#include "tclPort.h" - -/* - * The following constants are used by GetFormatSpec to indicate various - * special conditions in the parsing of a format specifier. - */ - -#define BINARY_ALL -1 /* Use all elements in the argument. */ -#define BINARY_NOCOUNT -2 /* No count was specified in format. */ - -/* - * Prototypes for local procedures defined in this file: - */ - -static int GetFormatSpec _ANSI_ARGS_((char **formatPtr, - char *cmdPtr, int *countPtr)); -static int FormatNumber _ANSI_ARGS_((Tcl_Interp *interp, int type, - Tcl_Obj *src, char **cursorPtr)); -static Tcl_Obj * ScanNumber _ANSI_ARGS_((char *buffer, int type)); - -/* - *---------------------------------------------------------------------- - * - * Tcl_BinaryObjCmd -- - * - * This procedure implements the "binary" Tcl command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_BinaryObjCmd(dummy, interp, objc, objv) - ClientData dummy; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ -{ - int arg; /* Index of next argument to consume. */ - int value = 0; /* Current integer value to be packed. - * Initialized to avoid compiler warning. */ - char cmd; /* Current format character. */ - int count; /* Count associated with current format - * character. */ - char *format; /* Pointer to current position in format - * string. */ - char *cursor; /* Current position within result buffer. */ - char *maxPos; /* Greatest position within result buffer that - * cursor has visited.*/ - char *buffer; /* Start of data buffer. */ - char *errorString, *errorValue, *str; - int offset, size, length; - Tcl_Obj *resultPtr; - - static char *subCmds[] = { "format", "scan", (char *) NULL }; - enum { BinaryFormat, BinaryScan } index; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); - return TCL_ERROR; - } - - if (Tcl_GetIndexFromObj(interp, objv[1], subCmds, "option", 0, - (int *) &index) != TCL_OK) { - return TCL_ERROR; - } - - switch (index) { - case BinaryFormat: - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "formatString ?arg arg ...?"); - return TCL_ERROR; - } - /* - * To avoid copying the data, we format the string in two passes. - * The first pass computes the size of the output buffer. The - * second pass places the formatted data into the buffer. - */ - - format = Tcl_GetStringFromObj(objv[2], NULL); - arg = 3; - offset = length = 0; - while (*format != 0) { - if (!GetFormatSpec(&format, &cmd, &count)) { - break; - } - switch (cmd) { - case 'a': - case 'A': - case 'b': - case 'B': - case 'h': - case 'H': - /* - * For string-type specifiers, the count corresponds - * to the number of characters in a single argument. - */ - - if (arg >= objc) { - goto badIndex; - } - if (count == BINARY_ALL) { - (void)Tcl_GetStringFromObj(objv[arg], &count); - } else if (count == BINARY_NOCOUNT) { - count = 1; - } - arg++; - if (cmd == 'a' || cmd == 'A') { - offset += count; - } else if (cmd == 'b' || cmd == 'B') { - offset += (count + 7) / 8; - } else { - offset += (count + 1) / 2; - } - break; - - case 'c': - size = 1; - goto doNumbers; - case 's': - case 'S': - size = 2; - goto doNumbers; - case 'i': - case 'I': - size = 4; - goto doNumbers; - case 'f': - size = sizeof(float); - goto doNumbers; - case 'd': - size = sizeof(double); - doNumbers: - if (arg >= objc) { - goto badIndex; - } - - /* - * For number-type specifiers, the count corresponds - * to the number of elements in the list stored in - * a single argument. If no count is specified, then - * the argument is taken as a single non-list value. - */ - - if (count == BINARY_NOCOUNT) { - arg++; - count = 1; - } else { - int listc; - Tcl_Obj **listv; - if (Tcl_ListObjGetElements(interp, objv[arg++], - &listc, &listv) != TCL_OK) { - return TCL_ERROR; - } - if (count == BINARY_ALL) { - count = listc; - } else if (count > listc) { - errorString = "number of elements in list does not match count"; - goto error; - } - } - offset += count*size; - break; - - case 'x': - if (count == BINARY_ALL) { - errorString = "cannot use \"*\" in format string with \"x\""; - goto error; - } else if (count == BINARY_NOCOUNT) { - count = 1; - } - offset += count; - break; - case 'X': - if (count == BINARY_NOCOUNT) { - count = 1; - } - if ((count > offset) || (count == BINARY_ALL)) { - count = offset; - } - if (offset > length) { - length = offset; - } - offset -= count; - break; - case '@': - if (offset > length) { - length = offset; - } - if (count == BINARY_ALL) { - offset = length; - } else if (count == BINARY_NOCOUNT) { - goto badCount; - } else { - offset = count; - } - break; - default: { - char buf[2]; - - Tcl_ResetResult(interp); - buf[0] = cmd; - buf[1] = '\0'; - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "bad field specifier \"", buf, "\"", NULL); - return TCL_ERROR; - } - } - } - if (offset > length) { - length = offset; - } - if (length == 0) { - return TCL_OK; - } - - /* - * Prepare the result object by preallocating the caclulated - * number of bytes and filling with nulls. - */ - - resultPtr = Tcl_GetObjResult(interp); - Tcl_SetObjLength(resultPtr, length); - buffer = Tcl_GetStringFromObj(resultPtr, NULL); - memset(buffer, 0, (size_t) length); - - /* - * Pack the data into the result object. Note that we can skip - * the error checking during this pass, since we have already - * parsed the string once. - */ - - arg = 3; - format = Tcl_GetStringFromObj(objv[2], NULL); - cursor = buffer; - maxPos = cursor; - while (*format != 0) { - if (!GetFormatSpec(&format, &cmd, &count)) { - break; - } - if ((count == 0) && (cmd != '@')) { - arg++; - continue; - } - switch (cmd) { - case 'a': - case 'A': { - char pad = (char) (cmd == 'a' ? '\0' : ' '); - - str = Tcl_GetStringFromObj(objv[arg++], &length); - - if (count == BINARY_ALL) { - count = length; - } else if (count == BINARY_NOCOUNT) { - count = 1; - } - if (length >= count) { - memcpy((VOID *) cursor, (VOID *) str, - (size_t) count); - } else { - memcpy((VOID *) cursor, (VOID *) str, - (size_t) length); - memset(cursor+length, pad, - (size_t) (count - length)); - } - cursor += count; - break; - } - case 'b': - case 'B': { - char *last; - - str = Tcl_GetStringFromObj(objv[arg++], &length); - if (count == BINARY_ALL) { - count = length; - } else if (count == BINARY_NOCOUNT) { - count = 1; - } - last = cursor + ((count + 7) / 8); - if (count > length) { - count = length; - } - value = 0; - errorString = "binary"; - if (cmd == 'B') { - for (offset = 0; offset < count; offset++) { - value <<= 1; - if (str[offset] == '1') { - value |= 1; - } else if (str[offset] != '0') { - errorValue = str; - goto badValue; - } - if (((offset + 1) % 8) == 0) { - *cursor++ = (char)(value & 0xff); - value = 0; - } - } - } else { - for (offset = 0; offset < count; offset++) { - value >>= 1; - if (str[offset] == '1') { - value |= 128; - } else if (str[offset] != '0') { - errorValue = str; - goto badValue; - } - if (!((offset + 1) % 8)) { - *cursor++ = (char)(value & 0xff); - value = 0; - } - } - } - if ((offset % 8) != 0) { - if (cmd == 'B') { - value <<= 8 - (offset % 8); - } else { - value >>= 8 - (offset % 8); - } - *cursor++ = (char)(value & 0xff); - } - while (cursor < last) { - *cursor++ = '\0'; - } - break; - } - case 'h': - case 'H': { - char *last; - int c; - - str = Tcl_GetStringFromObj(objv[arg++], &length); - if (count == BINARY_ALL) { - count = length; - } else if (count == BINARY_NOCOUNT) { - count = 1; - } - last = cursor + ((count + 1) / 2); - if (count > length) { - count = length; - } - value = 0; - errorString = "hexadecimal"; - if (cmd == 'H') { - for (offset = 0; offset < count; offset++) { - value <<= 4; - c = tolower(((unsigned char *) str)[offset]); - if ((c >= 'a') && (c <= 'f')) { - value |= ((c - 'a' + 10) & 0xf); - } else if ((c >= '0') && (c <= '9')) { - value |= (c - '0') & 0xf; - } else { - errorValue = str; - goto badValue; - } - if (offset % 2) { - *cursor++ = (char) value; - value = 0; - } - } - } else { - for (offset = 0; offset < count; offset++) { - value >>= 4; - c = tolower(((unsigned char *) str)[offset]); - if ((c >= 'a') && (c <= 'f')) { - value |= ((c - 'a' + 10) << 4) & 0xf0; - } else if ((c >= '0') && (c <= '9')) { - value |= ((c - '0') << 4) & 0xf0; - } else { - errorValue = str; - goto badValue; - } - if (offset % 2) { - *cursor++ = (char)(value & 0xff); - value = 0; - } - } - } - if (offset % 2) { - if (cmd == 'H') { - value <<= 4; - } else { - value >>= 4; - } - *cursor++ = (char) value; - } - - while (cursor < last) { - *cursor++ = '\0'; - } - break; - } - case 'c': - case 's': - case 'S': - case 'i': - case 'I': - case 'd': - case 'f': { - int listc, i; - Tcl_Obj **listv; - - if (count == BINARY_NOCOUNT) { - /* - * Note that we are casting away the const-ness of - * objv, but this is safe since we aren't going to - * modify the array. - */ - - listv = (Tcl_Obj**)(objv + arg); - listc = 1; - count = 1; - } else { - Tcl_ListObjGetElements(interp, objv[arg], - &listc, &listv); - if (count == BINARY_ALL) { - count = listc; - } - } - arg++; - for (i = 0; i < count; i++) { - if (FormatNumber(interp, cmd, listv[i], &cursor) - != TCL_OK) { - return TCL_ERROR; - } - } - break; - } - case 'x': - if (count == BINARY_NOCOUNT) { - count = 1; - } - memset(cursor, 0, (size_t) count); - cursor += count; - break; - case 'X': - if (cursor > maxPos) { - maxPos = cursor; - } - if (count == BINARY_NOCOUNT) { - count = 1; - } - if ((count == BINARY_ALL) - || (count > (cursor - buffer))) { - cursor = buffer; - } else { - cursor -= count; - } - break; - case '@': - if (cursor > maxPos) { - maxPos = cursor; - } - if (count == BINARY_ALL) { - cursor = maxPos; - } else { - cursor = buffer + count; - } - break; - } - } - break; - - case BinaryScan: { - int i; - Tcl_Obj *valuePtr, *elementPtr; - - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "value formatString ?varName varName ...?"); - return TCL_ERROR; - } - buffer = Tcl_GetStringFromObj(objv[2], &length); - format = Tcl_GetStringFromObj(objv[3], NULL); - cursor = buffer; - arg = 4; - offset = 0; - while (*format != 0) { - if (!GetFormatSpec(&format, &cmd, &count)) { - goto done; - } - switch (cmd) { - case 'a': - case 'A': - if (arg >= objc) { - goto badIndex; - } - if (count == BINARY_ALL) { - count = length - offset; - } else { - if (count == BINARY_NOCOUNT) { - count = 1; - } - if (count > (length - offset)) { - goto done; - } - } - - str = buffer + offset; - size = count; - - /* - * Trim trailing nulls and spaces, if necessary. - */ - - if (cmd == 'A') { - while (size > 0) { - if (str[size-1] != '\0' && str[size-1] != ' ') { - break; - } - size--; - } - } - valuePtr = Tcl_NewStringObj(str, size); - resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL, - valuePtr, - TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1); - if (resultPtr == NULL) { - Tcl_DecrRefCount(valuePtr); /* unneeded */ - return TCL_ERROR; - } - offset += count; - break; - case 'b': - case 'B': { - char *dest; - - if (arg >= objc) { - goto badIndex; - } - if (count == BINARY_ALL) { - count = (length - offset)*8; - } else { - if (count == BINARY_NOCOUNT) { - count = 1; - } - if (count > (length - offset)*8) { - goto done; - } - } - str = buffer + offset; - valuePtr = Tcl_NewObj(); - Tcl_SetObjLength(valuePtr, count); - dest = Tcl_GetStringFromObj(valuePtr, NULL); - - if (cmd == 'b') { - for (i = 0; i < count; i++) { - if (i % 8) { - value >>= 1; - } else { - value = *str++; - } - *dest++ = (char) ((value & 1) ? '1' : '0'); - } - } else { - for (i = 0; i < count; i++) { - if (i % 8) { - value <<= 1; - } else { - value = *str++; - } - *dest++ = (char) ((value & 0x80) ? '1' : '0'); - } - } - - resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL, - valuePtr, - TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1); - if (resultPtr == NULL) { - Tcl_DecrRefCount(valuePtr); /* unneeded */ - return TCL_ERROR; - } - offset += (count + 7 ) / 8; - break; - } - case 'h': - case 'H': { - char *dest; - int i; - static char hexdigit[] = "0123456789abcdef"; - - if (arg >= objc) { - goto badIndex; - } - if (count == BINARY_ALL) { - count = (length - offset)*2; - } else { - if (count == BINARY_NOCOUNT) { - count = 1; - } - if (count > (length - offset)*2) { - goto done; - } - } - str = buffer + offset; - valuePtr = Tcl_NewObj(); - Tcl_SetObjLength(valuePtr, count); - dest = Tcl_GetStringFromObj(valuePtr, NULL); - - if (cmd == 'h') { - for (i = 0; i < count; i++) { - if (i % 2) { - value >>= 4; - } else { - value = *str++; - } - *dest++ = hexdigit[value & 0xf]; - } - } else { - for (i = 0; i < count; i++) { - if (i % 2) { - value <<= 4; - } else { - value = *str++; - } - *dest++ = hexdigit[(value >> 4) & 0xf]; - } - } - - resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL, - valuePtr, - TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1); - if (resultPtr == NULL) { - Tcl_DecrRefCount(valuePtr); /* unneeded */ - return TCL_ERROR; - } - offset += (count + 1) / 2; - break; - } - case 'c': - size = 1; - goto scanNumber; - case 's': - case 'S': - size = 2; - goto scanNumber; - case 'i': - case 'I': - size = 4; - goto scanNumber; - case 'f': - size = sizeof(float); - goto scanNumber; - case 'd': - size = sizeof(double); - /* fall through */ - scanNumber: - if (arg >= objc) { - goto badIndex; - } - if (count == BINARY_NOCOUNT) { - if ((length - offset) < size) { - goto done; - } - valuePtr = ScanNumber(buffer+offset, cmd); - offset += size; - } else { - if (count == BINARY_ALL) { - count = (length - offset) / size; - } - if ((length - offset) < (count * size)) { - goto done; - } - valuePtr = Tcl_NewObj(); - str = buffer+offset; - for (i = 0; i < count; i++) { - elementPtr = ScanNumber(str, cmd); - str += size; - Tcl_ListObjAppendElement(NULL, valuePtr, - elementPtr); - } - offset += count*size; - } - - resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL, - valuePtr, - TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1); - if (resultPtr == NULL) { - Tcl_DecrRefCount(valuePtr); /* unneeded */ - return TCL_ERROR; - } - break; - case 'x': - if (count == BINARY_NOCOUNT) { - count = 1; - } - if ((count == BINARY_ALL) - || (count > (length - offset))) { - offset = length; - } else { - offset += count; - } - break; - case 'X': - if (count == BINARY_NOCOUNT) { - count = 1; - } - if ((count == BINARY_ALL) || (count > offset)) { - offset = 0; - } else { - offset -= count; - } - break; - case '@': - if (count == BINARY_NOCOUNT) { - goto badCount; - } - if ((count == BINARY_ALL) || (count > length)) { - offset = length; - } else { - offset = count; - } - break; - default: { - char buf[2]; - - Tcl_ResetResult(interp); - buf[0] = cmd; - buf[1] = '\0'; - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "bad field specifier \"", buf, "\"", NULL); - return TCL_ERROR; - } - } - } - - /* - * Set the result to the last position of the cursor. - */ - - done: - Tcl_ResetResult(interp); - Tcl_SetLongObj(Tcl_GetObjResult(interp), arg - 4); - break; - } - } - return TCL_OK; - - badValue: - Tcl_ResetResult(interp); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "expected ", errorString, - " string but got \"", errorValue, "\" instead", NULL); - return TCL_ERROR; - - badCount: - errorString = "missing count for \"@\" field specifier"; - goto error; - - badIndex: - errorString = "not enough arguments for all format specifiers"; - goto error; - - error: - Tcl_ResetResult(interp); - Tcl_AppendToObj(Tcl_GetObjResult(interp), errorString, -1); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * GetFormatSpec -- - * - * This function parses the format strings used in the binary - * format and scan commands. - * - * Results: - * Moves the formatPtr to the start of the next command. Returns - * the current command character and count in cmdPtr and countPtr. - * The count is set to BINARY_ALL if the count character was '*' - * or BINARY_NOCOUNT if no count was specified. Returns 1 on - * success, or 0 if the string did not have a format specifier. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -GetFormatSpec(formatPtr, cmdPtr, countPtr) - char **formatPtr; /* Pointer to format string. */ - char *cmdPtr; /* Pointer to location of command char. */ - int *countPtr; /* Pointer to repeat count value. */ -{ - /* - * Skip any leading blanks. - */ - - while (**formatPtr == ' ') { - (*formatPtr)++; - } - - /* - * The string was empty, except for whitespace, so fail. - */ - - if (!(**formatPtr)) { - return 0; - } - - /* - * Extract the command character and any trailing digits or '*'. - */ - - *cmdPtr = **formatPtr; - (*formatPtr)++; - if (**formatPtr == '*') { - (*formatPtr)++; - (*countPtr) = BINARY_ALL; - } else if (isdigit(**formatPtr)) { - (*countPtr) = strtoul(*formatPtr, formatPtr, 10); - } else { - (*countPtr) = BINARY_NOCOUNT; - } - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * FormatNumber -- - * - * This routine is called by Tcl_BinaryObjCmd to format a number - * into a location pointed at by cursor. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Moves the cursor to the next location to be written into. - * - *---------------------------------------------------------------------- - */ - -static int -FormatNumber(interp, type, src, cursorPtr) - Tcl_Interp *interp; /* Current interpreter, used to report - * errors. */ - int type; /* Type of number to format. */ - Tcl_Obj *src; /* Number to format. */ - char **cursorPtr; /* Pointer to index into destination buffer. */ -{ - int value; - double dvalue; - char cmd = (char)type; - - if (cmd == 'd' || cmd == 'f') { - /* - * For floating point types, we need to copy the data using - * memcpy to avoid alignment issues. - */ - - if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) { - return TCL_ERROR; - } - if (cmd == 'd') { - memcpy((*cursorPtr), &dvalue, sizeof(double)); - (*cursorPtr) += sizeof(double); - } else { - float fvalue; - - /* - * Because some compilers will generate floating point exceptions - * on an overflow cast (e.g. Borland), we restrict the values - * to the valid range for float. - */ - - if (fabs(dvalue) > (double)FLT_MAX) { - fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX; - } else { - fvalue = (float) dvalue; - } - memcpy((*cursorPtr), &fvalue, sizeof(float)); - (*cursorPtr) += sizeof(float); - } - } else { - if (Tcl_GetIntFromObj(interp, src, &value) != TCL_OK) { - return TCL_ERROR; - } - if (cmd == 'c') { - *(*cursorPtr)++ = (char)(value & 0xff); - } else if (cmd == 's') { - *(*cursorPtr)++ = (char)(value & 0xff); - *(*cursorPtr)++ = (char)((value >> 8) & 0xff); - } else if (cmd == 'S') { - *(*cursorPtr)++ = (char)((value >> 8) & 0xff); - *(*cursorPtr)++ = (char)(value & 0xff); - } else if (cmd == 'i') { - *(*cursorPtr)++ = (char)(value & 0xff); - *(*cursorPtr)++ = (char)((value >> 8) & 0xff); - *(*cursorPtr)++ = (char)((value >> 16) & 0xff); - *(*cursorPtr)++ = (char)((value >> 24) & 0xff); - } else if (cmd == 'I') { - *(*cursorPtr)++ = (char)((value >> 24) & 0xff); - *(*cursorPtr)++ = (char)((value >> 16) & 0xff); - *(*cursorPtr)++ = (char)((value >> 8) & 0xff); - *(*cursorPtr)++ = (char)(value & 0xff); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * ScanNumber -- - * - * This routine is called by Tcl_BinaryObjCmd to scan a number - * out of a buffer. - * - * Results: - * Returns a newly created object containing the scanned number. - * This object has a ref count of zero. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static Tcl_Obj * -ScanNumber(buffer, type) - char *buffer; /* Buffer to scan number from. */ - int type; /* Format character from "binary scan" */ -{ - int value; - - /* - * We cannot rely on the compiler to properly sign extend integer values - * when we cast from smaller values to larger values because we don't know - * the exact size of the integer types. So, we have to handle sign - * extension explicitly by checking the high bit and padding with 1's as - * needed. - */ - - switch ((char) type) { - case 'c': - value = buffer[0]; - - if (value & 0x80) { - value |= -0x100; - } - return Tcl_NewLongObj((long)value); - case 's': - value = (((unsigned char)buffer[0]) - + ((unsigned char)buffer[1] << 8)); - goto shortValue; - case 'S': - value = (((unsigned char)buffer[1]) - + ((unsigned char)buffer[0] << 8)); - shortValue: - if (value & 0x8000) { - value |= -0x10000; - } - return Tcl_NewLongObj((long)value); - case 'i': - value = (((unsigned char)buffer[0]) - + ((unsigned char)buffer[1] << 8) - + ((unsigned char)buffer[2] << 16) - + ((unsigned char)buffer[3] << 24)); - goto intValue; - case 'I': - value = (((unsigned char)buffer[3]) - + ((unsigned char)buffer[2] << 8) - + ((unsigned char)buffer[1] << 16) - + ((unsigned char)buffer[0] << 24)); - intValue: - /* - * Check to see if the value was sign extended properly on - * systems where an int is more than 32-bits. - */ - - if ((value & (((unsigned int)1)<<31)) && (value > 0)) { - value -= (((unsigned int)1)<<31); - value -= (((unsigned int)1)<<31); - } - - return Tcl_NewLongObj((long)value); - case 'f': { - float fvalue; - memcpy(&fvalue, buffer, sizeof(float)); - return Tcl_NewDoubleObj(fvalue); - } - case 'd': { - double dvalue; - memcpy(&dvalue, buffer, sizeof(double)); - return Tcl_NewDoubleObj(dvalue); - } - } - return NULL; -} |