Ejemplo n.º 1
0
static void DndReadSourceProperty(Display * dpy,
                                  Window window, Atom dnd_selection,
                                  Atom ** targets, unsigned short * num_targets)
{
    unsigned char *retval = 0;
    Atom type ;
    int format ;
    unsigned long bytesafter, lengthRtn;

    if ((XGetWindowProperty (dpy, window, dnd_selection, 0L, 100000L,
                             False, ATOM(_MOTIF_DRAG_INITIATOR_INFO), &type,
                             &format, &lengthRtn, &bytesafter,
                             &retval) != Success)
        || (type == XNone)) {
        *num_targets = 0;
        return ;
    }

    DndSrcProp * src_prop = (DndSrcProp *)retval;

    if (src_prop->byte_order != DndByteOrder()) {
        SWAP2BYTES(src_prop->target_index);
        SWAP4BYTES(src_prop->selection);
    }

    *num_targets = _DndIndexToTargets(dpy, src_prop->target_index, targets);

    XFree((char*)src_prop);
}
Ejemplo n.º 2
0
Archivo: DragBS.c Proyecto: att/uwin
/*
 * extracts n values (formatted as CARD32) from the drag buffer and
 * converts them to Atoms
 */
static void
read_atoms_from_drag_buffer(XmDndBufMgr bmgr, int n, Boolean swap, Atom* atoms)
{
    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atoms_from_drag_buffer(%d) - count %d swap %s\n",
		      __FILE__, __LINE__,
		      n, swap ? "True" : "False"));

    if (sizeof(Atom) == sizeof(CARD32))
    {
        _XmReadDragBuffer(bmgr, False, (char*) atoms, sizeof(Atom) * n);
        if (swap)
        {
            int i;

            for (i = 0; i < n; i++)
            {
                SWAP4BYTES(atoms[i]);
            }
        }
    }
    else {
        CARD32 in;
        int i;

        if (swap)
        {
            for (i = 0; i < n; i++)
            {
                _XmReadDragBuffer(bmgr, False, (char*) &in, sizeof(CARD32));
                SWAP4BYTES(in);
                atoms[i] = in;
            }
        }
        else {
            for (i = 0; i < n; i++)
            {
                _XmReadDragBuffer(bmgr, False, (char*) &in, sizeof(CARD32));
                atoms[i] = in;
            }
        }
    }
}
Ejemplo n.º 3
0
static DndTargetsTable TargetsTable(Display *display)
{
    Atom            type;
    int             format;
    unsigned long   size;
    unsigned long   bytes_after;
    Window motif_window = MotifWindow(display) ;
    unsigned char  *retval;
    DndTargetsTable targets_table ;
    int i,j ;
    char * target_data ;

    /* this version does no caching, so it's slow: round trip each time */
    /* ideally, register for property notify on this target_list
       atom and update when necessary only */

    if ((XGetWindowProperty (display, motif_window,
                             ATOM(_MOTIF_DRAG_TARGETS), 0L, 100000L,
                             False, ATOM(_MOTIF_DRAG_TARGETS),
                             &type, &format, &size, &bytes_after,
                             &retval) != Success) ||
        type == XNone) {
        qWarning("QMotifDND: Cannot get property on Motif window");
        return 0;
    }

    DndTargets * target_prop = (DndTargets *)retval;

    if (target_prop->protocol_version != DND_PROTOCOL_VERSION) {
        qWarning("QMotifDND: Protocol mismatch");
    }

    if (target_prop->byte_order != DndByteOrder()) {
        /* need to swap num_target_lists and size */
        SWAP2BYTES(target_prop->num_target_lists);
        SWAP4BYTES(target_prop->data_size);
    }

    /* now parse DndTarget prop data in a TargetsTable */

    targets_table = (DndTargetsTable)malloc(sizeof(DndTargetsTableRec));
    targets_table->num_entries = target_prop->num_target_lists ;
    targets_table->entries = (DndTargetsTableEntry)
                             malloc(sizeof(DndTargetsTableEntryRec) * target_prop->num_target_lists);

    target_data = (char*)target_prop + sizeof(*target_prop) ;

    for (i = 0 ; i < targets_table->num_entries; i++) {
        CARD16 num_targets ;
        CARD32 atom ;

        memcpy(&num_targets, target_data, 2);
        target_data += 2;

        /* potential swap needed here */
        if (target_prop->byte_order != DndByteOrder())
            SWAP2BYTES(num_targets);

        targets_table->entries[i].num_targets = num_targets ;
        targets_table->entries[i].targets = (Atom *)
                                            malloc(sizeof(Atom) * targets_table->entries[i].num_targets);


        for (j = 0; j < num_targets; j++) {
            memcpy(&atom, target_data, 4);
            target_data += 4;

            /* another potential swap needed here */
            if (target_prop->byte_order != DndByteOrder())
                SWAP4BYTES(atom);

            targets_table->entries[i].targets[j] = (Atom) atom ;
        }
    }

    if (target_prop) {
        XFree((char *)target_prop);
    }

    return targets_table ;
}
Ejemplo n.º 4
0
static Bool DndParseClientMessage(XClientMessageEvent *cm, DndData * dnd_data,
                                  char * receiver)
{
    DndMessage * dnd_message = (DndMessage*)&cm->data.b[0] ;

    if (cm->message_type != ATOM(_MOTIF_DRAG_AND_DROP_MESSAGE)) {
        return False ;
    }

    if (dnd_message->byte_order != DndByteOrder()) {
        SWAP2BYTES(dnd_message->flags);
        SWAP4BYTES(dnd_message->time);
    } /* do the rest in the switch */

    dnd_data->reason = dnd_message->reason  ;
    if (DND_GET_EVENT_TYPE(dnd_data->reason))
        *receiver = 1 ;
    else
        *receiver = 0 ;
    dnd_data->reason &= DND_CLEAR_EVENT_TYPE ;

    dnd_data->time = dnd_message->time ;

    /* we're reading in more stuff that necessary. but who cares */
    dnd_data->status = DND_GET_STATUS(dnd_message->flags) ;
    dnd_data->operation = DND_GET_OPERATION(dnd_message->flags) ;
    dnd_data->operations = DND_GET_OPERATIONS(dnd_message->flags) ;
    dnd_data->completion = DND_GET_COMPLETION(dnd_message->flags) ;

    switch(dnd_data->reason) {
    case DND_TOP_LEVEL_ENTER:
    case DND_TOP_LEVEL_LEAVE:
        if (dnd_message->byte_order != DndByteOrder()) {
            SWAP4BYTES(dnd_message->data.top.src_window);
            SWAP4BYTES(dnd_message->data.top.property);
        }
        dnd_data->src_window = dnd_message->data.top.src_window ;
        dnd_data->property = dnd_message->data.top.property ;
        break ; /* cannot fall through, see above comment in write msg */

    case DND_DRAG_MOTION:
    case DND_OPERATION_CHANGED:
    case DND_DROP_SITE_ENTER:
    case DND_DROP_START:
        if (dnd_message->byte_order != DndByteOrder()) {
            SWAP2BYTES(dnd_message->data.pot.x);
            SWAP2BYTES(dnd_message->data.pot.y);
            SWAP4BYTES(dnd_message->data.pot.property);
            SWAP4BYTES(dnd_message->data.pot.src_window);
        }
        dnd_data->x = dnd_message->data.pot.x ;
        dnd_data->y = dnd_message->data.pot.y ;
        dnd_data->property = dnd_message->data.pot.property ;
        dnd_data->src_window = dnd_message->data.pot.src_window ;
        break ;

    case DND_DROP_SITE_LEAVE:
        break;
    default:
        break ;
    }

    return True ;
}
Ejemplo n.º 5
0
Archivo: DragBS.c Proyecto: att/uwin
static Boolean
read_atoms_table(Display *display, XmDndAtomsTable tbl)
{
    Atom da, atype;
    Window win;
    int aformat, i;
    unsigned long nitems, bafter;
    XmDndAtoms *atoms = NULL;
    Boolean got_it = False;
    XmDndAtomsTableEntryRec atom_ent;
    XmDndBufMgrRec bmgr;

    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atoms_table(%d)\n",
		      __FILE__, __LINE__));

    da = XmInternAtom(display, _XA_MOTIF_DRAG_ATOMS, False);

    win = get_drag_window(display);

    begin_protection(display, win);

    if (XGetWindowProperty(display, win, da, 0L, PROP_LENGTH,
			   False, da,
			   &atype, &aformat, &nitems, &bafter,
			   (unsigned char **)&atoms) == Success &&
	nitems >= 8)
    {
        DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - got property, bafter=%i\n",
		      __FILE__, __LINE__, bafter));    
	got_it = True;
    }

    end_protection(display);

    if (bad_window)
    {
	_XmWarning((Widget)XmGetXmDisplay(display),
		   "Invalid DRAG WINDOW fetching DRAG_ATOMS.");
    }

    if (!got_it)
    {
	if (atoms)
	{
	    XFree((XPointer)atoms);
	}

	return False;
    }

    if (atoms->protocol_version != DND_PROTOCOL_VERSION)
    {
	_XmWarning((Widget)XmGetXmDisplay(display),
		   "DND Protocol version mismatch.");
    }

    if (atoms->byte_order != _XmByteOrder())
    {
	SWAP2BYTES(atoms->num_atoms);
	SWAP4BYTES(atoms->data_size);
    }

    if (!tbl)
    {
	tbl = (XmDndAtomsTable) XtMalloc(sizeof(XmDndAtomsTableRec));

	tbl->num_entries = 0;
	tbl->entries = NULL;

	set_atoms_table(display, tbl);
    }

    if (tbl->num_entries < atoms->num_atoms)
    {
	tbl->entries = (XmDndAtomsTableEntry) XtRealloc((char *)tbl->entries,
							atoms->num_atoms *
					      sizeof(XmDndAtomsTableEntryRec));
    }

    if (atoms->num_atoms > 0)
    {

	bmgr.atoms = (char *)atoms;
	bmgr.atom_start = (char *)(atoms + 1);
	bmgr.atom_size = atoms->data_size;

	for (i = 0; i < atoms->num_atoms; i++)
	{
	    _XmReadDragBuffer(&bmgr, False, (char *)&atom_ent,
			      sizeof(XmDndAtomsTableEntryRec));

	    if (atoms->byte_order != _XmByteOrder())
	    {
		SWAP4BYTES(atom_ent.atom);
		SWAP4BYTES(atom_ent.time);
	    }

	    tbl->entries[i].atom = atom_ent.atom;
	    tbl->entries[i].time = atom_ent.time;
	}
    }

    return True;
}
Ejemplo n.º 6
0
Archivo: DragBS.c Proyecto: att/uwin
/*
 * get the ATOM_PAIRS.  They may or may not already exist
 */
static Boolean
read_atom_pairs(Display *display)
{
    Atom pa, atype;
    Window win;
    Boolean gotit = False;
    XmDndAtomPairs *pairs;
    XmDndBufMgrRec bmgr;
    int i;
    XmDndAtomPair pair;
    char buf[32];
    int aformat;
    unsigned long nitems, bafter;
    unsigned char *prop = NULL;

    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d)\n",
		      __FILE__, __LINE__));

    pa = XmInternAtom(display, _XA_MOTIF_DRAG_ATOM_PAIRS, False);

    win = get_drag_window(display);

    begin_protection(display, win);

    if (XGetWindowProperty(display, win, pa, 0L, PROP_LENGTH,
			   False, pa,
			   &atype, &aformat, &nitems, &bafter,
			   (unsigned char **)&pairs) == Success &&
	nitems >= 8 && pairs != NULL)
    {
	DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - got property, bafter=%i\n",
		      __FILE__, __LINE__, bafter));

	gotit = True;
	prop = (unsigned char *)pairs;
    }
    end_protection(display);

    if (bad_window)
    {
	_XmWarning((Widget)XmGetXmDisplay(display),
		   "Bad window ATOM_PAIRS property on DRAG_WINDOW.");
    }

    if (!gotit)
    {
#if 0
	_XmWarning((Widget)XmGetXmDisplay(display),
		   "No ATOM_PAIRS property on DRAG_WINDOW.");
#endif

	if (prop)
	{
	    XFree((char *)prop);
	}

	DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - did not get property\n",
		      __FILE__, __LINE__));

	return False;
    }

    if (pairs->protocol_version != DND_PROTOCOL_VERSION)
    {
	_XmWarning((Widget)XmGetXmDisplay(display),
		   "DND Protocol version mismatch.");
    }

    if (pairs->byte_order != _XmByteOrder())
    {
	SWAP2BYTES(pairs->num_pairs);
	SWAP4BYTES(pairs->data_size);
    }

    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - %i pairs\n",
		      __FILE__, __LINE__,
		      pairs->num_pairs));

    if (pairs->num_pairs > 0)
    {
	bmgr.atoms = (char *)pairs;
	bmgr.atom_start = (char *)(pairs + 1);
	bmgr.atom_size = pairs->data_size;
	bmgr.names = (char *)pairs + pairs->data_size;
	bmgr.name_start = (char *)pairs + pairs->data_size;
	bmgr.name_size = nitems - pairs->data_size;

	for (i = 0; i < pairs->num_pairs; i++)
	{
	    _XmReadDragBuffer(&bmgr, False, (char *)&pair,
			      sizeof(XmDndAtomPair));

	    if (pairs->byte_order != _XmByteOrder())
	    {
		SWAP4BYTES(pair.atom);
		SWAP2BYTES(pair.namelen);
	    }

	    _XmReadDragBuffer(&bmgr, True, buf, pair.namelen);

	    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_atom_pairs(%d) - intern %s\n",
		      __FILE__, __LINE__,
		      buf));

	    _XmInternAtomAndName(display, pair.atom, buf);
	}
    }

    if (prop)
    {
	XFree((char *)prop);
    }

    return gotit;
}
Ejemplo n.º 7
0
Archivo: DragBS.c Proyecto: att/uwin
/*
 * get the drag receiver info property from the target
 *
 * check out the _XA_MOTIF_DRAG_RECEIVER_INFO property on a Motif
 * application's window.  There's a lot more there than what Daniel
 * talks about.  Must be due to PREREGISTER, yes?
 */
extern Boolean
_XmGetDragReceiverInfo(Display *display, Window win, XmDragReceiverInfo ri)
{
    Atom dri;
    XmDndReceiverProp *receiver;
    Atom type;
    int format;
    unsigned int border;
    unsigned long bafter, length;
    Window root;

    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:_XmGetDragReceiverInfo(%d)\n",
		      __FILE__, __LINE__));
    DEBUGOUT(_LtDebug0("DRAGSOURCE", NULL, "%s:_XmGetDragReceiverInfo(%d) - %p\n",
		      __FILE__, __LINE__, win));

    dri = XmInternAtom(display, _XA_MOTIF_DRAG_RECEIVER_INFO, False);

    if (XGetWindowProperty(display, win, dri, 0L, PROP_LENGTH, False,
			   dri, &type, &format, &length, &bafter,
			   (unsigned char **)&receiver) != Success)
    {
	DEBUGOUT(_LtDebug0("DRAGSOURCE", NULL, "%s:_XmGetDragReceiverInfo(%d) - getting prop failed\n",
		      __FILE__, __LINE__));
	return False;
    }

    if (length < sizeof(XmDndReceiverProp))
    {
	ri->dragProtocolStyle = XmDRAG_NONE;
	XFree((char *)receiver);
	DEBUGOUT(_LtDebug0("DRAGSOURCE", NULL, "%s:_XmGetDragReceiverInfo(%d) - None available\n",
		      __FILE__, __LINE__));
	return False;
    }

    if (receiver->protocol_version != DND_PROTOCOL_VERSION)
    {
	_XmWarning(NULL, "Drag protocol version mismatch: %d vs %d\n",
		   DND_PROTOCOL_VERSION, receiver->protocol_version);
    }

    if (receiver->byte_order != _XmByteOrder())
    {
	SWAP4BYTES(receiver->proxy_window);
	SWAP2BYTES(receiver->num_drop_sites);
	SWAP4BYTES(receiver->total_size);
    }

    Display_ProxyWindow(XmGetXmDisplay(display)) = receiver->proxy_window;

    ri->dragProtocolStyle = receiver->protocol_style;
    ri->iccInfo = (XtPointer)XtMalloc(sizeof(XmShellDropSiteInfoRec));

    DSI_ByteOrder(ri->iccInfo) = receiver->byte_order;
    DSI_NumDropSites(ri->iccInfo) = receiver->num_drop_sites;
    DSI_Info(ri->iccInfo).atoms = (char *)receiver;
    DSI_Info(ri->iccInfo).atom_size = receiver->total_size;
    DSI_Info(ri->iccInfo).atom_start = (char *)(receiver + 1);
    DSI_Info(ri->iccInfo).names = (char *)receiver + receiver->total_size;
    DSI_Info(ri->iccInfo).name_size = length - receiver->total_size;

    XGetGeometry(display, win, &root,
		 &ri->xOrigin, &ri->yOrigin, &ri->width, &ri->height,
		 &border, &ri->depth);

    XTranslateCoordinates(display, win, root, -border, -border,
			  &ri->xOrigin, &ri->yOrigin, &root);

    return True;
}
Ejemplo n.º 8
0
Archivo: DragBS.c Proyecto: att/uwin
static Boolean
read_targets_table(Display *display, XmDndTargetsTable tbl)
{
    Atom ta, atype;
    Window win;
    int aformat, i;
    unsigned long nitems, bafter;
    XmDndTargets *targets = NULL;
    Boolean got_it = False;
    XmDndBufMgrRec bmgr;
    CARD16 nents;

    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d)\n",
		      __FILE__, __LINE__));

    ta = XmInternAtom(display, _XA_MOTIF_DRAG_TARGETS, False);

    win = get_drag_window(display);

    begin_protection(display, win);

    if (XGetWindowProperty(display, win, ta, 0L, PROP_LENGTH,
			   False, ta,
			   &atype, &aformat, &nitems, &bafter,
			   (unsigned char **)&targets) == Success &&
	nitems >= 8)
    {
        DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d) bafter=%i\n",
		      __FILE__, __LINE__, bafter));

	got_it = True;
    }

    end_protection(display);

    if (bad_window)
    {
	_XmWarning((Widget)XmGetXmDisplay(display),
		   "Invalid DRAG WINDOW fetching DRAG_ATOMS.");
    }

    if (!got_it)
    {
	if (targets)
	{
	    XFree((XPointer)targets);
	}

	DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d) - False\n",
		      __FILE__, __LINE__));

	return False;
    }

    if (targets->protocol_version != DND_PROTOCOL_VERSION)
    {
	_XmWarning((Widget)XmGetXmDisplay(display),
		   "DND Protocol version mismatch.");
    }

    if (targets->byte_order != _XmByteOrder())
    {
	SWAP2BYTES(targets->num_target_lists);
	SWAP4BYTES(targets->data_size);
    }

    if (!tbl)
    {
	tbl = (XmDndTargetsTable)XtMalloc(sizeof(XmDndTargetsTableRec));

	tbl->num_entries = 0;
	tbl->entries = NULL;

	set_targets_table(display, tbl);
    }

    if (tbl->num_entries < targets->num_target_lists)
    {
	tbl->num_entries = targets->num_target_lists;
	tbl->entries =
	    (XmDndTargetsTableEntry)XtRealloc((char *)tbl->entries,
					      targets->num_target_lists *
					    sizeof(XmDndTargetsTableEntryRec));
    }

    if (targets->num_target_lists > 0)
    {

	bmgr.atoms = (char *)targets;
	bmgr.atom_start = (char *)(targets + 1);
	bmgr.atom_size = targets->data_size;

	for (i = 0; i < targets->num_target_lists; i++)
	{

	    _XmReadDragBuffer(&bmgr, False, (char *)&nents,
			      sizeof(CARD16));

	    if (targets->byte_order != _XmByteOrder())
	    {
		SWAP2BYTES(nents);
	    }

	    tbl->entries[i].num_targets = nents;
	    tbl->entries[i].targets = (Atom *)XtMalloc(nents * sizeof(Atom));

            read_atoms_from_drag_buffer(&bmgr, tbl->entries[i].num_targets,
                                        targets->byte_order != _XmByteOrder(),
                                        tbl->entries[i].targets);
	}
    }

    DEBUGOUT(_LtDebug0(__FILE__, NULL, "%s:read_targets_table(%d) - True %p\n",
		      __FILE__, __LINE__, tbl));

    if (targets)
     {
         XFree((XPointer)targets);
     }
    return True;
}
Ejemplo n.º 9
0
static PyObject *
py_decodelzw(PyObject *obj, PyObject *args)
{
    PyThreadState *_save = NULL;
    PyObject *byteobj = NULL;
    PyObject *result = NULL;
    int i, j;
    unsigned int encoded_len = 0;
    unsigned int decoded_len = 0;
    unsigned int result_len = 0;
    unsigned int table_len = 0;
    unsigned int len;
    unsigned int code, c, oldcode, mask, bitw, shr, bitcount;
    char *encoded = NULL;
    char *result_ptr = NULL;
    char *table2 = NULL;
    char *cptr;
    struct BYTE_STRING *decoded = NULL;
    struct BYTE_STRING *table[4096];
    struct BYTE_STRING *decoded_ptr, *newentry, *newresult, *t;
    int little_endian = 0;

    if (!PyArg_ParseTuple(args, "O", &byteobj))
        return NULL;

    if (!PyBytes_Check(byteobj)) {
        PyErr_Format(PyExc_TypeError, "expected byte string as input");
        goto _fail;
    }

    Py_INCREF(byteobj);
    encoded = PyBytes_AS_STRING(byteobj);
    encoded_len = (unsigned int)PyBytes_GET_SIZE(byteobj);

    /* release GIL: byte/string objects are immutable */
    _save = PyEval_SaveThread();

    if ((*encoded != -128) || ((*(encoded+1) & 128))) {
        PyEval_RestoreThread(_save);
        PyErr_Format(PyExc_ValueError,
            "strip must begin with CLEAR code");
        goto _fail;
    }
    little_endian = (*(unsigned short *)encoded) & 128;

    /* allocate buffer for codes and pointers */
    decoded_len = 0;
    len = (encoded_len + encoded_len/9) * sizeof(decoded);
    decoded = PyMem_Malloc(len * sizeof(void *));
    if (decoded == NULL) {
        PyEval_RestoreThread(_save);
        PyErr_Format(PyExc_MemoryError, "failed to allocate decoded");
        goto _fail;
    }
    memset((void *)decoded, 0, len * sizeof(void *));
    decoded_ptr = decoded;

    /* cache strings of length 2 */
    cptr = table2 = PyMem_Malloc(256*256*2 * sizeof(char));
    if (table2 == NULL) {
        PyEval_RestoreThread(_save);
        PyErr_Format(PyExc_MemoryError, "failed to allocate table2");
        goto _fail;
    }
    for (i = 0; i < 256; i++) {
        for (j = 0; j < 256; j++) {
            *cptr++ = (char)i;
            *cptr++ = (char)j;
        }
    }

    memset(table, 0, sizeof(table));
    table_len = 258;
    bitw = 9;
    shr = 23;
    mask = 4286578688;
    bitcount = 0;
    result_len = 0;
    code = 0;
    oldcode = 0;

    while ((unsigned int)((bitcount + bitw) >> 3) <= encoded_len) {
        /* read next code */
        code = *((unsigned int *)((void *)(encoded + (bitcount / 8))));
        if (little_endian)
            code = SWAP4BYTES(code);
        code <<= bitcount % 8;
        code &= mask;
        code >>= shr;
        bitcount += bitw;

        if (code == 257) /* end of information */
            break;

        if (code == 256) {  /* clearcode */
            /* initialize table and switch to 9 bit */
            while (table_len > 258) {
                t = table[--table_len];
                t->ref--;
                if (t->ref == 0) {
                    if (t->len > 2)
                        PyMem_Free(t->str);
                    PyMem_Free(t);
                }
            }
            bitw = 9;
            shr = 23;
            mask = 4286578688;

            /* read next code */
            code = *((unsigned int *)((void *)(encoded + (bitcount / 8))));
            if (little_endian)
                code = SWAP4BYTES(code);
            code <<= bitcount % 8;
            code &= mask;
            code >>= shr;
            bitcount += bitw;

            if (code == 257) /* end of information */
                break;

            /* decoded.append(table[code]) */
            if (code < 256) {
                result_len++;
                *((int *)decoded_ptr++) = code;
            } else {
                newresult = table[code];
                newresult->ref++;
                result_len += newresult->len;
                 *(struct BYTE_STRING **)decoded_ptr++ = newresult;
            }
        } else {
            if (code < table_len) {
                /* code is in table */
                /* newresult = table[code]; */
                /* newentry = table[oldcode] + table[code][0] */
                /* decoded.append(newresult); table.append(newentry) */
                if (code < 256) {
                    c = code;
                    *((unsigned int *)decoded_ptr++) = code;
                    result_len++;
                } else {
                    newresult = table[code];
                    newresult->ref++;
                    c = (unsigned int) *newresult->str;
                    *(struct BYTE_STRING **)decoded_ptr++ = newresult;
                    result_len += newresult->len;
                }
                newentry = PyMem_Malloc(sizeof(struct BYTE_STRING));
                newentry->ref = 1;
                if (oldcode < 256) {
                    newentry->len = 2;
                    newentry->str = table2 + (oldcode << 9) +
                                    ((unsigned char)c << 1);
                } else {
                    len = table[oldcode]->len;
                    newentry->len = len + 1;
                    newentry->str = PyMem_Malloc(newentry->len);
                    if (newentry->str == NULL)
                        break;
                    memmove(newentry->str, table[oldcode]->str, len);
                    newentry->str[len] = c;
                }
                table[table_len++] = newentry;
            } else {
                /* code is not in table */
                /* newentry = newresult = table[oldcode] + table[oldcode][0] */
                /* decoded.append(newresult); table.append(newentry) */
                newresult = PyMem_Malloc(sizeof(struct BYTE_STRING));
                newentry = newresult;
                newentry->ref = 2;
                if (oldcode < 256) {
                    newentry->len = 2;
                    newentry->str = table2 + 514*oldcode;
                } else {
                    len = table[oldcode]->len;
                    newentry->len = len + 1;
                    newentry->str = PyMem_Malloc(newentry->len);
                    if (newentry->str == NULL)
                        break;
                    memmove(newentry->str, table[oldcode]->str, len);
                    newentry->str[len] = *table[oldcode]->str;
                }
                table[table_len++] = newentry;
                *(struct BYTE_STRING **)decoded_ptr++ = newresult;
                result_len += newresult->len;
            }
        }
        oldcode = code;
        /* increase bit-width if necessary */
        switch (table_len) {
            case 511:
                bitw = 10;
                shr = 22;
                mask = 4290772992;
                break;
            case 1023:
                bitw = 11;
                shr = 21;
                mask = 4292870144;
                break;
            case 2047:
                bitw = 12;
                shr = 20;
                mask = 4293918720;
        }
    }