Search code examples
clinuxcastinguint8t

uint16_t uint8_t or size_t?


I would like to use a function which is charged to send both "data size" and "data" to a specific file descriptor by using write(). It works when the record length is equal to 2 bytes. However, I would like to use the same function to send also record length equal to 1 byte.

send_func(int port)
{
    void *fd;
    uint64_t fsize = 2517283;
    uint64_t nbrBytes = 0;  
    uint16_t rsize;
    int count;
    ssize_t ret;
    uint8_t Bsent = 0;

    for (count = 1; nbrBytes < fsize; count++) 
    {
        rsize = ((uint8_t*)fp)[nbrBytes];
        rsize += ((((uint8_t*)fp)[nbrBytes + 1]) << 8) & 0xFF00;
        nbrBytes += 2;

        // send size
        ret = write(port, rsize, 2);
        if (ret != 2) {
            return -1;
        }
        // send data
        ret = write(port, ((unsigned char*)fp) + Bsent, rsize - Bsent);
        if (ret < 0) {
            return -1;
        }
        Bsent += ret;
    }
}

send_func(int port)
{
    void *fd;
    uint64_t fsize = 2517283;
    uint64_t nbrBytes = 0;  
    size_t rsize;
    int count;
    ssize_t ret;
    uint8_t Bsent = 0;

    for (count = 1; nbrBytes < fsize; count++) 
    {
        if (mode == ONLY_1_BYTE) {
            rsize = ((uint8_t*)fp)[nbrBytes];
            rsize += ((((uint8_t*)fp)[nbrBytes + 1])); 
            nbrBytes += 1;

            do {
                // send data
                ret = write(port, ((unsigned char*)fp) + Bsent, rsize - Bsent);
                if (ret < 0) {
                    return -1;
                }  
                Bsent += ret;
            } while(Bsent < rsize)     
        }
        else
        {
            rsize = ((uint8_t*)fp)[nbrBytes];
            rsize += ((((uint8_t*)fp)[nbrBytes + 1]) << 8) & 0xFF00;
            nbrBytes += 2;   

            // send size
            ret = write(port, rsize, sizeof(uint16_t));
            if (ret != 2) {
                return -1;
            }        
        }

        do {
            // send data
            ret = write(port, ((unsigned char*)fp) + Bsent, rsize - Bsent);
            if (ret < 0) {
                return -1;
            }  
            Bsent += ret;
        } while(Bsent < rsize)
    }
}

Because there is only 1 length byte in the second case, I voluntarily removed the endianity operation, which is compulsory in case of 2 bytes.

Is it the best way to practice ?


Solution

  • Some best practices that you can apply to improve the code you posted:

    • Don't worry about optimizing a single byte out of the stream. It doesn't matter. Did you know that every Ethernet frame takes about 60 bytes of overhead aside from your payload?
    • Don't hand-roll endian swaps. Use built in functions like htons().
    • You need to account for "short writes" where the return value from write() is less than you tried to send. When that happens you need to loop and call write() again without re-sending a length prefix.