2011-09-25 76 views
0

我试图实现这个RFC 4.1。整数C整数到缓冲区RFC 4506

一个XDR有符号整数是一个32位数据,编码整数 范围[-2147483648,2147483647]。整数用 表示补码表示法。最高和最低有效字节分别为 0和3。整数声明如下:

 int identifier; 

     (MSB)     (LSB) 
    +-------+-------+-------+-------+ 
    |byte 0 |byte 1 |byte 2 |byte 3 |      INTEGER 
    +-------+-------+-------+-------+ 
    <------------32 bits------------> 

这是我的代码我需要知道是否有更好的方法来做到这一点?

void packInteger(char *buf,long int i) 
{ 
    if(i>=0) { 
     *buf++ = i>>24; 
     *buf++ = i>>16; 
     *buf++ = i>>8; 
     *buf++ = i; 
    } 
    if(i<0) { 
     i = i*-1; 
     i = 1 + (unsigned int)(0xffffffffu - i); 
     buf[0] = (unsigned int)i>>24; 
     buf[1] = (unsigned int)i>>16; 
     buf[2] = (unsigned int)i>>8; 
     buf[3] = (unsigned int)i; 
    } 
} 
long int unpackInteger(char *buf) 
{ 
    unsigned long int i2 = ((unsigned long int)buf[0]<<24) | 
          ((unsigned long int)buf[1]<<16) | 
          ((unsigned long int)buf[2]<<8) | 
          buf[3]; 
    long int i; 
    // change unsigned numbers to signed 
    if (i2 <= 0x7fffffffu) { i = i2; } 
    else { i = -1 - (long int)(0xffffffffu - i2); } 
    return i; 
} 
int main(void) 
{ 
    char buf[4]; 
    packInteger(buf,-31); 
    printf("%u %u %u %u\n",buf[0],buf[1],buf[2],buf[3]); 
    long int n = unpackInteger(buf); 
    printf("%ld",n); 
    return 0; 
} 

如果有人在64位系统上工作或没有T?

版本2

void packInteger(unsigned char *buf,long int i) 
{ 
unsigned long int j = i; // this will convert to 2's complement 
*buf++ = i>>24; 
*buf++ = i>>16; 
*buf++ = i>>8; 
*buf++ = i; 
} 
+0

你可以编辑你的问题。所以你可以把你的评论带入问题。 – Mysticial

+0

你不能使用'htonl'和'ntohl'功能吗?另外:http://stackoverflow.com/questions/105252/how-do-i-convert-between-big-endian-and-little-endian-values-in-c – Mat

+0

@Mat我需要手动这样做。 – cap10ibrahim

回答

2

您应该使用unsigned char您的缓冲区。

强制转换为unsigned用C进行转换,以二进制补码的数学相等的,所以你的背包功能,可以简化为:

void packInteger(unsigned char *buf, long int i) 
{ 
    unsigned long u = i; 

    buf[0] = (u >> 24) & 0xffUL; 
    buf[1] = (u >> 16) & 0xffUL; 
    buf[2] = (u >> 8) & 0xffUL; 
    buf[3] = u & 0xffUL; 
} 

你的解压功能似乎罚款(与变化unsigned char)。

+0

常数不需要是UL,除非你自己移动常量。当通过“通常的算术转换”将操作数赋给'&'时,它们将被提升为'unsigned long'。 –

+0

@DietrichEpp:不错 - 我不是故意暗示这是一个正确的问题,所以我删除了该文本。 – caf

+0

@DietrichEpp感谢您的铸造提示,但为什么&0xfful 检查我的新功能 我会将它添加到原始帖子 – cap10ibrahim