PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C nach Java kompilieren



thechef
28-01-2008, 04:42
Ich bin gerade daran dieses Stückchen Code nach Java zu portieren, stell mich aber nicht ganz richtig dabei an, sodass die Java-Version des folgenden Codes nicht richtig funktioniert, nämlich ist die Dekomprimierung um ein Byte falsch bei einem Testdatensatz von 16 Byte.

Ich will aber eigentlich unbedingt Debugging & Testing vermeiden und gar nicht nach Fehlern suchen, sondern diese Stück Code, wenn möglich maschinell (zur effizienten Vermeidung von Fehlern) portieren.

Gibt es C zu Java Compiler, die mit dem Code unten umgehen können?
(unsigned char, expliziter pointerzugriff und so Zeugs)


(Ich suche keine C zu bytecode compiler und auch kein JNI)

C


#include <seom/codec.h>

/**
* Based on quicklz (http://www.quicklz.com)
*
* Copyright 2006, Lasse Reinhold (lar@quicklz.com)
*/

#define min(v0,v1) ( (v0) < (v1) ? (v0) : (v1) )
#define u8(ptr) ( *(uint8_t *) (ptr) )
#define u32(ptr) ( *(uint32_t *) (ptr) )

static void __memcpy(void *dst, const void *src, unsigned long len)
{
if (src + len > dst) {
const void *end = dst + len;
while (dst < end)
*(char *)dst++ = *(char *)src++;
} else {
memcpy(dst, src, len);
}
}


void *seomCodecDecode(void *dst, const void *src, unsigned long size)
{
const void *end = dst + size;
unsigned char counter = 8;
uint8_t cbyte = u8(src++);

while (dst < end - 4) {
if (counter == 0) { /* fetch control byte */
cbyte = u8(src++);
counter = 8;
}

if (cbyte & (1 << 7)) { /* LZ match or RLE sequence */
cbyte = (cbyte << 1) | 1;
--counter;
if ((u8(src) & 0x80) == 0) { /* 7bits offset */
unsigned long offset = u8(src);
__memcpy(dst, dst - offset, 3);
dst += 3;
src += 1;
} else if ((u8(src) & 0x60) == 0) { /* 13bits offset */
unsigned long offset = ((u8(src) & 0x1f) << 8) | u8(src + 1);
__memcpy(dst, dst - offset, 3);
dst += 3;
src += 2;
} else if ((u8(src) & 0x40) == 0) { /* 10bits offset, 3bits length */
unsigned long len = ((u8(src) >> 2) & 7) + 4;
unsigned long offset = ((u8(src) & 0x03) << 8) | u8(src + 1);
__memcpy(dst, dst - offset, len);
dst += len;
src += 2;
} else if ((u8(src) & 0x20) == 0) { /* 16bits offset, 5bits length */
unsigned long len = (u8(src) & 0x1f) + 4;
unsigned long offset = (u8(src + 1) << 8) | u8(src + 2);
__memcpy(dst, dst - offset, len);
dst += len;
src += 3;
} else if ((u8(src) & 0x10) == 0) { /* 17bits offset, 11bits length */
unsigned long len = (((u8(src) & 0x0f) << 7) | (u8(src + 1) >> 1)) + 4;
unsigned long offset = ((u8(src + 1) & 0x01) << 16) | (u8(src + 2) << 8) | (u8(src + 3));
__memcpy(dst, dst - offset, len);
dst += len;
src += 4;
} else { /* RLE sequence */
unsigned long len = (((u8(src) & 0x0f) << 8) | u8(src + 1)) + 5;
memset(dst, u8(src + 2), len);
dst += len;
src += 3;
}
} else { /* literal */
static const uint8_t map[8][2] = { { 4, 0x0f }, { 3, 0x07 }, { 2, 0x03 }, { 2, 0x03 }, { 1, 0x01 }, { 1, 0x01 }, { 1, 0x01 }, { 1, 0x01 } };
unsigned char index = cbyte >> 4;
memcpy(dst, src, map[index][0]);
dst += map[index][0];
src += map[index][0];
counter -= map[index][0];
cbyte = (cbyte << map[index][0]) | map[index][1];
}
}

while (dst < end) {
if (counter == 0) {
counter = 8;
++src;
}
u8(dst++) = u8(src++);
--counter;
}

return dst;
}


Java


package yukon.factory;

import yukon.RawCompressedPacket;
import yukon.RawUncompressedPacket;

public class UncompressedPacketFactory {


public static RawUncompressedPacket createPacket(RawCompressedPacket rawpacket)
{

byte[] unCompressedBytes = new byte[(int)rawpacket.getDecompressedSize()];
System.out.println(testing.testing.byteArrayToStri ng(rawpacket.getBuffer()));
seomCodecDecode(unCompressedBytes,rawpacket.getBuf fer(),rawpacket.getDecompressedSize());
System.out.println(testing.testing.byteArrayToStri ng(unCompressedBytes));
RawUncompressedPacket uncompressedPacket=new RawUncompressedPacket();
uncompressedPacket.setBuffer(unCompressedBytes);
uncompressedPacket.setCompressedSize(rawpacket.get CompressedSize());
uncompressedPacket.setDecompressedSize(rawpacket.g etDecompressedSize());
uncompressedPacket.setTime(rawpacket.getTime());
uncompressedPacket.setType(rawpacket.getType());
return uncompressedPacket;
}




private static void memcpy(byte[] dst, byte src[], int offset, int length)
{
System.out.println(testing.testing.byteArrayToStri ng(dst));
if (src == dst && offset == 0){return;}
for (int i = 0;i<length;i++)
{
dst[i]=src[i+offset];
}
System.out.println(testing.testing.byteArrayToStri ng(dst));
}

private static void memcpy(byte[] dst, byte src[], int dstoffset, int srcoffset, int length)
{
System.out.println(testing.testing.byteArrayToStri ng(dst));
for (int i = 0;i<length;i++)
{
dst[i+dstoffset]=src[i+srcoffset];
}
System.out.println(testing.testing.byteArrayToStri ng(dst));
}
private static void memset(byte[] dst, int offset, byte value, int len)
{
System.out.println(testing.testing.byteArrayToStri ng(dst));
for (int i = 0;i<len;i++)
{
dst[offset+i]=value;
}
System.out.println(testing.testing.byteArrayToStri ng(dst));
}


private static byte[] seomCodecDecode(byte[] dst, byte[] src, long size)
{
//const void *end = dst + size;
char counter = 8;
int dstindex=0;
int srcindex=0;
int cbyte = unsignByte(src[srcindex++]);

while (dstindex < size - 4) {
if (counter == 0) { /* fetch control byte */
cbyte = unsignByte(src[srcindex++]);
//System.out.println("cbyte-60: " + cbyte);
counter = 8;
}

if ((cbyte & (1 << 7)) != 0) { /* LZ match or RLE sequence */
cbyte = unsignByte((byte)((cbyte << 1) | 1));
//System.out.println("cbyte-66: " + cbyte);
--counter;
if ((src[srcindex] & 0x80) == 0) { /* 7bits offset */
System.out.println("Line 72: " + src[srcindex] + " indexes " + srcindex + " " + dstindex);
int offset = unsignByte(src[srcindex]);
memcpy(dst, dst,dstindex - offset, 3); //here we are
dstindex += 3;
srcindex += 1;
} else if ((unsignByte(src[srcindex]) & 0x60) == 0) { /* 13bits offset */
System.out.println("Line 77: " + src[srcindex] + " indexes " + srcindex + " " + dstindex);
int offset = ((unsignByte(src[srcindex]) & 0x1f) << 8) | unsignByte(src[srcindex + 1]);
memcpy(dst, dst,dstindex - offset, 3);
dstindex += 3;
srcindex += 2;
} else if ((unsignByte(src[srcindex]) & 0x40) == 0) { /* 10bits offset, 3bits length */
System.out.println("Line 82: " + src[srcindex] + " indexes " + srcindex + " " + dstindex);
int len = ((unsignByte(src[srcindex]) >>> 2) & 7) + 4;
int offset = ((unsignByte(src[srcindex]) & 0x03) << 8) | unsignByte(src[srcindex + 1]);
memcpy(dst,dst,dstindex - offset, len);
dstindex += len;
srcindex += 2;
} else if ((unsignByte(src[srcindex]) & 0x20) == 0) { /* 16bits offset, 5bits length */
System.out.println("Line 88: " + src[srcindex] + " " + src[srcindex+1] + " " + src[srcindex+2]+" indexes " + srcindex + " " + dstindex);
int len = (unsignByte(src[srcindex]) & 0x1f) + 4;
int offset = (unsignByte(src[srcindex+1]) << 8) | unsignByte(src[srcindex+2]);
memcpy(dst, dst,dstindex - offset, len);
dstindex += len;
srcindex += 3;
} else if ((unsignByte(src[srcindex]) & 0x10) == 0) { /* 17bits offset, 11bits length */
System.out.println("Line 94: " + src[srcindex] + " " + src[srcindex+1] + " " + src[srcindex+2]+" indexes " + srcindex + " " + dstindex);
int len = (((unsignByte(src[srcindex]) & 0x0f) << 7) | (unsignByte(src[srcindex+1]) >>> 1)) + 4;
int offset = ((unsignByte(src[srcindex+1]) & 0x01) << 16) | (unsignByte(src[srcindex+2]) << 8) | (unsignByte(src[srcindex+3]));
//System.out.println("memcpy(dst,dst," + dstindex + " - " + offset + ", " + len + ");");
memcpy(dst,dst,dstindex - offset, len);
dstindex += len;
srcindex += 4;
} else { /* RLE sequence */
System.out.println("Line 106: " + src[srcindex] + " " + src[srcindex+1] + " " + src[srcindex+2]+" indexes " + srcindex + " " + dstindex);
int len = (((unsignByte(src[srcindex]) & 0x0f) << 8) | unsignByte(src[srcindex+1])) + 5;
memset(dst,dstindex, src[srcindex+2], len);
dstindex += len;
srcindex += 3;
//System.out.println("105-" + srcindex + " " + dstindex);
}
} else { /* literal */
byte[][] map = { { 4, 0x0f }, { 3, 0x07 }, { 2, 0x03 }, { 2, 0x03 }, { 1, 0x01 }, { 1, 0x01 }, { 1, 0x01 }, { 1, 0x01 } };
//System.out.println("cbyte: " + cbyte + " unsigned: " + unsignByte(cbyte));
int index = unsignByte(cbyte) >>> 4;
//System.out.println("index: " + index);
System.out.println("Line 118: indexes " + srcindex + " " + dstindex);
memcpy(dst, src, dstindex, srcindex,unsignByte(map[index][0]));
dstindex += unsignByte(map[index][0]);
srcindex += unsignByte(map[index][0]);
//System.out.println("114-" + srcindex);
counter -= unsignByte(map[index][0]);
cbyte = unsignByte((byte)((cbyte << unsignByte(map[index][0])) | unsignByte(map[index][1])));
//System.out.println("cbyte-112: " + cbyte);
}
}

while (dstindex < size) {
if (counter == 0) {
counter = 8;
++srcindex;
}
dst[dstindex++] = src[srcindex++];
//System.out.println("126-" + srcindex);
--counter;
}

return dst;
}

private static int unsignByte(int sign)
{
int toReturn = sign;
if (toReturn<0){toReturn+=256;}
return toReturn;
}
}


äh naja, mittlerweile hab ich das Problem gelöst - Programmierfehler beim benutzen dieser memcpy hilfs-methode.

panzi
02-02-2008, 18:26
Statt dir so eine memcopy Methode ineffizienter Weise selber zu schreiben verwende doch System.arraycopy (http://java.sun.com/javase/6/docs/api/java/lang/System.html#arraycopy(java.lang.Object,%20int,%20j ava.lang.Object,%20int,%20int)).
Und statt memset kannst du Arrays.fill (http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#fill(byte%5b%5d,%20int,%20int,%20byte) ) verwenden. Sollte auch effizient implementiert sein.