Ejemplo n.º 1
0
// Verbosity level currently supports 0 (low), 1 (medium), 2 (high)
// Buffer must be hold enough to hold the output string.  See the source to get an idea of how many bytes will be output
void RAK_DLL_EXPORT StatisticsToString( RakNetStatistics *s, char *buffer, int verbosityLevel )
{
	if ( s == 0 )
	{
		sprintf( buffer, "stats is a NULL pointer in statsToString\n" );
		return ;
	}

	if ( verbosityLevel == 0 )
	{
		// Verbosity level 0
		sprintf( buffer,
			"Total bytes sent: %u\n"
			"Total bytes received: %u\n"
			"Packetloss: %.1f%%\n",
			(unsigned int) BITS_TO_BYTES( s->totalBitsSent ),
			(unsigned int) BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
			100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent );
	}

	else if ( verbosityLevel == 1 )
	{
		RakNetTime time = RakNet::GetTime();
		double elapsedTime;
		double bpsSent;
		double bpsReceived;
		elapsedTime = (time-s->connectionStartTime) / 1000.0f;
		bpsSent = (double) s->totalBitsSent / elapsedTime;
		bpsReceived= (double) s->bitsReceived / elapsedTime;
		// Verbosity level 1

		sprintf( buffer,
			"Messages in Send buffer: %u\n"
			"Messages sent: %u\n"
			"Bytes sent: %u\n"
			"Acks sent: %u\n"
			"Acks in send buffer: %u\n"
			"Messages waiting for ack: %u\n"
			"Messages resent: %u\n"
			"Bytes resent: %u\n"
			"Packetloss: %.1f%%\n"
			"Messages received: %u\n"
			"Bytes received: %u\n"
			"Acks received: %u\n"
			"Duplicate acks received: %u\n"
			"Inst. KBits per second: %.1f\n"
			"KBits per second sent:\t\t\t%.1f\n"
			"KBits per second received:\t\t%.1f\n"
			"Bandwith exceeded:\t\t\t%i\n",
			s->messageSendBuffer[ SYSTEM_PRIORITY ] + s->messageSendBuffer[ HIGH_PRIORITY ] + s->messageSendBuffer[ MEDIUM_PRIORITY ] + s->messageSendBuffer[ LOW_PRIORITY ],
			s->messagesSent[ SYSTEM_PRIORITY ] + s->messagesSent[ HIGH_PRIORITY ] + s->messagesSent[ MEDIUM_PRIORITY ] + s->messagesSent[ LOW_PRIORITY ],
			(unsigned int) BITS_TO_BYTES( s->totalBitsSent ),
			s->acknowlegementsSent,
			s->acknowlegementsPending,
			s->messagesOnResendQueue,
			s->messageResends,
			(unsigned int) BITS_TO_BYTES( s->messagesTotalBitsResent ),
			100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent,
			s->duplicateMessagesReceived + s->invalidMessagesReceived + s->messagesReceived,
			(unsigned int) BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
			s->acknowlegementsReceived,
			s->duplicateAcknowlegementsReceived,
			s->bitsPerSecond  / 1000.0,
			bpsSent / 1000.0,
			bpsReceived / 1000.0,
			s->bandwidthExceeded);
	}
	else
	{
		RakNetTime time = RakNet::GetTime();
		double elapsedTime;
		double bpsSent;
		double bpsReceived;
		elapsedTime = (time-s->connectionStartTime) / 1000.0f;
		bpsSent = (double) s->totalBitsSent / elapsedTime;
		bpsReceived= (double) s->bitsReceived / elapsedTime;

		// Verbosity level 2.
		sprintf( buffer,
			"Bytes sent:\t\t\t\t%u\n"
			"Messages in send buffer:\t\tSP:%u HP:%u MP:%u LP:%u\n"
			"Messages sent:\t\t\t\tSP:%u HP:%u MP:%u LP:%u\n"
			"Message data bytes sent:\t\tSP:%u HP:%u MP:%u LP:%u\n"
			"Message header bytes sent:\t\tSP:%u HP:%u MP:%u LP:%u\n"
			"Message total bytes sent:\t\tSP:%u HP:%u MP:%u LP:%u\n"
			"Bytes received:\t\t\t\tTtl:%u Good:%u Bad:%u\n"
			"Packets received:\t\t\tTtl:%u Good:%u Bad:%u\n"
			"Acks received:\t\t\t\tTtl:%u Good:%u Dup:%u\n"
			"Messages received:\t\t\tTotal:%u Valid:%u Invalid:%u Dup:%u\n"
			"Packetloss:\t\t\t\t%.1f%%\n"
			"Packets sent:\t\t\t\t%u\n"
			"Acks sent:\t\t\t\t%u\n"
			"Acks in send buffer:\t\t\t%u\n"
			"Messages waiting for ack:\t\t%u\n"
			"Ack bytes sent:\t\t\t\t%u\n"
			"Sent packets containing only acks:\t%u\n"
			"Sent packets w/only acks and resends:\t%u\n"
			"Reliable messages resent:\t\t%u\n"
			"Reliable message data bytes resent:\t%u\n"
			"Reliable message header bytes resent:\t%u\n"
			"Reliable message total bytes resent:\t%u\n"
			"Number of messages split:\t\t%u\n"
			"Number of messages unsplit:\t\t%u\n"
			"Message splits performed:\t\t%u\n"
			"Additional encryption bytes:\t\t%u\n"
			"Sequenced messages out of order:\t%u\n"
			"Sequenced messages in order:\t\t%u\n"
			"Ordered messages out of order:\t\t%u\n"
			"Ordered messages in of order:\t\t%u\n"
			"Split messages waiting for reassembly:\t%u\n"
			"Messages in internal output queue:\t%u\n"
			"Inst KBits per second:\t\t\t%.1f\n"
			"Elapsed time (sec):\t\t\t%.1f\n"
			"KBits per second sent:\t\t\t%.1f\n"
			"KBits per second received:\t\t%.1f\n"
			"Bandwith exceeded:\t\t\t%i\n",
			(unsigned int) BITS_TO_BYTES( s->totalBitsSent ),
			s->messageSendBuffer[ SYSTEM_PRIORITY ], s->messageSendBuffer[ HIGH_PRIORITY ], s->messageSendBuffer[ MEDIUM_PRIORITY ], s->messageSendBuffer[ LOW_PRIORITY ],
			s->messagesSent[ SYSTEM_PRIORITY ], s->messagesSent[ HIGH_PRIORITY ], s->messagesSent[ MEDIUM_PRIORITY ], s->messagesSent[ LOW_PRIORITY ],
			(unsigned int) BITS_TO_BYTES( s->messageDataBitsSent[ SYSTEM_PRIORITY ] ), BITS_TO_BYTES( s->messageDataBitsSent[ HIGH_PRIORITY ] ), (unsigned int) BITS_TO_BYTES( s->messageDataBitsSent[ MEDIUM_PRIORITY ] ), (unsigned int) BITS_TO_BYTES( s->messageDataBitsSent[ LOW_PRIORITY ] ),
			(unsigned int) BITS_TO_BYTES( s->messageTotalBitsSent[ SYSTEM_PRIORITY ] - s->messageDataBitsSent[ SYSTEM_PRIORITY ] ), (unsigned int) BITS_TO_BYTES( s->messageTotalBitsSent[ HIGH_PRIORITY ] - s->messageDataBitsSent[ HIGH_PRIORITY ] ), (unsigned int) BITS_TO_BYTES( s->messageTotalBitsSent[ MEDIUM_PRIORITY ] - s->messageDataBitsSent[ MEDIUM_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ LOW_PRIORITY ] - s->messageDataBitsSent[ LOW_PRIORITY ] ),
			(unsigned int) BITS_TO_BYTES( s->messageTotalBitsSent[ SYSTEM_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ HIGH_PRIORITY ] ), (unsigned int) BITS_TO_BYTES( s->messageTotalBitsSent[ MEDIUM_PRIORITY ] ), (unsigned int) BITS_TO_BYTES( s->messageTotalBitsSent[ LOW_PRIORITY ] ),
			(unsigned int) BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ), BITS_TO_BYTES( s->bitsReceived ), (unsigned int) BITS_TO_BYTES( s->bitsWithBadCRCReceived ),
			s->packetsReceived + s->packetsWithBadCRCReceived, s->packetsReceived, s->packetsWithBadCRCReceived,
			s->acknowlegementsReceived + s->duplicateAcknowlegementsReceived, s->acknowlegementsReceived, s->duplicateAcknowlegementsReceived,
			s->messagesReceived + s->invalidMessagesReceived + s->duplicateMessagesReceived, s->messagesReceived, s->invalidMessagesReceived, s->duplicateMessagesReceived,
			100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent,
			s->packetsSent,
			s->acknowlegementsSent,
			s->acknowlegementsPending,
			s->messagesOnResendQueue,
			(unsigned int) BITS_TO_BYTES( s->acknowlegementBitsSent ),
			s->packetsContainingOnlyAcknowlegements,
			s->packetsContainingOnlyAcknowlegementsAndResends,
			s->messageResends,
			(unsigned int) BITS_TO_BYTES( s->messageDataBitsResent ),
			(unsigned int) BITS_TO_BYTES( s->messagesTotalBitsResent - s->messageDataBitsResent ),
			(unsigned int) BITS_TO_BYTES( s->messagesTotalBitsResent ),
			s->numberOfSplitMessages,
			s->numberOfUnsplitMessages,
			s->totalSplits,
			(unsigned int) BITS_TO_BYTES( s->encryptionBitsSent ),
			s->sequencedMessagesOutOfOrder,
			s->sequencedMessagesInOrder,
			s->orderedMessagesOutOfOrder,
			s->orderedMessagesInOrder,
			s->messagesWaitingForReassembly,
			s->internalOutputQueueSize,
			s->bitsPerSecond/1000.0,
			elapsedTime,
			bpsSent / 1000.0,
			bpsReceived / 1000.0,
			s->bandwidthExceeded
			);
	}
}
Ejemplo n.º 2
0
/*
 * saveImageFile - saves a cursor or icon file
 */
static bool saveImageFile( img_node *node )
{
    BITMAPARRAYFILEHEADER2      new_file;
    BITMAPFILEHEADER2           *and_part;
    BITMAPFILEHEADER2           *xor_part;
    BITMAPINFO2                 *andbmi;
    BITMAPINFO2                 *xorbmi;
    long                        clrtable_size;
    long                        and_size;
    ULONG                       nextoff;
    RGB2                        *colours;
    FILE                        *fp;
    char                        text[ HINT_TEXT_LEN ];
    char                        filename[ _MAX_FNAME ];
    img_node                    *new_image;
    bool                        ok;

    ok = false;
    fp = fopen( node->fname, "wb" );
    if( fp != NULL ) {
        if( fseek( fp, 0L, SEEK_SET ) == 0 ) {
            ok = true;
            nextoff = 0;
            for( new_image = node; new_image != NULL; new_image = new_image->nexticon ) {
                new_file.usType = BFT_BITMAPARRAY;
                new_file.cbSize = sizeof( BITMAPARRAYFILEHEADER2 );
                new_file.offNext = nextoff;
                new_file.cxDisplay = 0;
                new_file.cyDisplay = 0;

                and_part = fillFileHeader( new_image );
                memcpy( &(new_file.bfh2), and_part, sizeof( BITMAPFILEHEADER2 ) );
                /*
                 * First the info for the AND mask
                 */
                andbmi = GetAndBitmapInfo( new_image );
                if( andbmi == NULL ) {
                    ok = false;
                } else {
                    clrtable_size = sizeof( RGB2 ) * ( 1 << new_image->bitcount );
                    and_size = sizeof( RGB2 ) * 2;

                    new_file.bfh2.offBits = new_file.offNext + new_file.cbSize +
                                            and_size + clrtable_size +
                                            sizeof( BITMAPFILEHEADER2 );
                    memcpy( &(new_file.bfh2.bmp2), andbmi, sizeof( BITMAPINFOHEADER2 ) );
                    colours = (void *)&(andbmi->argbColor[0]);

                    if( fwrite( &new_file, sizeof( BITMAPARRAYFILEHEADER2 ), 1, fp ) != 1 ) {
                        ok = false;
                    } else if( fwrite( colours, and_size, 1, fp ) != 1 ) {
                        ok = false;
                    }
                    FreeDIBitmapInfo( andbmi );
                }
                MemFree( and_part );

                if( ok ) {
                    /*
                     * Now we write the XOR part
                     */
                    xor_part = fillFileHeader( new_image );
                    xorbmi = GetXorBitmapInfo( new_image );
                    if( xorbmi == NULL ) {
                        ok = false;
                    } else {
                        xor_part->offBits = new_file.bfh2.offBits + BITS_TO_BYTES( new_image->width, 2 * new_image->height );
                        memcpy( &(xor_part->bmp2), xorbmi, sizeof( BITMAPINFOHEADER2 ) );
                        colours = (void *)&(xorbmi->argbColor[0]);
                        if( fwrite( xor_part, sizeof( BITMAPFILEHEADER2 ), 1, fp ) != 1 ) {
                            ok = false;
                        } else if( fwrite( colours, clrtable_size, 1, fp ) != 1 ) {
                            ok = false;
                        }
                        FreeDIBitmapInfo( xorbmi );
                    }
                    MemFree( xor_part );
                    nextoff = nextoff + sizeof( BITMAPARRAYFILEHEADER2 ) + and_size + sizeof( BITMAPFILEHEADER2 ) + clrtable_size;
                }
                if( !rc ) {
                    break;
                }
            }
        }
        fclose( fp );
    }
    if( ok ) {
        /*
         * Now we write the bits for all the images in the file.
         */
        if( !writeImageBits( fp, node ) ) {
            return( false );
        }
        AllowRestoreOption( node );
        SetIsSaved( node->hwnd, TRUE );
        GetFnameFromPath( node->fname, filename );
        if( node->imgtype == ICON_IMG ) {
            sprintf( text, "Icon saved to '%s'", filename );
        } else {
            sprintf( text, "Pointer saved to '%s'", filename );
        }
        SetHintText( text );
    }
    return( ok );
} /* saveImageFile */
Ejemplo n.º 3
0
/*
 * Loop thru arts[] array marking state of each article READ/UNREAD
 */
void
parse_unread_arts(
	struct t_group *group)
{
	int i;
	long unread = 0;
	long bitmin, bitmax;
	t_bitmap *newbitmap = (t_bitmap *) 0;

	bitmin = group->newsrc.xmin;
	bitmax = group->newsrc.xmax;

	/*
	 * TODO
	 * what about group->newsrc.xmax > group->xmax?
	 * that should indicate an artnum 'reset' on the server
	 * (or using the "wrong" newsrc for that server)
	 */

	if (group->xmax > group->newsrc.xmax)
		group->newsrc.xmax = group->xmax;

	if (group->newsrc.xmax >= bitmin) {
		newbitmap = my_malloc(BITS_TO_BYTES(group->newsrc.xmax - bitmin + 1));
		NSETRNG0(newbitmap, 0L, group->newsrc.xmax - bitmin);
	}

	for_each_art(i) {
		if (arts[i].artnum < bitmin)
			arts[i].status = ART_READ;
		else if (arts[i].artnum > bitmax)
			arts[i].status = ART_UNREAD;
		else if (NTEST(group->newsrc.xbitmap, arts[i].artnum - bitmin) == ART_READ)
			arts[i].status = ART_READ;
		else
			arts[i].status = ART_UNREAD;

		/* TODO: logic correct? */
		if (newbitmap != NULL && arts[i].status == ART_UNREAD && arts[i].artnum >= bitmin) {
#if 0
		/*
		 * check for wrong article numbers in the overview
		 *
		 * TODO: check disabled as we currently catch the artnum > high_mark
		 *       case in read_nov_file() where we might be able to
		 *       fix the broken artnum (via xref:-parsing). currently
		 *       we just skip the art there.
		 */
			if (arts[i].artnum <= group->xmax)
#endif /* 0 */
				NSET1(newbitmap, arts[i].artnum - bitmin);
			unread++;
		}
	}

	group->newsrc.xbitlen = group->newsrc.xmax - bitmin + 1;

	FreeIfNeeded(group->newsrc.xbitmap);

	group->newsrc.xbitmap = newbitmap;
	group->newsrc.num_unread = unread;
}
Ejemplo n.º 4
0
void FileListTransfer::Send(FileList *fileList, RakPeerInterface *rakPeer, PlayerID recipient, unsigned short setID, PacketPriority priority, char orderingChannel, bool compressData)
{
	RakNet::BitStream outBitstream, encodedData;
	HuffmanEncodingTree tree;
	unsigned int frequencyTable[ 256 ];
	unsigned int i,j;
	unsigned totalCompressedLength, totalLength;
	DataStructures::Queue<FileListNode> compressedFiles;
	FileListNode n;

	if (compressData)
	{
		memset(frequencyTable,0,256*sizeof(unsigned int));

		for (i=0; i < fileList->fileList.Size(); i++)
		{
			for (j=0; j < fileList->fileList[i].dataLength; j++)
			{
				++frequencyTable[(unsigned char)(fileList->fileList[i].data[j])];
			}
		}

		tree.GenerateFromFrequencyTable(frequencyTable);

		// Compress all the files, so we know the total compressed size to be sent
		totalCompressedLength=totalLength=0;
		for (i=0; i < fileList->fileList.Size(); i++)
		{
			encodedData.Reset();
			// Why send compressed chunks if we are not sending the whole file?
			assert(fileList->fileList[i].fileLength==fileList->fileList[i].fileLength);
			tree.EncodeArray((unsigned char*)fileList->fileList[i].data, fileList->fileList[i].dataLength, &encodedData);
			n.dataLength=encodedData.GetNumberOfBitsUsed();
			totalCompressedLength+=BITS_TO_BYTES(n.dataLength);
			totalLength+=fileList->fileList[i].fileLength;
			n.data = new char[BITS_TO_BYTES(n.dataLength)];
			memcpy(n.data, encodedData.GetData(), BITS_TO_BYTES(n.dataLength));
			compressedFiles.Push(n);
		}
	}

	// Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes
	bool anythingToWrite;
	outBitstream.Write((unsigned char)ID_FILE_LIST_TRANSFER_HEADER);
	outBitstream.Write(setID);
	anythingToWrite=fileList->fileList.Size()>0;
	outBitstream.Write(anythingToWrite);
	if (anythingToWrite)
	{
		if (compressData)
		{
			outBitstream.Write(true);
			for (i=0; i < 256; i++)
				outBitstream.WriteCompressed(frequencyTable[i]);
			outBitstream.WriteCompressed(fileList->fileList.Size());
			outBitstream.WriteCompressed(totalLength);
			outBitstream.WriteCompressed(totalCompressedLength);
		}
		else
		{
			outBitstream.Write(false);
			outBitstream.WriteCompressed(fileList->fileList.Size());
			outBitstream.WriteCompressed(totalLength);
		}
		
		rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);

		// Send each possibly compressed file
		for (i=0; i < compressedFiles.Size(); i++)
		{
			outBitstream.Reset();
			outBitstream.Write((unsigned char)ID_FILE_LIST_TRANSFER_FILE);
			outBitstream.Write(fileList->fileList[i].context);
			outBitstream.Write(setID);
			outBitstream.WriteCompressed(i);
			outBitstream.WriteCompressed(fileList->fileList[i].dataLength); // Original length
			if (compressData)
				outBitstream.WriteCompressed(compressedFiles[i].dataLength); // Compressed bitlength			}
			stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream);
			if (compressData)
			{
				outBitstream.WriteBits((const unsigned char*)compressedFiles[i].data, compressedFiles[i].dataLength);
				delete [] compressedFiles[i].data;
			}
			else
				outBitstream.WriteBits((const unsigned char*)fileList->fileList[i].data, fileList->fileList[i].dataLength);
			
			rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
		}
	}
	else
		rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false);
}
Ejemplo n.º 5
0
//void possect_add_old(u32 key, const Pvoid_t tokens);
void possect_add(const Pvoid_t tokens)
{
        static char *posbuf;
        static char *xidbuf;
                
        if (!posbuf){
                posbuf = xmalloc(iblock_size * 8 + 8);
                memset(posbuf, 0, iblock_size * 8 + 8);
                xidbuf = xmalloc((iblock_size * 2 + 3) * 8);
                memset(xidbuf, 0, (iblock_size * 2 + 3) * 8);
        }

        Word_t *ptr;
        u32 len, xoffs, poffs, prev_offs, prev_xid, 
                xsum, xmax, osum, omax;
        Word_t xid = poffs = prev_offs = prev_xid =\
                xsum = osum = osum = omax = xmax = len = 0;
        
        JLF(ptr, tokens, xid);
        while (ptr){
                growing_glist *g = (growing_glist*)*ptr;
                *ptr = poffs;
                rice_encode(posbuf, &poffs, g->lst.lst, g->lst.len);
                free(g);

                xsum += xid - prev_xid;
                osum += poffs - prev_offs;
                
                if (xid - prev_xid > xmax)
                        xmax = xid - prev_xid;
                if (poffs - prev_offs > omax)
                        omax = poffs - prev_offs;

                prev_xid = xid;
                prev_offs = poffs;

                ++len;
                JLN(ptr, tokens, xid);
        }
        poffs = BITS_TO_BYTES(poffs);
        
        xid = prev_xid = prev_offs = xoffs = 0;

        elias_gamma_write(xidbuf, &xoffs, len + 1);

        if (!len)
                goto write_buffers;

        u32 rice_f1 = estimate_rice_f_param(xsum, xmax, len);
        u32 rice_f2 = estimate_rice_f_param(osum, omax, len);
       
        rice_write(xidbuf, &xoffs, rice_f1, 2);
        rice_write(xidbuf, &xoffs, rice_f2, 2);

        JLF(ptr, tokens, xid);
        while (ptr){
                rice_write(xidbuf, &xoffs, xid - prev_xid, rice_f1);
                prev_xid = xid;
                rice_write(xidbuf, &xoffs, *ptr - prev_offs, rice_f2);
                prev_offs = *ptr;
                JLN(ptr, tokens, xid);
        }

write_buffers:
        xoffs = BITS_TO_BYTES(xoffs);
        
        toc_e toc;
        toc.offs = ftello64(data_f);
        toc.val = xoffs;
        fwrite(&toc, sizeof(toc_e), 1, toc_f);
        
        fwrite(xidbuf, xoffs, 1, data_f);
        fwrite(posbuf, poffs, 1, data_f);
        memset(xidbuf, 0, xoffs);
        memset(posbuf, 0, poffs);
}
Ejemplo n.º 6
0
PluginReceiveResult Router::OnReceive(Packet *packet)
{
	if (packet->data[0]==ID_ROUTE_AND_MULTICAST ||
		(packet->length>5 && packet->data[0]==ID_TIMESTAMP && packet->data[5]==ID_ROUTE_AND_MULTICAST))
	{
#ifdef _DO_PRINTF
		RAKNET_DEBUG_PRINTF("%i got routed message from %i\n", peer->GetExternalID(packet->systemAddress).port, packet->systemAddress.port);
#endif
		RakNetTime timestamp;
		PacketPriority priority;
		PacketReliability reliability;
		unsigned char orderingChannel;
		SystemAddress originalSender;
		RakNet::BitStream out;
		BitSize_t outStartingOffset;
		unsigned int payloadBitLength;
		unsigned payloadWriteByteOffset;
		RakNet::BitStream incomingBitstream(packet->data, packet->length, false);
		incomingBitstream.IgnoreBits(8);
		
		if (packet->data[0]==ID_TIMESTAMP)
		{
			incomingBitstream.Read(timestamp);
			out.Write((MessageID)ID_TIMESTAMP);
			out.Write(timestamp);
			incomingBitstream.IgnoreBits(8);
		}

		// Read the send parameters
		unsigned char c;
		incomingBitstream.ReadCompressed(c);
		priority=(PacketPriority)c;
		incomingBitstream.ReadCompressed(c);
		reliability=(PacketReliability)c;
		incomingBitstream.ReadCompressed(orderingChannel);
		incomingBitstream.Read(payloadBitLength);
		
		out.Write((MessageID)ID_ROUTE_AND_MULTICAST);
		out.WriteCompressed((unsigned char)priority);
		out.WriteCompressed((unsigned char)reliability);
		out.WriteCompressed((unsigned char)orderingChannel);
		out.Write(payloadBitLength);
		out.AlignWriteToByteBoundary();
		incomingBitstream.AlignReadToByteBoundary();
		payloadWriteByteOffset=(unsigned int) BITS_TO_BYTES(out.GetWriteOffset());
		out.Write(&incomingBitstream, payloadBitLength); // This write also does a read on incomingBitStream

		if (restrictByType)
		{
			RakNet::BitStream t(out.GetData()+payloadWriteByteOffset, sizeof(unsigned char), false);
			MessageID messageID;
			t.Read(messageID);
			if (allowedTypes.HasData(messageID)==false)
				return RR_STOP_PROCESSING_AND_DEALLOCATE; // Don't route restricted types
		}

		incomingBitstream.Read(originalSender);
		out.Write(originalSender);
		outStartingOffset=out.GetWriteOffset();

		// Deserialize the root
		bool hasData=false;
		SystemAddress recipient;
		unsigned short numberOfChildren;
		incomingBitstream.Read(hasData);
		incomingBitstream.Read(recipient); // This should be our own address
		if (incomingBitstream.ReadCompressed(numberOfChildren)==false)
		{
#ifdef _DEBUG
			RakAssert(0);
#endif
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
		}

		unsigned childIndex;
		bool childHasData=false;
		SystemAddress childRecipient;
		unsigned short childNumberOfChildren;
		SystemAddress immediateRecipient;
		immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS;
		int pendingNodeCount=0;

		for (childIndex=0; childIndex < numberOfChildren; childIndex++)
		{
			while (pendingNodeCount!=-1)
			{
				// Copy out the serialized subtree for this child
				incomingBitstream.Read(childHasData);
				incomingBitstream.Read(childRecipient);
				if (!incomingBitstream.ReadCompressed(childNumberOfChildren))
					return RR_STOP_PROCESSING_AND_DEALLOCATE;
				if (immediateRecipient==UNASSIGNED_SYSTEM_ADDRESS)
				{
					immediateRecipient=childRecipient;
				}

				pendingNodeCount+=childNumberOfChildren-1;

				out.Write(childHasData);
				out.Write(childRecipient);
				out.WriteCompressed(childNumberOfChildren);
			}

#ifdef _DO_PRINTF
			RAKNET_DEBUG_PRINTF("%i routing to %i\n", peer->GetExternalID(packet->systemAddress).port, immediateRecipient.port);
#endif

			// Send what we got so far
			SendUnified(&out, priority, reliability, orderingChannel, immediateRecipient, false);

			// Restart writing the per recipient data
			out.SetWriteOffset(outStartingOffset);

			// Reread the top level node
			immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS;

			pendingNodeCount=0;

		}

		// Write the user payload to the packet struct if this is a destination and change the sender and return true
		if (hasData)
		{
#ifdef _DO_PRINTF
			RAKNET_DEBUG_PRINTF("%i returning payload to user\n", peer->GetExternalID(packet->systemAddress).port);
#endif

			if (packet->data[0]==ID_TIMESTAMP )
			{
				memcpy( packet->data + sizeof(RakNetTime)+sizeof(unsigned char), out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) );
				packet->bitSize=BYTES_TO_BITS(sizeof(RakNetTime)+sizeof(unsigned char))+payloadBitLength;
			}
			else
			{
				memcpy( packet->data, out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) );
				packet->bitSize=payloadBitLength;
			}
			packet->length=(unsigned int) BITS_TO_BYTES(packet->bitSize);
			packet->systemAddress.systemIndex=(SystemIndex)-1;
			packet->systemAddress=originalSender;

			return RR_CONTINUE_PROCESSING;
		}

		// Absorb
		return RR_STOP_PROCESSING_AND_DEALLOCATE;
	}

	return RR_CONTINUE_PROCESSING;
}
Ejemplo n.º 7
0
int WRAPI WRWriteBitmapToData( HBITMAP hbitmap, BYTE **data, uint_32 *size )
{
    BITMAPFILEHEADER    bmfh;
    BITMAPINFO          *bmi;
    long                bitmap_size;
    long                number_of_bytes;
    HDC                 hdc;

    if( hbitmap == (HBITMAP)NULL || data == NULL || size == NULL ) {
        return( FALSE );
    }

    bmi = WRGetDIBitmapInfo( hbitmap );
    if( bmi == NULL ) {
        return( FALSE );
    }

    number_of_bytes = BITS_TO_BYTES( bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth,
                                     bmi->bmiHeader.biHeight );

    bitmap_size = DIB_INFO_SIZE( bmi->bmiHeader.biBitCount );

    hdc = GetDC( (HWND)NULL );
    GetDIBits( hdc, hbitmap, 0, bmi->bmiHeader.biHeight, NULL, bmi, DIB_RGB_COLORS );
    ReleaseDC( (HWND)NULL, hdc );

    if( bmi->bmiHeader.biSizeImage == 0 ) {
        bmi->bmiHeader.biSizeImage = number_of_bytes;
    } else {
        number_of_bytes = bmi->bmiHeader.biSizeImage;
    }

    bmfh.bfType = BITMAP_TYPE;
    bmfh.bfSize = sizeof( BITMAPFILEHEADER ) + bitmap_size + number_of_bytes;
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + bitmap_size;

    // make sure the bitmap can actually be malloc'd!!
    if( bmfh.bfSize > INT_MAX ) {
        MemFree( bmi );
        return( FALSE );
    }

    *data = MemAlloc( bmfh.bfSize );
    if( *data == NULL ) {
        MemFree( bmi );
        return( FALSE );
    }
    *size = 0;

    memcpy( *data + *size, &bmfh, sizeof( BITMAPFILEHEADER ) );
    *size += sizeof( BITMAPFILEHEADER );

    memcpy( *data + *size, bmi, bitmap_size );
    *size += bitmap_size;

    if( !WRWriteDataInPiecesData( bmi, data, size, hbitmap ) ) {
        MemFree( bmi );
        return( FALSE );
    }

    MemFree( bmi );

    return( TRUE );
}
Ejemplo n.º 8
0
/*@ +charint @*/
bool ais_binary_decode(const struct gpsd_errout_t *errout,
		       struct ais_t *ais,
		       const unsigned char *bits, size_t bitlen,
		       struct ais_type24_queue_t *type24_queue)
/* decode an AIS binary packet */
{
    unsigned int u; int i;

#ifdef S_SPLINT_S
    assert(type24_queue != NULL);
#endif /* S_SPLINT_S */
#define UBITS(s, l)	ubits((unsigned char *)bits, s, l, false)
#define SBITS(s, l)	sbits((signed char *)bits, s, l, false)
#define UCHARS(s, to)	from_sixbit((unsigned char *)bits, s, sizeof(to)-1, to)
#define ENDCHARS(s, to)	from_sixbit((unsigned char *)bits, s, (bitlen-(s))/6,to)
    ais->type = UBITS(0, 6);
    ais->repeat = UBITS(6, 2);
    ais->mmsi = UBITS(8, 30);
    gpsd_log(errout, LOG_INF,
	     "AIVDM message type %d, MMSI %09d:\n",
	     ais->type, ais->mmsi);

#define PERMISSIVE_LENGTH_CHECK(correct) \
	if (bitlen < correct) { \
	    gpsd_log(errout, LOG_ERROR, \
		     "AIVDM message type %d size < %d bits (%zd).\n",	\
		     ais->type, correct, bitlen);			\
	    return false; \
	} else if (bitlen > correct) { \
	    gpsd_log(errout, LOG_WARN, \
		     "AIVDM message type %d size > %d bits (%zd).\n",	\
		     ais->type, correct, bitlen);			\
	}
#define RANGE_CHECK(min, max) \
	if (bitlen < min || bitlen > max) { \
	    gpsd_log(errout, LOG_ERROR, \
		     "AIVDM message type %d size is out of range (%zd).\n", \
		     ais->type, bitlen);				\
	    return false; \
	}

    /*
     * Something about the shape of this switch statement confuses
     * GNU indent so badly that there is no point in trying to be
     * finer-grained than leaving it all alone.
     */
    /* *INDENT-OFF* */
    switch (ais->type) {
    case 1:	/* Position Report */
    case 2:
    case 3:
	PERMISSIVE_LENGTH_CHECK(168)
	ais->type1.status	= UBITS(38, 4);
	ais->type1.turn		= SBITS(42, 8);
	ais->type1.speed	= UBITS(50, 10);
	ais->type1.accuracy	= UBITS(60, 1)!=0;
	ais->type1.lon		= SBITS(61, 28);
	ais->type1.lat		= SBITS(89, 27);
	ais->type1.course	= UBITS(116, 12);
	ais->type1.heading	= UBITS(128, 9);
	ais->type1.second	= UBITS(137, 6);
	ais->type1.maneuver	= UBITS(143, 2);
	//ais->type1.spare	= UBITS(145, 3);
	ais->type1.raim		= UBITS(148, 1)!=0;
	ais->type1.radio	= UBITS(149, 19);
	break;
    case 4: 	/* Base Station Report */
    case 11:	/* UTC/Date Response */
	PERMISSIVE_LENGTH_CHECK(168)
	ais->type4.year		= UBITS(38, 14);
	ais->type4.month	= UBITS(52, 4);
	ais->type4.day		= UBITS(56, 5);
	ais->type4.hour		= UBITS(61, 5);
	ais->type4.minute	= UBITS(66, 6);
	ais->type4.second	= UBITS(72, 6);
	ais->type4.accuracy	= UBITS(78, 1)!=0;
	ais->type4.lon		= SBITS(79, 28);
	ais->type4.lat		= SBITS(107, 27);
	ais->type4.epfd		= UBITS(134, 4);
	//ais->type4.spare	= UBITS(138, 10);
	ais->type4.raim		= UBITS(148, 1)!=0;
	ais->type4.radio	= UBITS(149, 19);
	break;
    case 5: /* Ship static and voyage related data */
	if (bitlen != 424) {
	    gpsd_log(errout, LOG_WARN,
		     "AIVDM message type 5 size not 424 bits (%zd).\n",
		     bitlen);
	    /*
	     * For unknown reasons, a lot of transmitters in the wild ship
	     * with a length of 420 or 422.  This is a recoverable error.
	     */
	    if (bitlen < 420)
		return false;
	}
	ais->type5.ais_version  = UBITS(38, 2);
	ais->type5.imo          = UBITS(40, 30);
	UCHARS(70, ais->type5.callsign);
	UCHARS(112, ais->type5.shipname);
	ais->type5.shiptype     = UBITS(232, 8);
	ais->type5.to_bow       = UBITS(240, 9);
	ais->type5.to_stern     = UBITS(249, 9);
	ais->type5.to_port      = UBITS(258, 6);
	ais->type5.to_starboard = UBITS(264, 6);
	ais->type5.epfd         = UBITS(270, 4);
	ais->type5.month        = UBITS(274, 4);
	ais->type5.day          = UBITS(278, 5);
	ais->type5.hour         = UBITS(283, 5);
	ais->type5.minute       = UBITS(288, 6);
	ais->type5.draught      = UBITS(294, 8);
	UCHARS(302, ais->type5.destination);
	if (bitlen >= 423)
	    ais->type5.dte          = UBITS(422, 1);
	//ais->type5.spare        = UBITS(423, 1);
	break;
    case 6: /* Addressed Binary Message */
	RANGE_CHECK(88, 1008);
	ais->type6.seqno          = UBITS(38, 2);
	ais->type6.dest_mmsi      = UBITS(40, 30);
	ais->type6.retransmit     = UBITS(70, 1)!=0;
	//ais->type6.spare        = UBITS(71, 1);
	ais->type6.dac            = UBITS(72, 10);
	ais->type6.fid            = UBITS(82, 6);
	ais->type6.bitcount       = bitlen - 88;
	/* not strictly required - helps stability in testing */ 
	(void)memset(ais->type6.bitdata, '\0', sizeof(ais->type6.bitdata));
	ais->type6.structured = false;
	/* Inland AIS */
	if (ais->type6.dac == 200) {
	    switch (ais->type6.fid) {
	    case 21:	/* ETA at lock/bridge/terminal */
		if (bitlen != 248)
		    break;
		UCHARS(88, ais->type6.dac200fid21.country);
		UCHARS(100, ais->type6.dac200fid21.locode);
		UCHARS(118, ais->type6.dac200fid21.section);
		UCHARS(148, ais->type6.dac200fid21.terminal);
		UCHARS(178, ais->type6.dac200fid21.hectometre);
		ais->type6.dac200fid21.month	= UBITS(208, 4);
		ais->type6.dac200fid21.day	= UBITS(212, 5);
		ais->type6.dac200fid21.hour	= UBITS(217, 5);
		ais->type6.dac200fid21.minute	= UBITS(222, 6);
		ais->type6.dac200fid21.tugs	= UBITS(228, 3);
		ais->type6.dac200fid21.airdraught	= UBITS(231, 12);
		/* skip 5 bits */
		ais->type6.structured = true;
		break;
	    case 22:	/* RTA at lock/bridge/terminal */
		if (bitlen != 232)
		    break;
		UCHARS(88, ais->type6.dac200fid22.country);
		UCHARS(100, ais->type6.dac200fid22.locode);
		UCHARS(118, ais->type6.dac200fid22.section);
		UCHARS(148, ais->type6.dac200fid22.terminal);
		UCHARS(178, ais->type6.dac200fid22.hectometre);
		ais->type6.dac200fid22.month	= UBITS(208, 4);
		ais->type6.dac200fid22.day	= UBITS(212, 5);
		ais->type6.dac200fid22.hour	= UBITS(217, 5);
		ais->type6.dac200fid22.minute	= UBITS(222, 6);
		ais->type6.dac200fid22.status	= UBITS(228, 2);
		/* skip 2 bits */
		ais->type6.structured = true;
		break;
	    case 55:	/* Number of Persons On Board */
		if (bitlen != 168)
		    break;
		ais->type6.dac200fid55.crew	= UBITS(88, 8);
		ais->type6.dac200fid55.passengers	= UBITS(96, 13);
		ais->type6.dac200fid55.personnel	= UBITS(109, 8);
		/* skip 51 bits */
		ais->type6.structured = true;
		break;
	    }
	    break;
	}
	/* UK and Republic Of Ireland */
	else if (ais->type6.dac == 235 || ais->type6.dac == 250) {
	    switch (ais->type6.fid) {
	    case 10:	/* GLA - AtoN monitoring data */
		if (bitlen != 136)
		    break;
		ais->type6.dac235fid10.ana_int	= UBITS(88, 10);
		ais->type6.dac235fid10.ana_ext1	= UBITS(98, 10);
		ais->type6.dac235fid10.ana_ext2	= UBITS(108, 10);
		ais->type6.dac235fid10.racon    = UBITS(118, 2);
		ais->type6.dac235fid10.light    = UBITS(120, 2);
		ais->type6.dac235fid10.alarm    = UBITS(122, 1);
		ais->type6.dac235fid10.stat_ext	= UBITS(123, 8);
		ais->type6.dac235fid10.off_pos  = UBITS(131, 1);
		/* skip 4 bits */
		ais->type6.structured = true;
		break;
	    }
	    break;
	}
	/* International */
	else if (ais->type6.dac == 1)
	    switch (ais->type6.fid) {
	    case 12:	/* IMO236 - Dangerous cargo indication */
		UCHARS(88, ais->type6.dac1fid12.lastport);
		ais->type6.dac1fid12.lmonth		= UBITS(118, 4);
		ais->type6.dac1fid12.lday		= UBITS(122, 5);
		ais->type6.dac1fid12.lhour		= UBITS(127, 5);
		ais->type6.dac1fid12.lminute	= UBITS(132, 6);
		UCHARS(138, ais->type6.dac1fid12.nextport);
		ais->type6.dac1fid12.nmonth		= UBITS(168, 4);
		ais->type6.dac1fid12.nday		= UBITS(172, 5);
		ais->type6.dac1fid12.nhour		= UBITS(177, 5);
		ais->type6.dac1fid12.nminute	= UBITS(182, 6);
		UCHARS(188, ais->type6.dac1fid12.dangerous);
		UCHARS(308, ais->type6.dac1fid12.imdcat);
		ais->type6.dac1fid12.unid		= UBITS(332, 13);
		ais->type6.dac1fid12.amount		= UBITS(345, 10);
		ais->type6.dac1fid12.unit		= UBITS(355, 2);
		/* skip 3 bits */
		ais->type6.structured = true;
		break;
	    case 14:	/* IMO236 - Tidal Window */
		ais->type6.dac1fid32.month	= UBITS(88, 4);
		ais->type6.dac1fid32.day	= UBITS(92, 5);
#define ARRAY_BASE 97
#define ELEMENT_SIZE 93
		for (u = 0; ARRAY_BASE + (ELEMENT_SIZE*u) <= bitlen; u++) {
		    int a = ARRAY_BASE + (ELEMENT_SIZE*u);
		    struct tidal_t *tp = &ais->type6.dac1fid32.tidals[u];
		    tp->lat	= SBITS(a + 0, 27);
		    tp->lon	= SBITS(a + 27, 28);
		    tp->from_hour	= UBITS(a + 55, 5);
		    tp->from_min	= UBITS(a + 60, 6);
		    tp->to_hour	= UBITS(a + 66, 5);
		    tp->to_min	= UBITS(a + 71, 6);
		    tp->cdir	= UBITS(a + 77, 9);
		    tp->cspeed	= UBITS(a + 86, 7);
		}
		ais->type6.dac1fid32.ntidals = u;
#undef ARRAY_BASE
#undef ELEMENT_SIZE
		ais->type6.structured = true;
		break;
	    case 15:	/* IMO236 - Extended Ship Static and Voyage Related Data */
		ais->type6.dac1fid15.airdraught	= UBITS(56, 11);
		ais->type6.structured = true;
		break;
	    case 16:	/* IMO236 - Number of persons on board */
		if (ais->type6.bitcount == 136)
		    ais->type6.dac1fid16.persons = UBITS(88, 13);/* 289 */
		else
		    ais->type6.dac1fid16.persons = UBITS(55, 13);/* 236 */
		ais->type6.structured = true;
		break;
	    case 18:	/* IMO289 - Clearance time to enter port */
		ais->type6.dac1fid18.linkage	= UBITS(88, 10);
		ais->type6.dac1fid18.month	= UBITS(98, 4);
		ais->type6.dac1fid18.day	= UBITS(102, 5);
		ais->type6.dac1fid18.hour	= UBITS(107, 5);
		ais->type6.dac1fid18.minute	= UBITS(112, 6);
		UCHARS(118, ais->type6.dac1fid18.portname);
		UCHARS(238, ais->type6.dac1fid18.destination);
		ais->type6.dac1fid18.lon	= SBITS(268, 25);
		ais->type6.dac1fid18.lat	= SBITS(293, 24);
		/* skip 43 bits */
		ais->type6.structured = true;
		break;
	    case 20:	/* IMO289 - Berthing data - addressed */
		ais->type6.dac1fid20.linkage	= UBITS(88, 10);
		ais->type6.dac1fid20.berth_length	= UBITS(98, 9);
		ais->type6.dac1fid20.berth_depth	= UBITS(107, 8);
		ais->type6.dac1fid20.position	= UBITS(115, 3);
		ais->type6.dac1fid20.month		= UBITS(118, 4);
		ais->type6.dac1fid20.day		= UBITS(122, 5);
		ais->type6.dac1fid20.hour		= UBITS(127, 5);
		ais->type6.dac1fid20.minute		= UBITS(132, 6);
		ais->type6.dac1fid20.availability	= UBITS(138, 1);
		ais->type6.dac1fid20.agent		= UBITS(139, 2);
		ais->type6.dac1fid20.fuel		= UBITS(141, 2);
		ais->type6.dac1fid20.chandler	= UBITS(143, 2);
		ais->type6.dac1fid20.stevedore	= UBITS(145, 2);
		ais->type6.dac1fid20.electrical	= UBITS(147, 2);
		ais->type6.dac1fid20.water		= UBITS(149, 2);
		ais->type6.dac1fid20.customs	= UBITS(151, 2);
		ais->type6.dac1fid20.cartage	= UBITS(153, 2);
		ais->type6.dac1fid20.crane		= UBITS(155, 2);
		ais->type6.dac1fid20.lift		= UBITS(157, 2);
		ais->type6.dac1fid20.medical	= UBITS(159, 2);
		ais->type6.dac1fid20.navrepair	= UBITS(161, 2);
		ais->type6.dac1fid20.provisions	= UBITS(163, 2);
		ais->type6.dac1fid20.shiprepair	= UBITS(165, 2);
		ais->type6.dac1fid20.surveyor	= UBITS(167, 2);
		ais->type6.dac1fid20.steam		= UBITS(169, 2);
		ais->type6.dac1fid20.tugs		= UBITS(171, 2);
		ais->type6.dac1fid20.solidwaste	= UBITS(173, 2);
		ais->type6.dac1fid20.liquidwaste	= UBITS(175, 2);
		ais->type6.dac1fid20.hazardouswaste	= UBITS(177, 2);
		ais->type6.dac1fid20.ballast	= UBITS(179, 2);
		ais->type6.dac1fid20.additional	= UBITS(181, 2);
		ais->type6.dac1fid20.regional1	= UBITS(183, 2);
		ais->type6.dac1fid20.regional2	= UBITS(185, 2);
		ais->type6.dac1fid20.future1	= UBITS(187, 2);
		ais->type6.dac1fid20.future2	= UBITS(189, 2);
		UCHARS(191, ais->type6.dac1fid20.berth_name);
		ais->type6.dac1fid20.berth_lon	= SBITS(311, 25);
		ais->type6.dac1fid20.berth_lat	= SBITS(336, 24);
		ais->type6.structured = true;
		break;
	    case 23:        /* IMO289 - Area notice - addressed */
		break;
	    case 25:	/* IMO289 - Dangerous cargo indication */
		ais->type6.dac1fid25.unit 	= UBITS(88, 2);
		ais->type6.dac1fid25.amount	= UBITS(90, 10);
		for (u = 0; 100 + u*17 < bitlen; u++) {
		    ais->type6.dac1fid25.cargos[u].code    = UBITS(100+u*17,4);
		    ais->type6.dac1fid25.cargos[u].subtype = UBITS(104+u*17,13);
		}
		ais->type6.dac1fid25.ncargos = u;
		ais->type6.structured = true;
		break;
	    case 28:	/* IMO289 - Route info - addressed */
		ais->type6.dac1fid28.linkage	= UBITS(88, 10);
		ais->type6.dac1fid28.sender		= UBITS(98, 3);
		ais->type6.dac1fid28.rtype		= UBITS(101, 5);
		ais->type6.dac1fid28.month		= UBITS(106, 4);
		ais->type6.dac1fid28.day		= UBITS(110, 5);
		ais->type6.dac1fid28.hour		= UBITS(115, 5);
		ais->type6.dac1fid28.minute		= UBITS(120, 6);
		ais->type6.dac1fid28.duration	= UBITS(126, 18);
		ais->type6.dac1fid28.waycount	= UBITS(144, 5);
#define ARRAY_BASE 149
#define ELEMENT_SIZE 55
		for (u = 0; u < (unsigned char)ais->type6.dac1fid28.waycount; u++) {
		    int a = ARRAY_BASE + (ELEMENT_SIZE*u);
		    ais->type6.dac1fid28.waypoints[u].lon = SBITS(a+0, 28);
		    ais->type6.dac1fid28.waypoints[u].lat = SBITS(a+28,27);
		}
#undef ARRAY_BASE
#undef ELEMENT_SIZE
		ais->type6.structured = true;
		break;
	    case 30:	/* IMO289 - Text description - addressed */
		ais->type6.dac1fid30.linkage   = UBITS(88, 10);
		ENDCHARS(98, ais->type6.dac1fid30.text);
		ais->type6.structured = true;
		break;
	    case 32:	/* IMO289 - Tidal Window */
		ais->type6.dac1fid32.month	= UBITS(88, 4);
		ais->type6.dac1fid32.day	= UBITS(92, 5);
#define ARRAY_BASE 97
#define ELEMENT_SIZE 88
		for (u = 0; ARRAY_BASE + (ELEMENT_SIZE*u) <= bitlen; u++) {
		    int a = ARRAY_BASE + (ELEMENT_SIZE*u);
		    struct tidal_t *tp = &ais->type6.dac1fid32.tidals[u];
		    tp->lon	= SBITS(a + 0, 25);
		    tp->lat	= SBITS(a + 25, 24);
		    tp->from_hour	= UBITS(a + 49, 5);
		    tp->from_min	= UBITS(a + 54, 6);
		    tp->to_hour	= UBITS(a + 60, 5);
		    tp->to_min	= UBITS(a + 65, 6);
		    tp->cdir	= UBITS(a + 71, 9);
		    tp->cspeed	= UBITS(a + 80, 8);
		}
		ais->type6.dac1fid32.ntidals = u;
#undef ARRAY_BASE
#undef ELEMENT_SIZE
		ais->type6.structured = true;
		break;
	    }
	if (!ais->type6.structured)
	    (void)memcpy(ais->type6.bitdata,
			 (char *)bits + (88 / CHAR_BIT),
			 BITS_TO_BYTES(ais->type6.bitcount));
	break;
    case 7: /* Binary acknowledge */
    case 13: /* Safety Related Acknowledge */
    {
	unsigned int mmsi[4];
	RANGE_CHECK(72, 158);
	for (u = 0; u < sizeof(mmsi)/sizeof(mmsi[0]); u++)
	    if (bitlen > 40 + 32*u)
		mmsi[u] = UBITS(40 + 32*u, 30);
	    else
		mmsi[u] = 0;
	/*@ -usedef @*/
	ais->type7.mmsi1 = mmsi[0];
	ais->type7.mmsi2 = mmsi[1];
	ais->type7.mmsi3 = mmsi[2];
	ais->type7.mmsi4 = mmsi[3];
	/*@ +usedef @*/
	break;
    }
    case 8: /* Binary Broadcast Message */
	RANGE_CHECK(56, 1008);
	//ais->type8.spare        = UBITS(38, 2);
	ais->type8.dac            = UBITS(40, 10);
	ais->type8.fid            = UBITS(50, 6);
	ais->type8.bitcount       = bitlen - 56;
	/* not strictly required - helps stability in testing */ 
	(void)memset(ais->type8.bitdata, '\0', sizeof(ais->type8.bitdata));
	ais->type8.structured = false;
	if (ais->type8.dac == 1)
	    switch (ais->type8.fid) {
	    case 11:        /* IMO236 - Meteorological/Hydrological data */
		/* layout is almost identical to FID=31 from IMO289 */
		ais->type8.dac1fid11.lat		= SBITS(56, 24);
		ais->type8.dac1fid11.lon		= SBITS(80, 25);
		ais->type8.dac1fid11.day		= UBITS(105, 5);
		ais->type8.dac1fid11.hour		= UBITS(110, 5);
		ais->type8.dac1fid11.minute		= UBITS(115, 6);
		ais->type8.dac1fid11.wspeed		= UBITS(121, 7);
		ais->type8.dac1fid11.wgust		= UBITS(128, 7);
		ais->type8.dac1fid11.wdir		= UBITS(135, 9);
		ais->type8.dac1fid11.wgustdir	= UBITS(144, 9);
		ais->type8.dac1fid11.airtemp	= UBITS(153, 11);
		ais->type8.dac1fid11.humidity	= UBITS(164, 7);
		ais->type8.dac1fid11.dewpoint	= UBITS(171, 10);
		ais->type8.dac1fid11.pressure	= UBITS(181, 9);
		ais->type8.dac1fid11.pressuretend	= UBITS(190, 2);
		ais->type8.dac1fid11.visibility	= UBITS(192, 8);
		ais->type8.dac1fid11.waterlevel	= UBITS(200, 9);
		ais->type8.dac1fid11.leveltrend	= UBITS(209, 2);
		ais->type8.dac1fid11.cspeed		= UBITS(211, 8);
		ais->type8.dac1fid11.cdir		= UBITS(219, 9);
		ais->type8.dac1fid11.cspeed2	= UBITS(228, 8);
		ais->type8.dac1fid11.cdir2		= UBITS(236, 9);
		ais->type8.dac1fid11.cdepth2	= UBITS(245, 5);
		ais->type8.dac1fid11.cspeed3	= UBITS(250, 8);
		ais->type8.dac1fid11.cdir3		= UBITS(258, 9);
		ais->type8.dac1fid11.cdepth3	= UBITS(267, 5);
		ais->type8.dac1fid11.waveheight	= UBITS(272, 8);
		ais->type8.dac1fid11.waveperiod	= UBITS(280, 6);
		ais->type8.dac1fid11.wavedir	= UBITS(286, 9);
		ais->type8.dac1fid11.swellheight	= UBITS(295, 8);
		ais->type8.dac1fid11.swellperiod	= UBITS(303, 6);
		ais->type8.dac1fid11.swelldir	= UBITS(309, 9);
		ais->type8.dac1fid11.seastate	= UBITS(318, 4);
		ais->type8.dac1fid11.watertemp	= UBITS(322, 10);
		ais->type8.dac1fid11.preciptype	= UBITS(332, 3);
		ais->type8.dac1fid11.salinity	= UBITS(335, 9);
		ais->type8.dac1fid11.ice		= UBITS(344, 2);
		ais->type8.structured = true;
		break;
	    case 13:        /* IMO236 - Fairway closed */
		UCHARS(56, ais->type8.dac1fid13.reason);
		UCHARS(176, ais->type8.dac1fid13.closefrom);
		UCHARS(296, ais->type8.dac1fid13.closeto);
		ais->type8.dac1fid13.radius 	= UBITS(416, 10);
		ais->type8.dac1fid13.extunit	= UBITS(426, 2);
		ais->type8.dac1fid13.fday   	= UBITS(428, 5);
		ais->type8.dac1fid13.fmonth 	= UBITS(433, 4);
		ais->type8.dac1fid13.fhour  	= UBITS(437, 5);
		ais->type8.dac1fid13.fminute	= UBITS(442, 6);
		ais->type8.dac1fid13.tday   	= UBITS(448, 5);
		ais->type8.dac1fid13.tmonth 	= UBITS(453, 4);
		ais->type8.dac1fid13.thour  	= UBITS(457, 5);
		ais->type8.dac1fid13.tminute	= UBITS(462, 6);
		/* skip 4 bits */
		ais->type8.structured = true;
		break;
	    case 15:        /* IMO236 - Extended ship and voyage */
		ais->type8.dac1fid15.airdraught	= UBITS(56, 11);
		/* skip 5 bits */
		ais->type8.structured = true;
		break;
	    case 16:	    /* Number of Persons On Board */
		if (ais->type8.bitcount == 136)
		    ais->type8.dac1fid16.persons = UBITS(88, 13);/* 289 */
		else
		    ais->type8.dac1fid16.persons = UBITS(55, 13);/* 236 */
		ais->type8.structured = true;
		break;
	    case 17:        /* IMO289 - VTS-generated/synthetic targets */
#define ARRAY_BASE 56
#define ELEMENT_SIZE 122
		for (u = 0; ARRAY_BASE + (ELEMENT_SIZE*u) <= bitlen; u++) {
		    struct target_t *tp = &ais->type8.dac1fid17.targets[u];
		    int a = ARRAY_BASE + (ELEMENT_SIZE*u);
		    tp->idtype = UBITS(a + 0, 2);
		    switch (tp->idtype) {
		    case DAC1FID17_IDTYPE_MMSI:
			tp->id.mmsi	= UBITS(a + 2, 42);
			break;
		    case DAC1FID17_IDTYPE_IMO:
			tp->id.imo	= UBITS(a + 2, 42);
			break;
		    case DAC1FID17_IDTYPE_CALLSIGN:
			UCHARS(a+2, tp->id.callsign);
			break;
		    default:
			UCHARS(a+2, tp->id.other);
			break;
		    }
		    /* skip 4 bits */
		    tp->lat	= SBITS(a + 48, 24);
		    tp->lon	= SBITS(a + 72, 25);
		    tp->course	= UBITS(a + 97, 9);
		    tp->second	= UBITS(a + 106, 6);
		    tp->speed	= UBITS(a + 112, 10);
		}
		ais->type8.dac1fid17.ntargets = u;
#undef ARRAY_BASE
#undef ELEMENT_SIZE
		ais->type8.structured = true;
		break;
	    case 19:        /* IMO289 - Marine Traffic Signal */
		ais->type8.dac1fid19.linkage	= UBITS(56, 10);
		UCHARS(66, ais->type8.dac1fid19.station);
		ais->type8.dac1fid19.lon	= SBITS(186, 25);
		ais->type8.dac1fid19.lat	= SBITS(211, 24);
		ais->type8.dac1fid19.status	= UBITS(235, 2);
		ais->type8.dac1fid19.signal	= UBITS(237, 5);
		ais->type8.dac1fid19.hour	= UBITS(242, 5);
		ais->type8.dac1fid19.minute	= UBITS(247, 6);
		ais->type8.dac1fid19.nextsignal	= UBITS(253, 5);
		/* skip 102 bits */
		ais->type8.structured = true;
		break;
	    case 21:        /* IMO289 - Weather obs. report from ship */
		break;
	    case 22:        /* IMO289 - Area notice - broadcast */
		break;
	    case 24:        /* IMO289 - Extended ship static & voyage-related data */
		break;
	    case 26:        /* IMO289 - Environmental */
		break;
	    case 27:        /* IMO289 - Route information - broadcast */
		ais->type8.dac1fid27.linkage	= UBITS(56, 10);
		ais->type8.dac1fid27.sender	= UBITS(66, 3);
		ais->type8.dac1fid27.rtype	= UBITS(69, 5);
		ais->type8.dac1fid27.month	= UBITS(74, 4);
		ais->type8.dac1fid27.day	= UBITS(78, 5);
		ais->type8.dac1fid27.hour	= UBITS(83, 5);
		ais->type8.dac1fid27.minute	= UBITS(88, 6);
		ais->type8.dac1fid27.duration	= UBITS(94, 18);
		ais->type8.dac1fid27.waycount	= UBITS(112, 5);
#define ARRAY_BASE 117
#define ELEMENT_SIZE 55
		for (i = 0; i < ais->type8.dac1fid27.waycount; i++) {
		    int a = ARRAY_BASE + (ELEMENT_SIZE*i);
		    ais->type8.dac1fid27.waypoints[i].lon	= SBITS(a + 0, 28);
		    ais->type8.dac1fid27.waypoints[i].lat	= SBITS(a + 28, 27);
		}
#undef ARRAY_BASE
#undef ELEMENT_SIZE
		ais->type8.structured = true;
		break;
	    case 29:        /* IMO289 - Text Description - broadcast */
		ais->type8.dac1fid29.linkage   = UBITS(56, 10);
		ENDCHARS(66, ais->type8.dac1fid29.text);
		ais->type8.structured = true;
		break;
	    case 31:        /* IMO289 - Meteorological/Hydrological data */
		ais->type8.dac1fid31.lon		= SBITS(56, 25);
		ais->type8.dac1fid31.lat		= SBITS(81, 24);
		ais->type8.dac1fid31.accuracy       = (bool)UBITS(105, 1);
		ais->type8.dac1fid31.day		= UBITS(106, 5);
		ais->type8.dac1fid31.hour		= UBITS(111, 5);
		ais->type8.dac1fid31.minute		= UBITS(116, 6);
		ais->type8.dac1fid31.wspeed		= UBITS(122, 7);
		ais->type8.dac1fid31.wgust		= UBITS(129, 7);
		ais->type8.dac1fid31.wdir		= UBITS(136, 9);
		ais->type8.dac1fid31.wgustdir	= UBITS(145, 9);
		ais->type8.dac1fid31.airtemp	= SBITS(154, 11);
		ais->type8.dac1fid31.humidity	= UBITS(165, 7);
		ais->type8.dac1fid31.dewpoint	= SBITS(172, 10);
		ais->type8.dac1fid31.pressure	= UBITS(182, 9);
		ais->type8.dac1fid31.pressuretend	= UBITS(191, 2);
		ais->type8.dac1fid31.visgreater	= UBITS(193, 1);
		ais->type8.dac1fid31.visibility	= UBITS(194, 7);
		ais->type8.dac1fid31.waterlevel	= UBITS(201, 12);
		ais->type8.dac1fid31.leveltrend	= UBITS(213, 2);
		ais->type8.dac1fid31.cspeed		= UBITS(215, 8);
		ais->type8.dac1fid31.cdir		= UBITS(223, 9);
		ais->type8.dac1fid31.cspeed2	= UBITS(232, 8);
		ais->type8.dac1fid31.cdir2		= UBITS(240, 9);
		ais->type8.dac1fid31.cdepth2	= UBITS(249, 5);
		ais->type8.dac1fid31.cspeed3	= UBITS(254, 8);
		ais->type8.dac1fid31.cdir3		= UBITS(262, 9);
		ais->type8.dac1fid31.cdepth3	= UBITS(271, 5);
		ais->type8.dac1fid31.waveheight	= UBITS(276, 8);
		ais->type8.dac1fid31.waveperiod	= UBITS(284, 6);
		ais->type8.dac1fid31.wavedir	= UBITS(290, 9);
		ais->type8.dac1fid31.swellheight	= UBITS(299, 8);
		ais->type8.dac1fid31.swellperiod	= UBITS(307, 6);
		ais->type8.dac1fid31.swelldir	= UBITS(313, 9);
		ais->type8.dac1fid31.seastate	= UBITS(322, 4);
		ais->type8.dac1fid31.watertemp	= SBITS(326, 10);
		ais->type8.dac1fid31.preciptype	= UBITS(336, 3);
		ais->type8.dac1fid31.salinity	= UBITS(339, 9);
		ais->type8.dac1fid31.ice		= UBITS(348, 2);
		ais->type8.structured = true;
		break;
	    }
	else if (ais->type8.dac == 200) {
	    switch (ais->type8.fid) {
	    case 10:	/* Inland ship static and voyage related data */
		if (bitlen != 168)
		    break;
		UCHARS(56, ais->type8.dac200fid10.vin);
		ais->type8.dac200fid10.length	= UBITS(104, 13);
		ais->type8.dac200fid10.beam	= UBITS(117, 10);
		ais->type8.dac200fid10.shiptype	= UBITS(127, 14);
		ais->type8.dac200fid10.hazard	= UBITS(141, 3);
		ais->type8.dac200fid10.draught	= UBITS(144, 11);
		ais->type8.dac200fid10.loaded	= UBITS(155, 2);
		ais->type8.dac200fid10.speed_q	= (bool)UBITS(157, 1);
		ais->type8.dac200fid10.course_q	= (bool)UBITS(158, 1);
		ais->type8.dac200fid10.heading_q	= (bool)UBITS(159, 1);
		/* skip 8 bits */
		/*
		 * Attempt to prevent false matches with this message type 
		 * by range-checking certain fields.
		 */
		if (ais->type8.dac200fid10.hazard > DAC200FID10_HAZARD_MAX
		    || !isascii((int)ais->type8.dac200fid10.vin[0]))
		    ais->type8.structured = false;
		else
		    ais->type8.structured = true;
		break;
	    case 23:	/* EMMA warning */
		if (bitlen != 256)
		    break;
		ais->type8.dac200fid23.start_year	= UBITS(56, 8);
		ais->type8.dac200fid23.start_month	= UBITS(64, 4);
		ais->type8.dac200fid23.start_day	= UBITS(68, 5);
		ais->type8.dac200fid23.end_year	= UBITS(73, 8);
		ais->type8.dac200fid23.end_month	= UBITS(81, 4);
		ais->type8.dac200fid23.end_day	= UBITS(85, 5);
		ais->type8.dac200fid23.start_hour	= UBITS(90, 5);
		ais->type8.dac200fid23.start_minute	= UBITS(95, 6);
		ais->type8.dac200fid23.end_hour	= UBITS(101, 5);
		ais->type8.dac200fid23.end_minute	= UBITS(106, 6);
		ais->type8.dac200fid23.start_lon	= SBITS(112, 28);
		ais->type8.dac200fid23.start_lat	= SBITS(140, 27);
		ais->type8.dac200fid23.end_lon	= SBITS(167, 28);
		ais->type8.dac200fid23.end_lat	= SBITS(195, 27);
		ais->type8.dac200fid23.type	= UBITS(222, 4);
		ais->type8.dac200fid23.min	= SBITS(226, 9);
		ais->type8.dac200fid23.max	= SBITS(235, 9);
		ais->type8.dac200fid23.intensity	= UBITS(244, 2);
		ais->type8.dac200fid23.wind	= UBITS(246, 4);
		/* skip 6 bits */
		ais->type8.structured = true;
		break;
	    case 24:	/* Water level */
		if (bitlen != 168)
		    break;
		UCHARS(56, ais->type8.dac200fid24.country);
#define ARRAY_BASE 68
#define ELEMENT_SIZE 25
		for (i = 0; ARRAY_BASE + (ELEMENT_SIZE*i) < (int)bitlen; i++) {
		    int a = ARRAY_BASE + (ELEMENT_SIZE*i);
		    ais->type8.dac200fid24.gauges[i].id = UBITS(a+0,  11);
		    ais->type8.dac200fid24.gauges[i].level = SBITS(a+11, 14);
		}
		ais->type8.dac200fid24.ngauges = i;
#undef ARRAY_BASE
#undef ELEMENT_SIZE
		/* skip 6 bits */
		ais->type8.structured = true;
		break;
	    case 40:	/* Signal status */
		if (bitlen != 168)
		    break;
		ais->type8.dac200fid40.lon	= SBITS(56, 28);
		ais->type8.dac200fid40.lat	= SBITS(84, 27);
		ais->type8.dac200fid40.form	= UBITS(111, 4);
		ais->type8.dac200fid40.facing	= UBITS(115, 9);
		ais->type8.dac200fid40.direction	= UBITS(124, 3);
		ais->type8.dac200fid40.status	= UBITS(127, 30);
		/* skip 11 bits */
		ais->type8.structured = true;
		break;
	    }
	}
	/* land here if we failed to match a known DAC/FID */
	if (!ais->type8.structured)
	    (void)memcpy(ais->type8.bitdata,
			 (char *)bits + (56 / CHAR_BIT),
			 BITS_TO_BYTES(ais->type8.bitcount));
	break;
    case 9: /* Standard SAR Aircraft Position Report */
	PERMISSIVE_LENGTH_CHECK(168);
	ais->type9.alt		= UBITS(38, 12);
	ais->type9.speed		= UBITS(50, 10);
	ais->type9.accuracy		= (bool)UBITS(60, 1);
	ais->type9.lon		= SBITS(61, 28);
	ais->type9.lat		= SBITS(89, 27);
	ais->type9.course		= UBITS(116, 12);
	ais->type9.second		= UBITS(128, 6);
	ais->type9.regional		= UBITS(134, 8);
	ais->type9.dte		= UBITS(142, 1);
	//ais->type9.spare		= UBITS(143, 3);
	ais->type9.assigned		= UBITS(146, 1)!=0;
	ais->type9.raim		= UBITS(147, 1)!=0;
	ais->type9.radio		= UBITS(148, 20);
	break;
    case 10: /* UTC/Date inquiry */
	PERMISSIVE_LENGTH_CHECK(72);
	//ais->type10.spare        = UBITS(38, 2);
	ais->type10.dest_mmsi      = UBITS(40, 30);
	//ais->type10.spare2       = UBITS(70, 2);
	break;
    case 12: /* Safety Related Message */
	RANGE_CHECK(72, 1008);
	ais->type12.seqno          = UBITS(38, 2);
	ais->type12.dest_mmsi      = UBITS(40, 30);
	ais->type12.retransmit     = (bool)UBITS(70, 1);
	//ais->type12.spare        = UBITS(71, 1);
	ENDCHARS(72, ais->type12.text);
	break;
    case 14:	/* Safety Related Broadcast Message */
	RANGE_CHECK(40, 1008);
	//ais->type14.spare          = UBITS(38, 2);
	ENDCHARS(40, ais->type14.text);
	break;
    case 15:	/* Interrogation */
	RANGE_CHECK(88, 168);
	(void)memset(&ais->type15, '\0', sizeof(ais->type15));
	//ais->type14.spare         = UBITS(38, 2);
	ais->type15.mmsi1		= UBITS(40, 30);
	ais->type15.type1_1		= UBITS(70, 6);
	ais->type15.type1_1		= UBITS(70, 6);
	ais->type15.offset1_1	= UBITS(76, 12);
	//ais->type14.spare2        = UBITS(88, 2);
	if (bitlen > 90) {
	    ais->type15.type1_2	= UBITS(90, 6);
	    ais->type15.offset1_2	= UBITS(96, 12);
	    //ais->type14.spare3    = UBITS(108, 2);
	    if (bitlen > 110) {
		ais->type15.mmsi2	= UBITS(110, 30);
		ais->type15.type2_1	= UBITS(140, 6);
		ais->type15.offset2_1	= UBITS(146, 12);
		//ais->type14.spare4	= UBITS(158, 2);
	    }
	}
	break;
    case 16:	/* Assigned Mode Command */
	RANGE_CHECK(96, 144);
	ais->type16.mmsi1		= UBITS(40, 30);
	ais->type16.offset1		= UBITS(70, 12);
	ais->type16.increment1	= UBITS(82, 10);
	if (bitlen < 144)
	    ais->type16.mmsi2=ais->type16.offset2=ais->type16.increment2 = 0;
	else {
	    ais->type16.mmsi2	= UBITS(92, 30);
	    ais->type16.offset2	= UBITS(122, 12);
	    ais->type16.increment2	= UBITS(134, 10);
	}
	break;
    case 17:	/* GNSS Broadcast Binary Message */
	RANGE_CHECK(80, 816);
	//ais->type17.spare         = UBITS(38, 2);
	ais->type17.lon		= UBITS(40, 18);
	ais->type17.lat		= UBITS(58, 17);
	//ais->type17.spare	        = UBITS(75, 4);
	ais->type17.bitcount        = bitlen - 80;
	(void)memcpy(ais->type17.bitdata,
		     (char *)bits + (80 / CHAR_BIT),
		     BITS_TO_BYTES(ais->type17.bitcount));
	break;
    case 18:	/* Standard Class B CS Position Report */
	PERMISSIVE_LENGTH_CHECK(168)
	ais->type18.reserved	= UBITS(38, 8);
	ais->type18.speed		= UBITS(46, 10);
	ais->type18.accuracy	= UBITS(56, 1)!=0;
	ais->type18.lon		= SBITS(57, 28);
	ais->type18.lat		= SBITS(85, 27);
	ais->type18.course		= UBITS(112, 12);
	ais->type18.heading		= UBITS(124, 9);
	ais->type18.second		= UBITS(133, 6);
	ais->type18.regional	= UBITS(139, 2);
	ais->type18.cs		= UBITS(141, 1)!=0;
	ais->type18.display 	= UBITS(142, 1)!=0;
	ais->type18.dsc     	= UBITS(143, 1)!=0;
	ais->type18.band    	= UBITS(144, 1)!=0;
	ais->type18.msg22   	= UBITS(145, 1)!=0;
	ais->type18.assigned	= UBITS(146, 1)!=0;
	ais->type18.raim		= UBITS(147, 1)!=0;
	ais->type18.radio		= UBITS(148, 20);
	break;
    case 19:	/* Extended Class B CS Position Report */
	PERMISSIVE_LENGTH_CHECK(312)
	ais->type19.reserved     = UBITS(38, 8);
	ais->type19.speed        = UBITS(46, 10);
	ais->type19.accuracy     = UBITS(56, 1)!=0;
	ais->type19.lon          = SBITS(57, 28);
	ais->type19.lat          = SBITS(85, 27);
	ais->type19.course       = UBITS(112, 12);
	ais->type19.heading      = UBITS(124, 9);
	ais->type19.second       = UBITS(133, 6);
	ais->type19.regional     = UBITS(139, 4);
	UCHARS(143, ais->type19.shipname);
	ais->type19.shiptype     = UBITS(263, 8);
	ais->type19.to_bow       = UBITS(271, 9);
	ais->type19.to_stern     = UBITS(280, 9);
	ais->type19.to_port      = UBITS(289, 6);
	ais->type19.to_starboard = UBITS(295, 6);
	ais->type19.epfd         = UBITS(301, 4);
	ais->type19.raim         = UBITS(305, 1)!=0;
	ais->type19.dte          = UBITS(306, 1)!=0;
	ais->type19.assigned     = UBITS(307, 1)!=0;
	//ais->type19.spare      = UBITS(308, 4);
	break;
    case 20:	/* Data Link Management Message */
	RANGE_CHECK(72, 160);
	//ais->type20.spare		= UBITS(38, 2);
	ais->type20.offset1		= UBITS(40, 12);
	ais->type20.number1		= UBITS(52, 4);
	ais->type20.timeout1	= UBITS(56, 3);
	ais->type20.increment1	= UBITS(59, 11);
	ais->type20.offset2		= UBITS(70, 12);
	ais->type20.number2		= UBITS(82, 4);
	ais->type20.timeout2	= UBITS(86, 3);
	ais->type20.increment2	= UBITS(89, 11);
	ais->type20.offset3		= UBITS(100, 12);
	ais->type20.number3		= UBITS(112, 4);
	ais->type20.timeout3	= UBITS(116, 3);
	ais->type20.increment3	= UBITS(119, 11);
	ais->type20.offset4		= UBITS(130, 12);
	ais->type20.number4		= UBITS(142, 4);
	ais->type20.timeout4	= UBITS(146, 3);
	ais->type20.increment4	= UBITS(149, 11);
	break;
    case 21:	/* Aid-to-Navigation Report */
	RANGE_CHECK(272, 360);
	ais->type21.aid_type = UBITS(38, 5);
	from_sixbit((unsigned char *)bits,
		    43, 20, ais->type21.name);
	ais->type21.accuracy     = UBITS(163, 1);
	ais->type21.lon          = SBITS(164, 28);
	ais->type21.lat          = SBITS(192, 27);
	ais->type21.to_bow       = UBITS(219, 9);
	ais->type21.to_stern     = UBITS(228, 9);
	ais->type21.to_port      = UBITS(237, 6);
	ais->type21.to_starboard = UBITS(243, 6);
	ais->type21.epfd         = UBITS(249, 4);
	ais->type21.second       = UBITS(253, 6);
	ais->type21.off_position = UBITS(259, 1)!=0;
	ais->type21.regional     = UBITS(260, 8);
	ais->type21.raim         = UBITS(268, 1)!=0;
	ais->type21.virtual_aid  = UBITS(269, 1)!=0;
	ais->type21.assigned     = UBITS(270, 1)!=0;
	//ais->type21.spare      = UBITS(271, 1);
	if (strlen(ais->type21.name) == 20 && bitlen > 272)
	    ENDCHARS(272, ais->type21.name+20);
	break;
    case 22:	/* Channel Management */
	PERMISSIVE_LENGTH_CHECK(168)
	ais->type22.channel_a    = UBITS(40, 12);
	ais->type22.channel_b    = UBITS(52, 12);
	ais->type22.txrx         = UBITS(64, 4);
	ais->type22.power        = UBITS(68, 1);
	ais->type22.addressed    = UBITS(139, 1);
	if (!ais->type22.addressed) {
	    ais->type22.area.ne_lon       = SBITS(69, 18);
	    ais->type22.area.ne_lat       = SBITS(87, 17);
	    ais->type22.area.sw_lon       = SBITS(104, 18);
	    ais->type22.area.sw_lat       = SBITS(122, 17);
	} else {
	    ais->type22.mmsi.dest1             = UBITS(69, 30);
	    ais->type22.mmsi.dest2             = UBITS(104, 30);
	}
	ais->type22.band_a       = UBITS(140, 1);
	ais->type22.band_b       = UBITS(141, 1);
	ais->type22.zonesize     = UBITS(142, 3);
	break;
    case 23:	/* Group Assignment Command */
	PERMISSIVE_LENGTH_CHECK(160)
	ais->type23.ne_lon       = SBITS(40, 18);
	ais->type23.ne_lat       = SBITS(58, 17);
	ais->type23.sw_lon       = SBITS(75, 18);
	ais->type23.sw_lat       = SBITS(93, 17);
	ais->type23.stationtype  = UBITS(110, 4);
	ais->type23.shiptype     = UBITS(114, 8);
	ais->type23.txrx         = UBITS(144, 4);
	ais->type23.interval     = UBITS(146, 4);
	ais->type23.quiet        = UBITS(150, 4);
	break;
    case 24:	/* Class B CS Static Data Report */
	switch (UBITS(38, 2)) {
	case 0:
	    RANGE_CHECK(160, 168);
	    /* save incoming 24A shipname/MMSI pairs in a circular queue */
	    {
		struct ais_type24a_t *saveptr = &type24_queue->ships[type24_queue->index];

		gpsd_log(errout, LOG_PROG,
			 "AIVDM: 24A from %09u stashed.\n",
			 ais->mmsi);
		saveptr->mmsi = ais->mmsi;
		UCHARS(40, saveptr->shipname);
		++type24_queue->index;
		type24_queue->index %= MAX_TYPE24_INTERLEAVE;
	    }
	    //ais->type24.a.spare	= UBITS(160, 8);

	    UCHARS(40, ais->type24.shipname);
	    ais->type24.part = part_a;
	    return true;
	case 1:
	    PERMISSIVE_LENGTH_CHECK(168)
	    ais->type24.shiptype = UBITS(40, 8);
	    /*
	     * In ITU-R 1371-4, there are new model and serial fields
	     * carved out of the right-hand end of vendorid, which is
	     * reduced from 7 chars to 3.  To cope with older AIS
	     * implementations conforming to revision 3 and older,
	     * unpack the trailing bits *both* ways; truly
	     * revision-4-conformant implementations will have up to
	     * four characters of trailing garbage on the vendorid,
	     * and older implementations will have garbafe in the
	     * model and serial fields.
	     */
	    UCHARS(48, ais->type24.vendorid);
	    ais->type24.model = UBITS(66, 4);
	    ais->type24.serial = UBITS(70, 20);
	    UCHARS(90, ais->type24.callsign);
	    if (AIS_AUXILIARY_MMSI(ais->mmsi)) {
		ais->type24.mothership_mmsi   = UBITS(132, 30);
	    } else {
		ais->type24.dim.to_bow        = UBITS(132, 9);
		ais->type24.dim.to_stern      = UBITS(141, 9);
		ais->type24.dim.to_port       = UBITS(150, 6);
		ais->type24.dim.to_starboard  = UBITS(156, 6);
	    }
	    //ais->type24.b.spare	    = UBITS(162, 8);

	    /* search the 24A queue for a matching MMSI */
	    for (i = 0; i < MAX_TYPE24_INTERLEAVE; i++) {
		if (type24_queue->ships[i].mmsi == ais->mmsi) {
		    (void)strlcpy(ais->type24.shipname,
				  type24_queue->ships[i].shipname,
				  sizeof(ais->type24.shipname));
		    gpsd_log(errout, LOG_PROG,
			     "AIVDM 24B from %09u matches a 24A.\n",
			     ais->mmsi);
		    /* prevent false match if a 24B is repeated */
		    type24_queue->ships[i].mmsi = 0;
		    ais->type24.part = both;
		    return true;
		}
	    }

	    /* no match, return Part B */
	    ais->type24.part = part_b;
	    return true;
	default:
	    gpsd_log(errout, LOG_WARN,
		     "AIVDM message type 24 of subtype unknown.\n");
	    return false;
	}
	// break;
    case 25:	/* Binary Message, Single Slot */
	/* this check and the following one reject line noise */
	if (bitlen < 40 || bitlen > 168) {
	    gpsd_log(errout, LOG_WARN,
		     "AIVDM message type 25 size not between 40 to 168 bits (%zd).\n",
		     bitlen);
	    return false;
	}
	ais->type25.addressed	= (bool)UBITS(38, 1);
	ais->type25.structured	= (bool)UBITS(39, 1);
	if (bitlen < (unsigned)(40 + (16*ais->type25.structured) + (30*ais->type25.addressed))) {
	    gpsd_log(errout, LOG_WARN,
		     "AIVDM message type 25 too short for mode.\n");
	    return false;
	}
	if (ais->type25.addressed)
	    ais->type25.dest_mmsi   = UBITS(40, 30);
	if (ais->type25.structured)
	    ais->type25.app_id      = UBITS(40+ais->type25.addressed*30,16);
	ais->type25.bitcount       = bitlen - 40 - 16*ais->type25.structured;
	/* bit 40 is exactly 5 bytes in; 2 bytes is 16 bits */
	(void)memcpy(ais->type25.bitdata,
		     (char *)bits+5 + 2 * ais->type25.structured,
		     BITS_TO_BYTES(ais->type25.bitcount));
	/* discard MMSI if addressed */
	if (ais->type25.addressed) {
	    shiftleft((unsigned char *)ais->type25.bitdata, ais->type25.bitcount, 30);
	    ais->type25.bitcount -= 30;
	}
	break;
    case 26:	/* Binary Message, Multiple Slot */
	RANGE_CHECK(60, 1004);
	ais->type26.addressed	= (bool)UBITS(38, 1);
	ais->type26.structured	= (bool)UBITS(39, 1);
	if ((signed)bitlen < 40 + 16*ais->type26.structured + 30*ais->type26.addressed + 20) {
	    gpsd_log(errout, LOG_WARN,
		     "AIVDM message type 26 too short for mode.\n");
	    return false;
	}
	if (ais->type26.addressed)
	    ais->type26.dest_mmsi   = UBITS(40, 30);
	if (ais->type26.structured)
	    ais->type26.app_id      = UBITS(40+ais->type26.addressed*30,16);
	ais->type26.bitcount        = bitlen - 60 - 16*ais->type26.structured;
	(void)memcpy(ais->type26.bitdata,
		     (unsigned char *)bits+5 + 2 * ais->type26.structured,
		     BITS_TO_BYTES(ais->type26.bitcount));
	/* discard MMSI if addressed */
	if (ais->type26.addressed) {
	    shiftleft((unsigned char *)ais->type26.bitdata, ais->type26.bitcount, 30);
	    ais->type26.bitcount -= 30;
	}
	break;
    case 27:	/* Long Range AIS Broadcast message */
	if (bitlen != 96 && bitlen != 168) {
	    gpsd_log(errout, LOG_WARN,
		     "unexpected AIVDM message type 27 (%zd).\n",
		     bitlen);
	    return false;
	} if (bitlen == 168) {
	    /*
	     * This is an implementation error observed in the wild,
	     * sending a full 168-bit slot rather than just 96 bits.
	     */
	    gpsd_log(errout, LOG_WARN,
		     "oversized 169=8-bit AIVDM message type 27.\n");
	}
	ais->type27.accuracy        = (bool)UBITS(38, 1);
	ais->type27.raim		= UBITS(39, 1)!=0;
	ais->type27.status		= UBITS(40, 4);
	ais->type27.lon		= SBITS(44, 18);
	ais->type27.lat		= SBITS(62, 17);
	ais->type27.speed		= UBITS(79, 6);
	ais->type27.course		= UBITS(85, 9);
	ais->type27.gnss            = (bool)UBITS(94, 1);
	break;
    default:
	gpsd_log(errout, LOG_ERROR,
		 "Unparsed AIVDM message type %d.\n",ais->type);
	return false;
    }
    /* *INDENT-ON* */
#undef UCHARS
#undef SBITS
#undef UBITS

    /* data is fully decoded */
    return true;
}
Ejemplo n.º 9
0
Archivo: lamp.c Proyecto: Dmilo/freewpc
 * Default lamp values are also tracked per-player.  They are guaranteed to be
 * all off at the start of a player's game, and they are saved/restored in
 * multiplayer games.  The secondary/lightshow values are transient and are not
 * saved this way.
 *
 */

#include <freewpc.h>

__fastram__ lamp_set lamp_matrix;

lamp_set lamp_flash_matrix;

__fastram__ lamp_set lamp_flash_matrix_now;

U8 bit_matrix[BITS_TO_BYTES (MAX_FLAGS)];

U8 global_bits[BITS_TO_BYTES (MAX_GLOBAL_FLAGS)];

#ifdef CONFIG_LAMP_STROBE16
typedef U16 lamp_strobe_t;
#else
typedef U8 lamp_strobe_t;
#endif
__fastram__ lamp_strobe_t lamp_strobe_mask;

__fastram__ U8 lamp_strobe_column;

__fastram__ U8 lamp_power_timer;

U8 lamp_power_level;
Ejemplo n.º 10
0
Archivo: font.c Proyecto: paud/d2x-xl
int GrInternalString0 (int x, int y, char *s)
{
	unsigned char * fp;
	char *text_ptr, *next_row, *text_ptr1;
	int r, BitMask, i, bits, width, spacing, letter, underline;
	int	skip_lines = 0;
	unsigned int VideoOffset, VideoOffset1;
	ubyte *palette = grdCurCanv->cv_bitmap.bm_palette;

if (!palette)
	palette = gamePalette;

if (FG_COLOR.rgb) {
	FG_COLOR.rgb = 0;
	FG_COLOR.index = GrFindClosestColor (gamePalette, 
													 FG_COLOR.color.red, FG_COLOR.color.green, FG_COLOR.color.blue);
	}
if (BG_COLOR.rgb) {
	BG_COLOR.rgb = 0;
	BG_COLOR.index = GrFindClosestColor (gamePalette, 
													 BG_COLOR.color.red, BG_COLOR.color.green, BG_COLOR.color.blue);
	}
bits=0;
VideoOffset1 = y * ROWSIZE + x;
next_row = s;
while (next_row != NULL) {
	text_ptr1 = next_row;
	next_row = NULL;
	if (x == 0x8000) {			//centered
		int xx = GetCenteredX (text_ptr1);
		VideoOffset1 = y * ROWSIZE + xx;
		}
	for (r = 0; r < FHEIGHT; r++) {
		text_ptr = text_ptr1;
		VideoOffset = VideoOffset1;
		while (*text_ptr) {
			if (*text_ptr == '\n') {
				next_row = &text_ptr[1];
				break;
				}
			if (*text_ptr == CC_COLOR) {
				FG_COLOR.index = *(text_ptr+1);
				FG_COLOR.rgb = 0;
				text_ptr += 2;
				continue;
				}
			if (*text_ptr == CC_LSPACING) {
				skip_lines = * (text_ptr+1) - '0';
				text_ptr += 2;
				continue;
				}
			underline = 0;
			if (*text_ptr == CC_UNDERLINE) {
				if ((r == FBASELINE + 2) || (r == FBASELINE + 3))
					underline = 1;
				text_ptr++;
				}	
			get_char_width (text_ptr[0], text_ptr[1], &width, &spacing);
			letter = *text_ptr - FMINCHAR;
			if (!INFONT (letter)) {	//not in font, draw as space
				VideoOffset += spacing;
				text_ptr++;
				continue;
				}
			if (FFLAGS & FT_PROPORTIONAL)
				fp = FCHARS [letter];
			else
				fp = FDATA + letter * BITS_TO_BYTES (width)*FHEIGHT;
			if (underline)
				for (i = 0; i < width; i++)
					DATA[VideoOffset++] = (unsigned char) FG_COLOR.index;
				else {
					fp += BITS_TO_BYTES (width)*r;
					BitMask = 0;
					for (i = 0; i < width; i++) {
						if (BitMask == 0) {
							bits = *fp++;
							BitMask = 0x80;
							}
						if (bits & BitMask)
							DATA[VideoOffset++] = (unsigned char) FG_COLOR.index;
						else
							DATA[VideoOffset++] = (unsigned char) BG_COLOR.index;
						BitMask >>= 1;
						}
					}
			VideoOffset += spacing-width;		//for kerning
			text_ptr++;
			}
		VideoOffset1 += ROWSIZE; y++;
		}
	y += skip_lines;
	VideoOffset1 += ROWSIZE * skip_lines;
	skip_lines = 0;
	}
return 0;
}
Ejemplo n.º 11
0
Archivo: font.c Proyecto: paud/d2x-xl
int GrInternalString0m (int x, int y, char *s)
{
	unsigned char * fp;
	char * text_ptr, * next_row, * text_ptr1;
	int r, BitMask, i, bits, width, spacing, letter, underline;
	int	skip_lines = 0;
	char c;
	int orig_color;
	unsigned int VideoOffset, VideoOffset1;

if (FG_COLOR.rgb) {
	FG_COLOR.rgb = 0;
	FG_COLOR.index = GrFindClosestColor (FONT->ft_parent_bitmap.bm_palette, 
													 FG_COLOR.color.red, FG_COLOR.color.green, FG_COLOR.color.blue);
	}
if (BG_COLOR.rgb) {
	BG_COLOR.rgb = 0;
	BG_COLOR.index = GrFindClosestColor (FONT->ft_parent_bitmap.bm_palette, 
													 BG_COLOR.color.red, BG_COLOR.color.green, BG_COLOR.color.blue);
	}
orig_color = FG_COLOR.index;//to allow easy reseting to default string color with colored strings -MPM
bits=0;
VideoOffset1 = y * ROWSIZE + x;

	next_row = s;
	FG_COLOR.rgb = 0;
	while (next_row != NULL)
	{
		text_ptr1 = next_row;
		next_row = NULL;

		if (x==0x8000) {			//centered
			int xx = GetCenteredX (text_ptr1);
			VideoOffset1 = y * ROWSIZE + xx;
		}

		for (r=0; r<FHEIGHT; r++) {
			text_ptr = text_ptr1;
			VideoOffset = VideoOffset1;
			while ((c = *text_ptr)) {
				if (c == '\n') {
					next_row = &text_ptr[1];
					break;
					}
				if (c == CC_COLOR) {
					FG_COLOR.index = * (++text_ptr);
					text_ptr++;
					continue;
					}
				if (c == CC_LSPACING) {
					skip_lines = * (++text_ptr) - '0';
					text_ptr++;
					continue;
					}
				underline = 0;
				if (c == CC_UNDERLINE) {
					if ((r==FBASELINE+2) || (r==FBASELINE+3))
						underline = 1;
					c = * (++text_ptr);
					}
				get_char_width (c, text_ptr[1], &width, &spacing);
				letter = c - FMINCHAR;
				if (!INFONT (letter) || c <= 0x06) {	//not in font, draw as space
#if 0
					CHECK_EMBEDDED_COLORS () 
#else
					if ((c >= 1) && (c <= 3)) {
						if (*++text_ptr) {
							if (grMsgColorLevel >= c) {
								FG_COLOR.rgb = 1;
								FG_COLOR.color.red = text_ptr [0] - 128;
								FG_COLOR.color.green = text_ptr [1] - 128;
								FG_COLOR.color.blue = text_ptr [2] - 128;
								FG_COLOR.color.alpha = 0;
								}
							text_ptr += 3;
							}
						}
					else if ((c >= 4) && (c <= 6)) {
						if (grMsgColorLevel >= *text_ptr - 3) {
							FG_COLOR.index = orig_color;
							FG_COLOR.rgb = 0;
							}
						text_ptr++;
						}
#endif
					else {
						VideoOffset += spacing;
						text_ptr++;
						}
					continue;
					}
				if (FFLAGS & FT_PROPORTIONAL)
					fp = FCHARS[letter];
				else
					fp = FDATA + letter * BITS_TO_BYTES (width) * FHEIGHT;

				if (underline)
					for (i=0; i< width; i++)
						DATA[VideoOffset++] = (unsigned int) FG_COLOR.index;
				else {
					fp += BITS_TO_BYTES (width)*r;
					BitMask = 0;
					for (i=0; i< width; i++) {
						if (BitMask==0) {
							bits = *fp++;
							BitMask = 0x80;
						}
						if (bits & BitMask)
							DATA[VideoOffset++] = (unsigned int) FG_COLOR.index;
						else
							VideoOffset++;
						BitMask >>= 1;
					}
				}
				text_ptr++;
				VideoOffset += spacing-width;
			}
			VideoOffset1 += ROWSIZE;
			y++;
		}
		y += skip_lines;
		VideoOffset1 += ROWSIZE * skip_lines;
		skip_lines = 0;
	}
Ejemplo n.º 12
0
Packet* RakClient::Receive( void )
{
    Packet * packet = RakPeer::Receive();

    // Intercept specific client / server feature packets

    if ( packet )
    {
        RakNet::BitStream bitStream( ( char* ) packet->data, packet->length, false );
        int i;

        if ( packet->data[ 0 ] == ID_CONNECTION_REQUEST_ACCEPTED )
        {
//			ConnectionAcceptStruct cas;
//			cas.Deserialize(bitStream);
            //	unsigned short remotePort;
            //	PlayerID externalID;
            PlayerIndex playerIndex;

            RakNet::BitStream inBitStream((char*)packet->data, packet->length, false);
            inBitStream.IgnoreBits(8); // ID_CONNECTION_REQUEST_ACCEPTED
            inBitStream.IgnoreBits(8 * sizeof(unsigned short)); //inBitStream.Read(remotePort);
            inBitStream.IgnoreBits(8 * sizeof(unsigned int)); //inBitStream.Read(externalID.binaryAddress);
            inBitStream.IgnoreBits(8 * sizeof(unsigned short)); //inBitStream.Read(externalID.port);
            inBitStream.Read(playerIndex);

            localPlayerIndex = playerIndex;
            packet->playerIndex = playerIndex;
        }
        else if (
            packet->data[ 0 ] == ID_REMOTE_NEW_INCOMING_CONNECTION ||
            packet->data[ 0 ] == ID_REMOTE_EXISTING_CONNECTION ||
            packet->data[ 0 ] == ID_REMOTE_DISCONNECTION_NOTIFICATION ||
            packet->data[ 0 ] == ID_REMOTE_CONNECTION_LOST )
        {
            bitStream.IgnoreBits( 8 ); // Ignore identifier
            bitStream.Read( packet->playerId.binaryAddress );
            bitStream.Read( packet->playerId.port );

            if ( bitStream.Read( ( unsigned short& ) packet->playerIndex ) == false )
            {
                DeallocatePacket( packet );
                return 0;
            }


            if ( packet->data[ 0 ] == ID_REMOTE_DISCONNECTION_NOTIFICATION ||
                    packet->data[ 0 ] == ID_REMOTE_CONNECTION_LOST )
            {
                i = GetOtherClientIndexByPlayerID( packet->playerId );

                if ( i >= 0 )
                    otherClients[ i ].isActive = false;
            }
        }
        else if ( packet->data[ 0 ] == ID_REMOTE_STATIC_DATA )
        {
            bitStream.IgnoreBits( 8 ); // Ignore identifier
            bitStream.Read( packet->playerId.binaryAddress );
            bitStream.Read( packet->playerId.port );
            bitStream.Read( packet->playerIndex ); // ADDED BY KURI

            i = GetOtherClientIndexByPlayerID( packet->playerId );

            if ( i < 0 )
                i = GetFreeOtherClientIndex();

            if ( i >= 0 )
            {
                otherClients[ i ].playerId = packet->playerId;
                otherClients[ i ].isActive = true;
                otherClients[ i ].staticData.Reset();
                // The static data is what is left over in the stream
                otherClients[ i ].staticData.Write( ( char* ) bitStream.GetData() + BITS_TO_BYTES( bitStream.GetReadOffset() ), bitStream.GetNumberOfBytesUsed() - BITS_TO_BYTES( bitStream.GetReadOffset() ) );
            }
        }
        else if ( packet->data[ 0 ] == ID_BROADCAST_PINGS )
        {
            PlayerID playerId;
            int index;

            bitStream.IgnoreBits( 8 ); // Ignore identifier

            for ( i = 0; i < 32; i++ )
            {
                if ( bitStream.Read( playerId.binaryAddress ) == false )
                    break; // No remaining data!

                bitStream.Read( playerId.port );

                index = GetOtherClientIndexByPlayerID( playerId );

                if ( index >= 0 )
                    bitStream.Read( otherClients[ index ].ping );
                else
                {
                    index = GetFreeOtherClientIndex();

                    if ( index >= 0 )
                    {
                        otherClients[ index ].isActive = true;
                        bitStream.Read( otherClients[ index ].ping );
                        otherClients[ index ].playerId = playerId;
                        otherClients[ index ].staticData.Reset();
                    }

                    else
                        bitStream.IgnoreBits( sizeof( short ) * 8 );
                }
            }

            DeallocatePacket( packet );
            return 0;
        }
        else if ( packet->data[ 0 ] == ID_TIMESTAMP &&
                  packet->length == sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned int) )
        {
            /*
            RakNet::BitStream s_BitS( (char *)packet->data, SetRandomNumberSeedStruct_Size, false );
            SetRandomNumberSeedStruct s;
            s.Deserialize( s_BitS );
            */

            RakNet::BitStream inBitStream((char *)packet->data, packet->length, false);
            /*
            unsigned char ts;
            unsigned int timeStamp;
            unsigned char typeId;
            unsigned int seed;
            unsigned int nextSeed;
            */

            unsigned int timeStamp;
            unsigned char typeId;
            unsigned int in_seed;
            unsigned int in_nextSeed;
            inBitStream.IgnoreBits(8); // ID_TIMESTAMP
            inBitStream.Read(timeStamp);
            inBitStream.Read(typeId); // ID_SET_RANDOM_NUMBER_SEED ?

            // Check to see if this is a user TIMESTAMP message which
            // accidentally has length SetRandomNumberSeedStruct_Size
            if ( typeId != ID_SET_RANDOM_NUMBER_SEED )
                return packet;

            inBitStream.Read(in_seed);
            inBitStream.Read(in_nextSeed);

            seed = in_seed;
            nextSeed = in_nextSeed;
            nextSeedUpdate = timeStamp + 9000; // Seeds are updated every 9 seconds

            DeallocatePacket( packet );
            return 0;
        }
    }

    return packet;
}
Ejemplo n.º 13
0
void PacketLogger::OnInternalPacket(InternalPacket *internalPacket, unsigned frameNumber, PlayerID remoteSystemID, RakNetTime time, bool isSend)
{
	char str[256];
	char sendType[4];
	PlayerID localPlayerId;
	localPlayerId = rakPeer->GetInternalID();

	if (isSend)
		strcpy(sendType, "Snd");
	else
		strcpy(sendType, "Rcv");

	// TODO - put this back in a different form
	/*
	if (internalPacket->isAcknowledgement)
	{
		if (printAcks)
		{
			if (printId==false)
				sprintf(str, "%s,Ack,%5i,%5i,  NIL,    1,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,time,
				localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
			else
				sprintf(str, "%s,Ack,%i,%i,NIL,1,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,time,
				localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
		}
		else
			str[0]=0;
	}
	else
	*/
	{
		if (internalPacket->data[0]==ID_TIMESTAMP && internalPacket->data[sizeof(unsigned char)+sizeof(RakNetTime)]!=ID_RPC)
		{
			if (printId==false)
			{
				sprintf(str, "%s,Tms,%5i,%5i,%5i,%5i,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,
					internalPacket->data[1+sizeof(int)], internalPacket->dataBitLength,time,
					localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
			}
			else
			{
				sprintf(str, "%s,Tms,%i,%i,%s,%i,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,
					IDTOString(internalPacket->data[1+sizeof(int)]), internalPacket->dataBitLength,time,
					localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
			}

		}
		else if (internalPacket->data[0]==ID_RPC || (internalPacket->dataBitLength>(sizeof(unsigned char)+sizeof(RakNetTime))*8 && internalPacket->data[0]==ID_TIMESTAMP && internalPacket->data[sizeof(unsigned char)+sizeof(RakNetTime)]==ID_RPC))
		{
			bool hasTimestamp;
			unsigned int bitsOfData;
			bool nameIsEncoded;
			unsigned char uniqueIdentifier[256];
			RPCIndex rpcIndex;
			RPCMap *rpcMap;
			RakNet::BitStream rpcDecode(internalPacket->data, BITS_TO_BYTES(internalPacket->dataBitLength), false);
			rpcDecode.IgnoreBits(8);
			if (internalPacket->data[0]==ID_TIMESTAMP)
				rpcDecode.IgnoreBits(sizeof(unsigned char)+sizeof(RakNetTime));
			rpcDecode.Read(nameIsEncoded);
			if (nameIsEncoded)
			{
				stringCompressor->DecodeString((char*)uniqueIdentifier, 256, &rpcDecode);
			}
			else
			{
				rpcDecode.ReadCompressed( rpcIndex );
				RPCNode *rpcNode;
				rpcMap = rakPeer->GetRPCMap(isSend==true ? remoteSystemID : UNASSIGNED_PLAYER_ID);
				if (rpcMap)
					rpcNode = rpcMap->GetNodeFromIndex(rpcIndex);
				else
					rpcNode=0;

				if (rpcMap && rpcNode)
					strcpy((char*)uniqueIdentifier, rpcNode->uniqueIdentifier);
				else
					strcpy((char*)uniqueIdentifier, "[UNKNOWN]");
			}
			rpcDecode.Read(hasTimestamp);
			rpcDecode.ReadCompressed(bitsOfData);
			
			if (hasTimestamp)
				sprintf(str, "%s,RpT,%5i,%5i,%s,%5i,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,
				uniqueIdentifier, internalPacket->dataBitLength,time,
				localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
			else
				sprintf(str, "%s,Rpc,%5i,%5i,%s,%5i,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,
				uniqueIdentifier, internalPacket->dataBitLength,time,
				localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
		}
		else
		{
			if (printId==false)
			{
				sprintf(str, "%s,Nrm,%5i,%5i,%5i,%5i,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,
					internalPacket->data[0], internalPacket->dataBitLength,time,
					localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
			}
			else
			{
				sprintf(str, "%s,Nrm,%i,%i,%s,%i,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,
					IDTOString(internalPacket->data[0]), internalPacket->dataBitLength,time,
					localPlayerId.binaryAddress, localPlayerId.port, remoteSystemID.binaryAddress, remoteSystemID.port);
			}
		}
	}

	WriteLog(str);
}
Ejemplo n.º 14
0
/*
 * writeImageBits - writes the bits for the image
 */
static bool writeImageBits( FILE *fp, img_node *node )
{
    WPI_PRES                    pres;
    WPI_PRES                    mempres;
    HDC                         memdc;
    ULONG                       byte_count;
    img_node                    *new_image;
    BITMAPINFO2                 *bmi;
    HBITMAP                     oldbitmap;
    HBITMAP                     inverse_bitmap;
    HBITMAP                     clr_bitmap;
    BYTE                        *buffer;
    bool                        ok;

    ok = true;
    pres = _wpi_getpres( HWND_DESKTOP );
    mempres = _wpi_createcompatiblepres( pres, Instance, &memdc );
    _wpi_releasepres( HWND_DESKTOP, pres );
    for( new_image = node; new_image != NULL; new_image = new_image->nexticon ) {
        bmi = GetAndBitmapInfo(new_image);
        if( bmi == NULL ) {
            ok = false;
            break;
        }
        /*
         * first we write the PM XOR mask (inverse mask) then the PM AND
         * mask (and mask) and then the PM colour mask (xor mask).
         */
        byte_count = BITS_TO_BYTES( new_image->width, new_image->height );
        buffer = MemAlloc( byte_count );

        inverse_bitmap = CreateInverseBitmap( new_image->handbitmap, new_image->hxorbitmap );
        oldbitmap = _wpi_selectobject( mempres, inverse_bitmap );
        GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi );
        fwrite( buffer, sizeof( BYTE ), byte_count, fp );
        _wpi_selectobject( mempres, oldbitmap );
        _wpi_deletebitmap( inverse_bitmap );

        oldbitmap = _wpi_selectobject( mempres, new_image->handbitmap );
        GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi );
        fwrite( buffer, sizeof( BYTE ), byte_count, fp );
        _wpi_selectobject( mempres, oldbitmap );

        MemFree( buffer );
        FreeDIBitmapInfo( bmi );

        bmi = GetXorBitmapInfo( new_image );
        if( bmi == NULL ) {
            ok = false;
            break;
        }
        clr_bitmap = CreateColourBitmap( new_image->handbitmap, new_image->hxorbitmap );
        oldbitmap = _wpi_selectobject( mempres, clr_bitmap );
        byte_count = BITS_TO_BYTES( new_image->width * new_image->bitcount, new_image->height );
        buffer = MemAlloc( byte_count );
        GpiQueryBitmapBits( mempres, 0, node->height, buffer, bmi );
        fwrite( buffer, sizeof( BYTE ), byte_count, fp );
        MemFree( buffer );
        FreeDIBitmapInfo( bmi );
        _wpi_selectobject( mempres, oldbitmap );
        _wpi_deletebitmap( clr_bitmap );
    }
    _wpi_deletecompatiblepres( mempres, memdc );
    return( ok );
} /* writeImageBits */
Ejemplo n.º 15
0
static ssize_t chm_imp_configure  (mphf_t *mphf, request_t *fork_req){ // {{{
	ssize_t                ret;
	backend_t             *t;
	backend_t             *be_g              = NULL;
	backend_t             *be_v              = NULL;
	backend_t             *be_e              = NULL;
	char                  *backend           = NULL;
	uintmax_t              nelements_min     = CAPACITY_MIN_DEFAULT;
	uintmax_t              nelements_step    = CAPACITY_STEP_DEFAULT;
	uintmax_t              nelements_mul     = CAPACITY_MUL_DEFAULT;
	uintmax_t              bi_value          = VALUE_BITS_DEFAULT;
	uintmax_t              readonly          = 0;
	chm_imp_t             *data              = (chm_imp_t *)&mphf->data;
	
	if( (data->status & FILLED) == 0){
		hash_data_copy(ret, TYPE_UINTT,  nelements_min,  mphf->config, HK(nelements_min));
		hash_data_copy(ret, TYPE_UINTT,  nelements_step, mphf->config, HK(nelements_step));
		hash_data_copy(ret, TYPE_UINTT,  nelements_mul,  mphf->config, HK(nelements_mul));
		hash_data_copy(ret, TYPE_UINTT,  bi_value,       mphf->config, HK(value_bits));     // number of bits per value to store
		hash_data_copy(ret, TYPE_UINTT,  readonly,       mphf->config, HK(readonly));       // run in read-only mode
		
		hash_data_copy(ret, TYPE_STRINGT, backend,       mphf->config, HK(backend_g));
		if(ret == 0){
			be_g = t = backend_acquire(backend);
			if(fork_req){
				be_g = backend_fork(t, fork_req);
				backend_destroy(t);
			}
		}
		
		hash_data_copy(ret, TYPE_STRINGT, backend,       mphf->config, HK(backend_v));
		if(ret == 0){
			be_v = t = backend_acquire(backend);
			if(fork_req){
				be_v = backend_fork(t, fork_req);
				backend_destroy(t);
			}
		}
		
		hash_data_copy(ret, TYPE_STRINGT, backend,       mphf->config, HK(backend_e));
		if(ret == 0){
			be_e = t = backend_acquire(backend);
			if(fork_req){
				be_e = backend_fork(t, fork_req);
				backend_destroy(t);
			}
		}
		
		
		if(be_g == NULL)
			return error("backend chm_imp parameter backend_g invalid");
		
		if(be_v == NULL || be_e == NULL || readonly != 0){
			data->status &= ~WRITEABLE;
		}else{
			data->status |= WRITEABLE;
		}
		
		data->be_g           = be_g;
		data->be_v           = be_v;
		data->be_e           = be_e;
		data->nelements_min  = nelements_min;
		data->nelements_step = nelements_step;
		data->nelements_mul  = nelements_mul;
		data->bi_value       = bi_value;
		data->bt_value       = BITS_TO_BYTES(data->bi_value);
		
		data->status        |= FILLED;
	}
	return 0;
} // }}}
Ejemplo n.º 16
0
int GrInternalString0m (int x, int y, const char *s)
{
	ubyte*			fp;
	const char*		textP, * nextRowP, * text_ptr1;
	int				r, mask, i, bits, width, spacing, letter, underline;
	int				skip_lines = 0;
	char				c;
	int				origColor;
	uint				videoOffset, videoOffset1;
	ubyte*			videoBuffer = CCanvas::Current ()->Buffer ();
	int				rowSize = CCanvas::Current ()->RowSize ();
	tFont				font;

if (CCanvas::Current ()->FontColor (0).rgb) {
	CCanvas::Current ()->FontColor (0).rgb = 0;
	CCanvas::Current ()->FontColor (0).index = fontManager.Current ()->ParentBitmap ().Palette ()->ClosestColor (CCanvas::Current ()->FontColor (0).color.red, CCanvas::Current ()->FontColor (0).color.green, CCanvas::Current ()->FontColor (0).color.blue);
	}
if (CCanvas::Current ()->FontColor (1).rgb) {
	CCanvas::Current ()->FontColor (1).rgb = 0;
	CCanvas::Current ()->FontColor (1).index = fontManager.Current ()->ParentBitmap ().Palette ()->ClosestColor (CCanvas::Current ()->FontColor (1).color.red, CCanvas::Current ()->FontColor (1).color.green, CCanvas::Current ()->FontColor (1).color.blue);
	}
origColor = CCanvas::Current ()->FontColor (0).index;//to allow easy reseting to default string color with colored strings -MPM
bits=0;
videoOffset1 = y * rowSize + x;
fontManager.Current ()->GetInfo (font);
nextRowP = s;
CCanvas::Current ()->FontColor (0).rgb = 0;
while (nextRowP != NULL) {
	text_ptr1 = nextRowP;
	nextRowP = NULL;

	if (x==0x8000) {			//centered
		int xx = fontManager.Current ()->GetCenteredX (text_ptr1);
		videoOffset1 = y * rowSize + xx;
		}

	for (r = 0; r < font.height; r++) {
		textP = text_ptr1;
		videoOffset = videoOffset1;
		while ((c = *textP)) {
			if (c == '\n') {
				nextRowP = textP + 1;
				break;
				}
			if (c == CC_COLOR) {
				CCanvas::Current ()->FontColor (0).index = * (++textP);
				textP++;
				continue;
				}
			if (c == CC_LSPACING) {
				skip_lines = * (++textP) - '0';
				textP++;
				continue;
				}
			underline = 0;
			if (c == CC_UNDERLINE) {
				if ((r==font.baseLine+2) || (r==font.baseLine+3))
					underline = 1;
				c = * (++textP);
				}
			fontManager.Current ()->GetCharWidth (c, textP[1], width, spacing);
			letter = c - font.minChar;
			if (c <= 0x06) {	//not in font, draw as space
				textP = ScanEmbeddedColors (c, textP, origColor, 0, 1);
				continue;
				}

			if (!fontManager.Current ()->InFont (letter)) {
				videoOffset += spacing;
				textP++;
				}

			if (font.flags & FT_PROPORTIONAL)
				fp = font.chars[letter];
			else
				fp = font.data + letter * BITS_TO_BYTES (width) * font.height;

			if (underline)
				for (i = 0; i < width; i++)
					videoBuffer [videoOffset++] = (uint) CCanvas::Current ()->FontColor (0).index;
			else {
				fp += BITS_TO_BYTES (width) * r;
				mask = 0;
				for (i = 0; i < width; i++) {
					if (mask == 0) {
						bits = *fp++;
						mask = 0x80;
						}
					if (bits & mask)
						videoBuffer [videoOffset++] = (uint) CCanvas::Current ()->FontColor (0).index;
					else
						videoOffset++;
					mask >>= 1;
					}
				}
			textP++;
			videoOffset += spacing-width;
			}
		videoOffset1 += rowSize;
		y++;
		}
	y += skip_lines;
	videoOffset1 += rowSize * skip_lines;
	skip_lines = 0;
	}
return 0;
}
Ejemplo n.º 17
0
/*
 * IEStretchBlt
 */
BOOL IEStretchBlt( WPI_PRES hdcDest, int nXOriginDest, int nYOriginDest,
                                     int nWidthDest, int nHeightDest,
                   WPI_PRES hdcSrc, int nXOriginSrc, int nYOriginSrc,
                                    int nWidthSrc, int nHeightSrc,
                   DWORD fdwRop, int bitcount )
{
    POINT               slines;
    POINT               dlines;
    POINT               num_strips;
    unsigned long       linesize;
    int                 x, y;
    int                 sw, sh, dw, dh;
    WPI_PRES            srcpres;
    HDC                 srcdc;
    HBITMAP             oldbitmap;
    HBITMAP             newbitmap;

    num_strips.x = nWidthDest / 256;
    num_strips.x++;
#if 0
    if( nWidthDest > 32 ) {
        /* use the version that returns exact bytes needed for bits */
        linesize = BITS_INTO_BYTES( (unsigned long)(nWidthDest * bitcount), 1 );
    } else {
        /* use the version that rounds up to 32 bits */
        linesize = BITS_TO_BYTES( (unsigned long)(nWidthDest * bitcount), 1 );
    }
#else
    /* use the version that rounds up to 32 bits */
    linesize = BITS_TO_BYTES( (unsigned long)(nWidthDest * bitcount), 1 );
#endif
    num_strips.y = ((unsigned long)nHeightDest * linesize) / (16 * 1024);
    num_strips.y++;

    if( num_strips.x > nWidthSrc ) {
        num_strips.x = nWidthSrc;
    } else if( num_strips.x < nWidthSrc ) {
        num_strips.x += num_strips.x % 2;
    }

    if( num_strips.y > nHeightSrc ) {
        num_strips.y = nHeightSrc;
    } else if( num_strips.y < nHeightSrc ) {
        num_strips.y += num_strips.y % 2;
    }

    slines.x = nWidthSrc / num_strips.x;
    dlines.x = ((unsigned long)slines.x * (unsigned long)nWidthDest) /
               (unsigned long)nWidthSrc;

    slines.y = nHeightSrc / num_strips.y;
    dlines.y = ((unsigned long)slines.y * (unsigned long)nHeightDest) /
               (unsigned long)nHeightSrc;

    srcpres = _wpi_createcompatiblepres( hdcDest, Instance, &srcdc );
    newbitmap = _wpi_createcompatiblebitmap( hdcDest, dlines.x, dlines.y );
    oldbitmap = _wpi_selectobject( srcpres, newbitmap );

    sw = slines.x;
    dw = dlines.x;
    for( x = 0; slines.x * x <= nWidthSrc; x++ ) {
        if( slines.x * x + sw > nWidthSrc ) {
            sw = nWidthSrc - x * slines.x;
            dw = nWidthDest - x * dlines.x;
        }
        sh = slines.y;
        dh = dlines.y;
        for( y = 0; slines.y * y <= nHeightSrc; y++ ) {
            if( slines.y * y + sh > nHeightSrc ) {
                sh = nHeightSrc - y * slines.y;
                dh = nHeightDest - y * dlines.y;
            }
            _wpi_stretchblt( srcpres, 0, 0, dw, dh, hdcSrc,
                             nXOriginSrc + slines.x * x, nYOriginSrc + slines.y * y,
                             sw, sh, fdwRop );
            _wpi_bitblt( hdcDest, nXOriginDest + dlines.x * x,
                         nYOriginDest + dlines.y * y, dw, dh, srcpres, 0, 0, SRCCOPY );
        }
    }

    _wpi_selectobject( srcpres, oldbitmap );
    _wpi_deleteobject( newbitmap );
    _wpi_deletecompatiblepres( srcpres, srcdc );

    return( TRUE );

} /* IEStretchBlt */
Ejemplo n.º 18
0
int GrInternalStringClippedM (int x, int y, const char *s)
{
	ubyte * fp;
	const char * textP, * nextRowP, * text_ptr1;
	int r, mask, i, bits, width, spacing, letter, underline;
	int x1 = x, last_x;
	tFont font;

fontManager.Current ()->GetInfo (font);
bits = 0;
nextRowP = s;
CCanvas::Current ()->FontColor (0).rgb = 0;
while (nextRowP != NULL) {
	text_ptr1 = nextRowP;
	nextRowP = NULL;
	x = x1;
	if (x==0x8000)			//centered
		x = fontManager.Current ()->GetCenteredX (text_ptr1);
	last_x = x;
	for (r = 0; r < font.height; r++) {
		x = last_x;
		textP = text_ptr1;
		while (*textP) {
			if (*textP == '\n') {
				nextRowP = &textP[1];
				break;
				}
	
			if (*textP == CC_COLOR) {
				CCanvas::Current ()->FontColor (0).index = * (textP+1);
				textP += 2;
				continue;
				}

			if (*textP == CC_LSPACING) {
				Int3 ();	//	Warning: skip lines not supported for clipped strings.
				textP += 2;
				continue;
				}

			underline = 0;
			if (*textP == CC_UNDERLINE) {
				if ((r == font.baseLine + 2) || (r == font.baseLine + 3))
					underline = 1;
				textP++;
				}
			fontManager.Current ()->GetCharWidth (textP[0], textP[1], width, spacing);
			letter = *textP-font.minChar;
			if (!fontManager.Current ()->InFont (letter)) {	//not in font, draw as space
				x += spacing;
				textP++;
				continue;
				}

			if (font.flags & FT_PROPORTIONAL)
				fp = font.chars[letter];
			else
				fp = font.data + letter * BITS_TO_BYTES (width)*font.height;

			if (underline) {
				for (i = 0; i < width; i++) {
					CCanvas::Current ()->SetColor (CCanvas::Current ()->FontColor (0).index);
					DrawPixelClipped (x++, y);
					}
				}
			else {
				fp += BITS_TO_BYTES (width)*r;
				mask = 0;
				for (i = 0; i< width; i++) {
					if (mask==0) {
						bits = *fp++;
						mask = 0x80;
						}
					if (bits & mask) {
						CCanvas::Current ()->SetColor (CCanvas::Current ()->FontColor (0).index);
						DrawPixelClipped (x++, y);
						} 
					else {
						x++;
						}
					mask >>= 1;
					}
				}
			x += spacing-width;		//for kerning
			textP++;
			}
		y++;
		}
	}
font.parentBitmap.SetBuffer (NULL);	//beware of the destructor!
return 0;
}
Ejemplo n.º 19
0
static HBITMAP WRReadBitmap( BYTE *data, long offset, BOOL core, bitmap_info *info )
{
    DWORD               size;           /* generic size - used repeatedly */
    BYTE _HUGE          *mask_ptr;      /* pointer to bit array in memory */
    HDC                 hdc;
    HPALETTE            new_palette, old_palette;
    BITMAPINFO          *bm_info = NULL;
    BITMAPCOREINFO      *bm_core = NULL;
    HBITMAP             bitmap_handle;
    int                 pos;

    bitmap_handle = (HBITMAP)NULL;

    if( core ) {
        bm_core = WRReadCoreInfo( &data );
        if( bm_core == NULL ) {
            return( bitmap_handle );
        }
        size = BITS_TO_BYTES( bm_core->bmciHeader.bcWidth * bm_core->bmciHeader.bcBitCount,
                              bm_core->bmciHeader.bcHeight );
    } else {
        bm_info = WRReadDIBInfo( &data );
        if( bm_info == NULL ) {
            return( bitmap_handle );
        }
        size = BITS_TO_BYTES( bm_info->bmiHeader.biWidth * bm_info->bmiHeader.biBitCount,
                              bm_info->bmiHeader.biHeight );
    }

    pos = offset;
    mask_ptr = __halloc( size, 1 );
    if( mask_ptr != NULL ) {
        WRReadInPieces( mask_ptr, data, size );
        if( core ) {
            BITMAPCOREHEADER    *h;

            h = &bm_core->bmciHeader;
            /*
             * This will cause a GP Fault!
             */
            bitmap_handle = CreateBitmap( h->bcWidth, h->bcHeight, h->bcPlanes,
                                          h->bcBitCount, mask_ptr );
        } else {
            if( bm_info->bmiHeader.biBitCount < 9 ) {
                /* Bitmap has palette, create it */            
                new_palette = CreateDIBPalette( bm_info );
                if( new_palette != NULL ) {
                    hdc = GetDC( (HWND)NULL );
                    old_palette = SelectPalette( hdc, new_palette, FALSE );
                    RealizePalette( hdc );
                    bitmap_handle = CreateDIBitmap( hdc, &bm_info->bmiHeader, CBM_INIT,
                                                    mask_ptr, bm_info, DIB_RGB_COLORS );
                    SelectPalette( hdc, old_palette, FALSE );
                    DeleteObject( new_palette );
                    ReleaseDC( (HWND)NULL, hdc );
                }
            } else {
                /* Bitmap with no palette*/
                hdc = GetDC( (HWND)NULL );
                bitmap_handle = CreateDIBitmap( hdc, &bm_info->bmiHeader, CBM_INIT,
                                                mask_ptr, bm_info, DIB_RGB_COLORS );
                ReleaseDC( (HWND)NULL, hdc );
            }
        }
        __hfree( mask_ptr );
    }
    if( core ) {
        if( info != NULL ) {
            info->u.bm_core = bm_core;
        } else {
            MemFree( bm_core );
        }
    } else {
        if( info != NULL ) {
            info->u.bm_info = bm_info;
        } else {
            MemFree( bm_info );
        }
    }
    return( bitmap_handle );
}
Ejemplo n.º 20
0
/*
 * expand group->newsrc information if group->xmax is larger than
 * group->newsrc.xmax or min is smaller than group->newsrc.xmin.
 */
void
expand_bitmap(
	struct t_group *group,
	long min)
{
	long bitlen;
	long first;
	long tmp;
	long max;
	t_bool need_full_copy = FALSE;

	/* calculate new max */
	if (group->newsrc.xmax > group->xmax)
		max = group->newsrc.xmax;
	else
		max = group->xmax;

	/* adjust min */
	if (!min)
		min = group->newsrc.xmin;

	/* calculate first */
	if (min >= group->newsrc.xmin)
		first = group->newsrc.xmin;
	else
		first = group->newsrc.xmin - ((group->newsrc.xmin - min + (NBITS - 1)) & ~(NBITS - 1));

	/* adjust first */
	if (first > group->newsrc.xmax + 1)
		first = first - ((first - (group->newsrc.xmax + 1) + (NBITS - 1)) & ~(NBITS - 1));

	/* check first */
	if (first < 1) {
		need_full_copy = TRUE;
		first = 1;
	}

	bitlen = max - first + 1;

	if (bitlen <= 0) {
		bitlen = 0;
		FreeIfNeeded(group->newsrc.xbitmap);
		group->newsrc.xbitmap = (t_bitmap *) 0;
#ifdef DEBUG_NEWSRC
		debug_print_comment("expand_bitmap: group->newsrc.bitlen == 0");
#endif /* DEBUG_NEWSRC */
	} else if (group->newsrc.xbitmap == NULL) {
		group->newsrc.xbitmap = my_malloc(BITS_TO_BYTES(bitlen));
		if (group->newsrc.xmin > first)
			NSETRNG0(group->newsrc.xbitmap, 0L, group->newsrc.xmin - first - 1L);
		if (bitlen > group->newsrc.xmin - first)
			NSETRNG1(group->newsrc.xbitmap, group->newsrc.xmin - first, bitlen - 1);
#ifdef DEBUG_NEWSRC
		debug_print_comment("expand_bitmap: group->newsrc.xbitmap == NULL");
#endif /* DEBUG_NEWSRC */
	} else if (need_full_copy) {
		t_bitmap *newbitmap;
		newbitmap = my_malloc(BITS_TO_BYTES(bitlen));

		/* Copy over old bitmap */
		/* TODO: change to use shift */
		for (tmp = group->newsrc.xmin; tmp <= group->newsrc.xmax; tmp++) {
			if (NTEST(group->newsrc.xbitmap, tmp - group->newsrc.xmin))
				NSET1(newbitmap, tmp - first);
			else
				NSET0(newbitmap, tmp - first);
		}

		/* Mark earlier articles as read, updating num_unread */

		if (first < group->newsrc.xmin) {
			NSETRNG0(newbitmap, 0L, group->newsrc.xmin - first - 1L);
		}
		{
			long i;

			for (i = group->newsrc.xmin; i < min; i++) {
				if (NTEST(newbitmap, i - first) != ART_READ) {
					NSET0(newbitmap, i - first);
					if (group->newsrc.num_unread)
						group->newsrc.num_unread--;
				}
			}
		}

		/* Mark high numbered articles as unread */

		if (group->newsrc.xmin - first + group->newsrc.xbitlen < bitlen) {
			tmp = group->newsrc.xmin - first + group->newsrc.xbitlen;
			NSETRNG1(newbitmap, tmp, bitlen - 1);
		}

		free(group->newsrc.xbitmap);
		group->newsrc.xbitmap = newbitmap;
#ifdef DEBUG_NEWSRC
		debug_print_comment("expand_bitmap: group->newsrc.bitlen != (group->max-group->min)+1 and need full copy");
#endif /* DEBUG_NEWSRC */
	} else if (max != group->newsrc.xmax || first != group->newsrc.xmin) {
		t_bitmap *newbitmap;
		newbitmap = my_malloc(BITS_TO_BYTES(bitlen));

		/* Copy over old bitmap */

		assert((group->newsrc.xmin - first) / NBITS + BITS_TO_BYTES(group->newsrc.xbitlen) <= BITS_TO_BYTES(bitlen));

		memcpy(newbitmap + (group->newsrc.xmin - first) / NBITS, group->newsrc.xbitmap, BITS_TO_BYTES(group->newsrc.xbitlen));

		/* Mark earlier articles as read, updating num_unread */

		if (first < group->newsrc.xmin) {
			NSETRNG0(newbitmap, 0L, group->newsrc.xmin - first - 1L);
		}
		{
			long i;

			for (i = group->newsrc.xmin; i < min; i++) {
				if (NTEST(newbitmap, i - first) != ART_READ) {
					NSET0(newbitmap, i - first);
					if (group->newsrc.num_unread)
						group->newsrc.num_unread--;
				}
			}
		}

		/* Mark high numbered articles as unread */

		if (group->newsrc.xmin - first + group->newsrc.xbitlen < bitlen) {
			tmp = group->newsrc.xmin - first + group->newsrc.xbitlen;
			NSETRNG1(newbitmap, tmp, bitlen - 1);
		}

		free(group->newsrc.xbitmap);
		group->newsrc.xbitmap = newbitmap;
#ifdef DEBUG_NEWSRC
		debug_print_comment("expand_bitmap: group->newsrc.bitlen != (group->max-group->min)+1");
#endif /* DEBUG_NEWSRC */
	}
	group->newsrc.xmin = first;
	if (group->newsrc.xmax < max)
		group->newsrc.num_unread += max - group->newsrc.xmax;
	group->newsrc.xmax = max;
	group->newsrc.xbitlen = bitlen;
	group->newsrc.present = TRUE;
}
Ejemplo n.º 21
0
bool FileListTransfer::DecodeFile(Packet *packet)
{
	unsigned char *decompressedFileData;
	char fileName[512];
	unsigned char context;
	unsigned fileIndex, fileLength, compressedLength;
	unsigned bitLength;
	unsigned len;
	unsigned short setID;
	RakNet::BitStream inBitStream(packet->data, packet->length, false);
	inBitStream.IgnoreBits(8);
	inBitStream.Read(context);
	inBitStream.Read(setID);
	FileListReceiver *fileListReceiver;
	if (fileListReceivers.Has(setID)==false)
	{
#ifdef _DEBUG
		assert(0);
#endif
		return false;
	}
	fileListReceiver=fileListReceivers.Get(setID);
	if (fileListReceiver->allowedSender!=packet->playerId)
	{
#ifdef _DEBUG
		assert(0);
#endif
		return false;
	}

#ifdef _DEBUG
	assert(fileListReceiver->gotSetHeader==true);
#endif
	
	inBitStream.ReadCompressed(fileIndex);
	inBitStream.ReadCompressed(fileLength);
	if (fileListReceiver->isCompressed)
	{
		inBitStream.ReadCompressed(bitLength);
		compressedLength=BITS_TO_BYTES(bitLength);
	}

	if (stringCompressor->DecodeString(fileName, 512, &inBitStream)==false)
	{
#ifdef _DEBUG
		assert(0);
#endif
		return false;
	}

	decompressedFileData = new unsigned char [fileLength];

	if (fileListReceiver->isCompressed)
	{
		len=fileListReceiver->tree.DecodeArray(&inBitStream, bitLength, fileLength, decompressedFileData);
		if (len!=fileLength)
		{
#ifdef _DEBUG
			assert(0);
#endif
			delete [] decompressedFileData;
			return false;
		}
	}
	else
		inBitStream.Read((char*)decompressedFileData, fileLength);

	// User callback for this file.
	fileListReceiver->downloadHandler->OnFile(fileIndex, fileName, (char*)decompressedFileData, compressedLength, fileLength, setID, fileListReceiver->setCount, fileListReceiver->setTotalCompressedTransmissionLength, fileListReceiver->setTotalFinalLength, context);

	delete [] decompressedFileData;

	// If this set is done, free the memory for it.
	if (fileListReceiver->setCount==fileIndex+1)
	{
		if (fileListReceiver->deleteDownloadHandler)
			delete fileListReceiver->downloadHandler;
		delete fileListReceiver;
		fileListReceivers.Delete(setID);
	}

	return true;
}
Ejemplo n.º 22
0
/*
 * Parse the newsrc sequence for the specified group
 */
static void
parse_bitmap_seq(
	struct t_group *group,
	char *seq)
{
	char *ptr;
	int sum = 0;
	long low = 0L;
	long high = 0L;
	long min, max;
	t_bool gotseq = FALSE;

	/*
	 * Skip possible non-numeric prefix
	 */
	ptr = seq;
	while (ptr && *ptr && (*ptr < '0' || *ptr > '9'))
		ptr++;

#ifdef DEBUG_NEWSRC
	{
		char buf[NEWSRC_LINE];
		sprintf(buf, "Parsing [%s%c %.*s]", group->name, SUB_CHAR(group->subscribed), (int) (NEWSRC_LINE - strlen(group->name) - 20), ptr);
		debug_print_comment(buf);
		debug_print_bitmap(group, NULL);
	}
#endif /* DEBUG_NEWSRC */

	if (ptr) {
		gotseq = TRUE;
		ptr = parse_get_seq(ptr, &low, &high);

		if (high < group->xmin - 1)
			high = group->xmin - 1;

		min = ((low <= 1) ? (high + 1) : 1);

		if (group->xmin > min)
			min = group->xmin;

		if (group->xmax > high)
			max = group->xmax;
		else
			max = high;		/* trust newsrc's max */

		FreeAndNull(group->newsrc.xbitmap);
		group->newsrc.xmax = max;
		group->newsrc.xmin = min;
		group->newsrc.xbitlen = (max - min) + 1;
		if (group->newsrc.xbitlen > 0) {
			group->newsrc.xbitmap = my_malloc(BITS_TO_BYTES(group->newsrc.xbitlen));
			NSETRNG1(group->newsrc.xbitmap, 0L, group->newsrc.xbitlen - 1L);
		}

		if (min <= high) {
			if (low > min)
				sum = low - min;
			else
				low = min;
			NSETRNG0(group->newsrc.xbitmap, low - min, high - min);
		}

		/*
		 * Pick up any additional articles/ranges after the first
		 */
		while (*ptr)
			ptr = parse_subseq(group, ptr, &low, &high, &sum);
	} else {
		FreeAndNull(group->newsrc.xbitmap);
		group->newsrc.xmax = group->xmax;
		if (group->xmin > 0)
			group->newsrc.xmin = group->xmin;
		else
			group->newsrc.xmin = 1;
		group->newsrc.xbitlen = (group->newsrc.xmax - group->newsrc.xmin) + 1;
		if (group->newsrc.xbitlen > 0) {
			group->newsrc.xbitmap = my_malloc(BITS_TO_BYTES(group->newsrc.xbitlen));
			NSETRNG1(group->newsrc.xbitmap, 0L, group->newsrc.xbitlen - 1L);
		}
/*
wait_message(2, "BITMAP Grp=[%s] MinMax=[%ld-%ld] Len=[%ld]\n",
	group->name, group->xmin, group->xmax, group->newsrc.xbitlen);
*/
	}

	group->newsrc.present = TRUE;

	if (gotseq) {
		if (group->newsrc.xmax > high)
			sum += group->newsrc.xmax - high;
	} else
		sum = (int) ((group->count >= 0) ? group->count : ((group->newsrc.xmax - group->newsrc.xmin) + 1));

	group->newsrc.num_unread = sum;
#ifdef DEBUG_NEWSRC
	debug_print_bitmap(group, NULL);
#endif /* DEBUG_NEWSRC */
}
Ejemplo n.º 23
0
void write_image_bitmap(int* ret, file_system_info fs_info, image_options img_opt, unsigned long* bitmap, cmd_opt* opt) {

	int i, debug = opt->debug;

	switch(img_opt.bitmap_mode) {

	case BM_BIT:
	{
		if (write_all(ret, (char*)bitmap, BITS_TO_BYTES(fs_info.totalblock), opt) == -1)
			log_mesg(0, 1, 1, debug, "write bitmap to image error: %s\n", strerror(errno));

		break;
	}

	case BM_BYTE:
	{
		char bbuffer[16384];

		for (i = 0; i < fs_info.totalblock; ++i) {

			bbuffer[i % sizeof(bbuffer)] = pc_test_bit(i, bitmap);

			if (i % sizeof(bbuffer) == sizeof(bbuffer) - 1 || i == fs_info.totalblock - 1) {

				if (write_all(ret, bbuffer, 1 + (i % sizeof(bbuffer)), opt) == -1)
					log_mesg(0, 1, 1, debug, "write bitmap to image error: %s\n", strerror(errno));
			}
		}

		break;
	}

	case BM_NONE:
	{
		// All blocks MUST be present
		if (fs_info.usedblocks != fs_info.totalblock)
			log_mesg(0, 1, 1, debug, "ERROR: used blocks count does not match total blocks count\n");
		break;
	}

	default:
		log_mesg(0, 1, 1, debug, "ERROR: unknown bitmap mode [%d]\n", img_opt.bitmap_mode);
		break;
	}

	if (img_opt.bitmap_mode != BM_NONE) {

		switch (img_opt.image_version) {

		case 0x0001:
			if (write_all(ret, BIT_MAGIC, BIT_MAGIC_SIZE, opt) != BIT_MAGIC_SIZE)
				log_mesg(0, 1, 1, debug, "write bitmap to image error: %s\n", strerror(errno));
			break;

		case 0x0002: {

			uint32_t crc;

			init_crc32(&crc);

			crc = crc32(crc, bitmap, BITS_TO_BYTES(fs_info.totalblock));

			if (write_all(ret, (char*)&crc, sizeof(crc), opt) != sizeof(crc))
				log_mesg(0, 1, 1, debug, "write bitmap to image error: %s\n", strerror(errno));

			break;
		}

		default:
			log_mesg(0, 1, 1, debug, "image_version is not set or write_image_bitmap() must to be updated [%d]\n",
				img_opt.image_version);
			break;
		}
	}
}
Ejemplo n.º 24
0
/*
 * Parse a subsection of the newsrc sequencer ie., 1-34,23-90,93,97-99
 * would parse the sequence if called in a loop in the following way:
 *   1st call would parse  1-34 and return 23-90,93,97-99
 *   2nd call would parse 23-90 and return 93,97-99
 *   3rd call would parse    93 and return 97-99
 *   4th call would parse 97-99 and return NULL
 */
static char *
parse_subseq(
	struct t_group *group,
	char *seq,
	long *low,
	long *high,
	int *sum)
{
	long bitmin;
	long bitmax;
	long last_high = *high;

	seq = parse_get_seq(seq, low, high);

	/*
	 * Bitmap index
	 */
	bitmin = *low - group->newsrc.xmin;

	/*
	 * check that seq is not out of order
	 */
	if (*low > last_high)
		*sum += (*low - last_high) - 1;

	if (*high == *low) {
		if (bitmin >= 0) {
			if (*high > group->newsrc.xmax) {
				/* We trust .newsrc's max. */
				long bitlen;
				t_bitmap *newbitmap;

				group->newsrc.xmax = *high;
				bitlen = group->newsrc.xmax - group->newsrc.xmin + 1;
				newbitmap = my_malloc(BITS_TO_BYTES(bitlen));

				/* Copy over old bitmap */
				memcpy(newbitmap, group->newsrc.xbitmap, BITS_TO_BYTES(group->newsrc.xbitlen));

				/* Mark high numbered articles as unread */
				NSETRNG1(newbitmap, group->newsrc.xbitlen, bitlen - 1);

				free(group->newsrc.xbitmap);
				group->newsrc.xbitmap = newbitmap;
				group->newsrc.xbitlen = bitlen;
			}
			NSET0(group->newsrc.xbitmap, bitmin);
		}
	} else if ((*low < *high) && (*high >= group->newsrc.xmin)) {
		/*
		 * Restrict the range to min..max
		 */
		if (bitmin < 0)
			bitmin = 0;

		bitmax = *high;

		if (bitmax > group->newsrc.xmax) {
			/* We trust .newsrc's max. */
			long bitlen;
			t_bitmap *newbitmap;

			group->newsrc.xmax = bitmax;
			bitlen = group->newsrc.xmax - group->newsrc.xmin + 1;
			newbitmap = my_malloc(BITS_TO_BYTES(bitlen));

			/* Copy over old bitmap */
			memcpy(newbitmap, group->newsrc.xbitmap, BITS_TO_BYTES(group->newsrc.xbitlen));

			/* Mark high numbered articles as unread */
			NSETRNG1(newbitmap, group->newsrc.xbitlen, bitlen - 1);

			free(group->newsrc.xbitmap);
			group->newsrc.xbitmap = newbitmap;
			group->newsrc.xbitlen = bitlen;
		}

		bitmax -= group->newsrc.xmin;

		/*
		 * Fill in the whole range as read
		 */
		NSETRNG0(group->newsrc.xbitmap, bitmin, bitmax);
	}
	return seq;
}
Ejemplo n.º 25
0
/* This functions codes all ixeme occurrences in a segment in the correct 
 * order. The catch is that instead of using global ixeme IDs, we use a
 * minimal local set of IDs, namely integers [1..|S|] for |S| individual
 * ixemes. Mapping between the IDs is implictely saved in the ascending 
 * order of ixeme IDs, obtainable from the forward index. */
void possect_add(const Pvoid_t tokens)
{
        static uint *offsets;
        //static uint offsets_len;
        static char *encode_buf;
        //static uint buf_len;
        
        if (!offsets){
                offsets = xmalloc(segment_size * sizeof(uint));
                encode_buf = xmalloc(segment_size * 8);
                memset(encode_buf, 0, segment_size * 8);
        }
        memset(offsets, 0, segment_size * sizeof(uint));

        //ENSURE_IBLOCK
        
        Word_t max = 0;
        JLC(max, tokens, 0, -1);

        /* write TOC entry */
        toc_e toc;
        toc.offs = ftello64(data_f);
        toc.val = max;
        fwrite(&toc, sizeof(toc_e), 1, toc_f);
        
        /* write token list */
        uint max_pos = encode_tokens(tokens);
        
        /*
        if (segment_size > offsets_len){
                free(offsets);
                offsets_len = segment_size;
                offsets = xmalloc(offsets_len * sizeof(uint));
        }
        memset(offsets, 0, offsets_len * sizeof(uint));
        */

        /* estimate rice_f */
        u32 rice_f, offs = 0;
        if (max)
                rice_f = estimate_rice_f((u32*)&max, 1);
        else
                rice_f = 2;

        /* allocate bits to positions */
        Word_t *ptr;
        //uint max_pos = 0;
        int i, j, c = 0;
        Word_t xid = 0; 
        JLF(ptr, tokens, xid);
        while (ptr){
                offs = 0;
                rice_write(NULL, &offs, ++c, rice_f);

                const growing_glist *g = (const growing_glist*)*ptr;
                for (i = 0; i < g->lst.len; i++){
                        offsets[g->lst.lst[i] - 1] = offs;
                        if (g->lst.lst[i] > max_pos)
                                max_pos = g->lst.lst[i];
                }

                JLN(ptr, tokens, xid);
        }
        
        /* compute bit offset for each position */
        offs = 0;
        elias_gamma_write(NULL, &offs, max_pos + 1);
        rice_write(NULL, &offs, rice_f, 2);
        for (i = 0; i < max_pos; i++){
                uint tmp = offsets[i];
                if (!tmp)
                        dub_die("A hole in poslist at %u / %u!", i, max_pos);
                offsets[i] = offs;
                offs += tmp;
        }
        u32 endpos = offs;
        
        //u32 total_bits = offs;
        //elias_gamma_write(NULL, &offs, total_bits);
        //rice_write(NULL, &offs, 0, rice_f);

        u32 total_bytes = BITS_TO_BYTES(offs);
        if (total_bytes > segment_size * 8)
                dub_die("Pos buffer too small! %u > %u.",
                        total_bytes, segment_size * 8);
        /* 
        if (total_bytes > buf_len){
                free(encode_buf);
                buf_len = total_bytes;
                encode_buf = xmalloc(buf_len + 4);
                memset(encode_buf, 0, buf_len + 4);
        }
        */

        /* write codes */

        offs  = 0;
        elias_gamma_write(encode_buf, &offs, max_pos + 1);
        rice_write(encode_buf, &offs, rice_f, 2);
        //elias_gamma_write(encode_buf, &offs, total_bits);

        xid = c = j = 0; 
        JLF(ptr, tokens, xid);
        while (ptr){
                ++c;
                growing_glist *g = (growing_glist*)*ptr;
                for (i = 0; i < g->lst.len; i++){
                        //u32 d = offsets[g->lst.lst[i] - 1];
                        //dub_msg("OFFS %u VAL %u", d, c);
                        rice_write(encode_buf, 
                                &offsets[g->lst.lst[i] - 1], c, rice_f);
                        //u32 dd = rice_read(encode_buf, &d, rice_f);
                        //if (c != dd) 
                        //        dub_die("POKS! %u, %u != %u", key, dd, c);
                        ++j;
                }
                free(g);
                JLN(ptr, tokens, xid);
        }
        
        //rice_write(encode_buf, &endpos, 0, rice_f);
        fwrite(encode_buf, total_bytes, 1, data_f);
        memset(encode_buf, 0, total_bytes);
}
Ejemplo n.º 26
0
int main(int argc, char *argv[]) {
	if(argc != 2) {
		printf("Usage: xsvfplayer <filename>\n");
		return 1;
	}
	
	if(NULL == (file = fopen(argv[1], "r"))) {
		printf("Cannot open file.\n");
		return 1;
	}
	fseek(file, 0, SEEK_END);
	filesize = ftell(file);
	rewind(file);
	
	if(NULL == (xsvfprog = xsvfprog_open())) {
		printf("Cannot connect to XSVF player.\n");
		return 1;
	}
	if(SUCCESS != xsvfprog_init(xsvfprog)) {
		printf("Initialization of XSVF player failed.\n");
		xsvfprog_prgend(xsvfprog);
		return 1;
	}

#ifdef DEBUG
	debugfile = fopen("debug.xsvf", "w");
#endif
	printf("Programming...");
	while(!feof(file) && !quit) {
		bufsize = 0;
		/* get command */
		file2buf(1);
#ifdef DEBUG
		printf("instr 0x%02x: ", buf[0]);
#endif
		/* read additional command parameters */
		switch(buf[0]) {
		
		case XCOMPLETE:
			/* quit if XCOMPLETE command reached */
			quit = 1;
			break;
		
		case XREPEAT:
		case XSTATE:
		case XENDIR:
		case XENDDR:
			/* these commands need one additional byte */
			file2buf(1);
#ifdef DEBUG
			printf("par = %d, ", buf[1]);
#endif
			break;
		
		case XRUNTEST:
			/* this command needs four additional bytes */
			file2buf(4);
#ifdef DEBUG
			printf("delay = %d us, ", ntohl(*((long*) &buf[1])));
#endif
			break;
		
		case XTDOMASK:
		case XSDR:
		case XSDRB:
		case XSDRC:
		case XSDRE:
			/* these commands need drSize additional bits */
			file2buf(BITS_TO_BYTES(drSize));
			break;
		
		case XSDRTDO:
		case XSDRTDOB:
		case XSDRTDOC:
		case XSDRTDOE:
			/* these commands need 2x drSize additional bits */
			file2buf(2 * BITS_TO_BYTES(drSize));
			break;
		
		case XSDRSIZE:
			file2buf(4);
			drSize = ntohl(*((long*) &buf[1]));
#ifdef DEBUG
			printf("drSize = %d, ", drSize);
#endif
			if (BITS_TO_BYTES(drSize) > MAX_BITVEC_BYTES) {
				exit_err("\nData Register too long.\n");
			}
			break;
		
		case XSIR:
			file2buf(1);
			irSize = *((unsigned char*) &buf[1]);
#ifdef DEBUG
			printf("irSize = %d, ", irSize);
#endif
			if (BITS_TO_BYTES(irSize) > MAX_BITVEC_BYTES) {
				exit_err("\nInstruction Register too long.\n");
			}
			file2buf(BITS_TO_BYTES(irSize));
			break;
		
		case XSIR2:
			file2buf(2);
			irSize = ntohs(*((short*) &buf[1]));
#ifdef DEBUG
			printf("irSize = %d, ", irSize);
#endif
			if (BITS_TO_BYTES(irSize) > MAX_BITVEC_BYTES) {
				exit_err("\nInstruction Register too long.\n");
			}
			file2buf(BITS_TO_BYTES(irSize));
			break;
		
		case XSETSDRMASKS:
			file2buf(2 * BITS_TO_BYTES(drSize));
			drSize2 = BitStringOnes(drSize, &buf[1 + BITS_TO_BYTES(drSize)]);
#ifdef DEBUG
			printf("drSize2 = %d, ", drSize2);
#endif
			if (BITS_TO_BYTES(drSize2) > MAX_BITVEC_BYTES) {
				exit_err("\nData Register2 too long.\n");
			}
			break;
		
		case XSDRINC:
			file2buf(BITS_TO_BYTES(drSize) + 1);
			int num = *((unsigned char*) &buf[1 + BITS_TO_BYTES(drSize)]);
			file2buf(num * BITS_TO_BYTES(drSize2));
			break;
		
		case XCOMMENT:
			do {
				ch = fgetc(file);
			} while(ch != 0 && ch != EOF);
			/* we don't send comments to the programmer... */
			continue;
			break;
		
		default:
			exit_err("\nIllegal XSVF command.\n");
			break;
		
		}
		
#ifdef DEBUG
		printf("%d bytes long\n", bufsize);
		fwrite(buf, 1, bufsize, debugfile);
#endif
		
		ret = xsvfprog_exec(xsvfprog, buf, bufsize);
#ifdef DEBUG
		printf("%d\n", ret);
#endif

		switch(ret) {
		
		case 0:
			/* success, do nothing, just go on */
			break;
		
		case UNKNOWN_COMMAND:
			exit_err("\nProgramming error: Unknown command.\n");
			break;
		
		case XE_TDOMISMATCH:
			exit_err("\nProgramming error: Captured TDO value differs from expected TDO value.\n");
			break;
		
		case XE_ILLEGALCMD:
			exit_err("\nProgramming error: Illegal XSVF command.\n");
			break;
		
		case XE_ILLEGALSTATE:
			exit_err("\nProgramming error: Illegal TAP state.\n");
			break;
		
		case XE_DATAOVERFLOW:
			exit_err("\nProgramming error: Bit string overflow.\n");
			break;
		
		case XE_DATAUNDERFLOW:
			exit_err("\nProgramming error: End of command buffer reached expecting more data.\n");
			break;
		
		default:
			exit_err("\nUnknown programming error.\n");
			break;
		
		}

		filepos += bufsize;
		printf("\rProgramming... %3u%%", 100*filepos/filesize);
		fflush(stdout);
	}
	xsvfprog_prgend(xsvfprog);
	printf("\nDone.\n");
	
	fclose(file);
#ifdef DEBUG
	fclose(debugfile);
#endif
	xsvfprog_close(xsvfprog);
}