簡體   English   中英

字節級別長度描述

[英]Byte level length description

我有一個協議,需要一個長度為32位的字段,並且必須在運行時生成它來描述給定數據包中有多少字節。

下面的代碼有點難看,但我想知道這是否可以重構為更高效或易於理解。 問題是代碼只會生成足夠的字節來描述數據包的長度,所以小於255個字節= 1個字節的長度,小於65535 = 2個字節的長度等...

{
    extern char byte_stream[];
    int bytes = offset_in_packet;
    int n = length_of_packet;
   /* Under 4 billion, so this can be represented in 32 bits. */
    int t;
   /* 32-bit number used for temporary storage. */

    /* These are the bytes we will break up n into. */
    unsigned char first, second, third, fourth;

    t = n & 0xFF000000;
    /* We have used AND to "mask out" the first byte of the number. */
    /* The only bits which can be on in t are the first 8 bits. */
    first = t >> 24;
    if (t)  {
        printf("byte 1: 0x%02x\n",first );
        byte_stream[bytes] = first; bytes++;
        write_zeros = 1;
    }
    /* Now we shift t so that it is between 0 and 255. This is the first, highest byte of n. */
    t = n & 0x00FF0000;
    second = t >> 16;
    if (t || write_zeros) {
        printf("byte 2: 0x%02x\n", second );
        byte_stream[bytes] = second; bytes++;
        write_zeros = 1;
    }

    t = n & 0x0000FF00;
    third = t >> 8;
    if ( t || write_zeros) {
        printf("byte 3: 0x%02x\n", third );
        byte_stream[bytes] = third; bytes++;
        write_zeros = 1;
    }

    t = n & 0x000000FF;
    fourth = t;
    if (t || write_zeros) {
        printf("byte 4: 0x%02x\n", fourth);
        byte_stream[bytes] = fourth; bytes++;
    }
}

你應該為你的長度使用固定寬度的字段。

  • 當接收端的程序必須讀取數據包的長度字段時,它如何知道長度停止的位置?
  • 如果數據包的長度可能達到4 GB,那么1-3字節的開銷真的很重要嗎?
  • 你看到你的代碼已經變得多么復雜了嗎?

試試這個循環:

{
    extern char byte_stream[];
    int bytes = offset_in_packet;
    int n = length_of_packet; /* Under 4 billion, so this can be represented in 32 bits. */
    int t; /* 32-bit number used for temporary storage. */
    int i;

    unsigned char curByte;

    for (i = 0; i < 4; i++) {
        t = n & (0xFF000000 >> (i * 16));

        curByte = t >> (24 - (i * 8));
        if (t || write_zeros)  {
            printf("byte %d: 0x%02x\n", i, curByte );
            byte_stream[bytes] = curByte;
                            bytes++;
            write_zeros = 1;
        }

    }

}

我不確定我理解你的問題。 你到底在想什么? 如果我理解正確,你試圖找到最重要的非零字節。
你可能最好使用這樣的循環:

int i;  
int write_zeros = 0;  
for (i = 3; i >=0 ; --i) {  
    t = (n >> (8 * i)) & 0xff;  
    if (t || write_zeros) {  
        write_zeros = 1;  
        printf ("byte %d : 0x%02x\n", 4-i, t);  
        byte_stream[bytes++] = t;
    }  
}

實際上你只做了四次計算,所以可讀性似乎比效率更重要 我使這樣的東西更具可讀性的方法是

  1. 將常用代碼提取到函數中
  2. 將類似的計算放在一起,使模式更加明顯
  3. 擺脫中間變量print_zeroes並明確表示輸出字節的情況,即使它們為零(即前一個字節非零)

我已將隨機代碼塊更改為函數並更改了一些變量(下划線在markdown預覽屏幕中給我帶來麻煩)。 我還假設正在傳入字節 ,並且傳遞它的人將向我們傳遞一個指針,以便我們可以修改它。

這是代碼:

/* append byte b to stream, increment index */
/* really needs to check length of stream before appending */
void output( int i, unsigned char b, char stream[], int *index )
{
    printf("byte %d: 0x%02x\n", i, b);
    stream[(*index)++] = b;
}


void answer( char bytestream[], unsigned int *bytes, unsigned int n)
{
    /* mask out four bytes from word n */
    first  = (n & 0xFF000000) >> 24;
    second = (n & 0x00FF0000) >> 16;
    third  = (n & 0x0000FF00) >>  8;
    fourth = (n & 0x000000FF) >>  0;

    /* conditionally output each byte starting with the */
    /* first non-zero byte */
    if (first) 
       output( 1, first, bytestream, bytes);

    if (first || second) 
       output( 2, second, bytestream, bytes);

    if (first || second || third) 
       output( 3, third, bytestream, bytes);

    if (first || second || third || fourth) 
       output( 4, fourth, bytestream, bytes);
 }

如此高效一點, 也許更容易理解的是對最后四個if語句的修改:

    if (n>0x00FFFFFF) 
       output( 1, first, bytestream, bytes);

    if (n>0x0000FFFF) 
       output( 2, second, bytestream, bytes);

    if (n>0x000000FF)  
       output( 3, third, bytestream, bytes);

    if (1) 
       output( 4, fourth, bytestream, bytes);

但是,我同意壓縮此字段會使接收狀態機過於復雜。 但是,如果您無法更改協議,則此代碼更易於閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM