1

EDIT: After doing some more research, it seems that what i actually need is big endian to middle endian and vice versa. so 12345678 -> 34127856 and back. Sorry for any confusion.

I have a small file, exactly 16MB. I am reading the whole file into a buffer. What Im trying to do is byteswap the whole file/buffer in one go if possible (eg. uniformly/globaly swaps ADDECEFA => DEADFACE). I have read countless pages of byteswapping but alot of the bitwise/byteswap stuff goes right over my head for some reason (dumb brain most likely). If anyone knows a bitwise/byteswap for dummies, please point me in the right direction!

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) 
{

    const char * suffix = ".reversed";

    FILE *input = fopen(argv[1], "rb");
    char * out = strcat(argv[1], suffix);
    FILE *output = fopen(out, "wb");

    int data[16384];
    int swapped;

 while(fread(data,sizeof data, 1, input)){

    swapped = ((data & 0x000000FF) << 24) |
              ((data & 0x0000FF00) <<  8) |
              ((data & 0x00FF0000) >>  8) |
              ((data & 0xFF000000) >> 24);

    fwrite(swapped, sizeof data , 1, output);

            /*  by golly it copies the file fast as heck!
                but i am unsure how to manipulate 'data' buffer
                so as it uniformly/globaly swaps ADDECEFA => DEADFACE 
            */
        }
    }

Also, if you see me doing something wrong in my code, please tell me and show me a better way. If you need me to elaborate anything please dont hesitate to ask. Thanks and have a good one.

EDIT: I added one of my failed attempts. My end goal was to swap the bytes as I write it back out to outfile and swap them as efficiently as possible.

james28909
  • 554
  • 2
  • 9
  • 20
  • It is too dangerous to `strcat(argv[1], suffix);` you have no idea if there is enough room. – Weather Vane Dec 14 '16 at 20:52
  • hmm so what would be the best way to handle that? I looked for a way to add the suffix to the filename from argv. ofcourse argv[1]+".suffix" didnt work ;( – james28909 Dec 14 '16 at 21:00
  • i guess i could output a static filename then rename it after im done. – james28909 Dec 14 '16 at 21:01
  • 1
    i did find this: http://stackoverflow.com/questions/7119718/appending-string-to-input-file-name-in-c" – james28909 Dec 14 '16 at 21:04
  • Allocate memory with the required space (incl `'\0'` terminator) and build a new string. Either with `strcpy` and `strcat`, or with `sprintf`. But do please check `argc` before accessing `argv[]`. Please show how you have tried to do the swapping. From the example, it looks as if you want to swap each pair of bytes. – Weather Vane Dec 14 '16 at 21:05
  • I tried alot of different things, i would go back and edit my code to include all of the resources but it would take me a while to find them all. let me see what i can do. Everything i tried either crashed, or didnt work. I really want to swap the largest amount of bytes possible, I realize the swapping 4 or 8 pair of bytes would be faster than swapping one pair of bytes. Ill put one of the failed attempts of byteswapping up in the code. – james28909 Dec 14 '16 at 21:24

1 Answers1

1

Given

int data[16384];

this code

while(fread(data,sizeof data, 1, input)){

will try to read 16,384 int values from input. Nothing wrong so far.

But this code:

swapped = ((data & 0x000000FF) << 24) |
          ((data & 0x0000FF00) <<  8) |
          ((data & 0x00FF0000) >>  8) |
          ((data & 0xFF000000) >> 24);

Will put try to stuff whatever part that fits of the byte-swapped address of data into swapped, because data is evaluated as the address of the first element of the array.

You probably want something like this:

swapped = ((data[ 0 ] & 0x000000FF) << 24) |
          ((data[ 0 ] & 0x0000FF00) <<  8) |
          ((data[ 0 ] & 0x00FF0000) >>  8) |
          ((data[ 0 ] & 0xFF000000) >> 24);

But that has a problem that shifting signed int values has implementation-defined behavior. See Arithmetic bit-shift on a signed integer

So you probably want

unsigned int data[16384];

Even given that, though, you're only swapping one int value. You need to loop over all the data that's been read, swapping each int, assuming that's what you want to do.

Which raises another problem - your code does not track how much data it needs to byte swap. You need to count the number of int values read in and use that.

Finally, this code

fwrite(swapped, sizeof data , 1, output);

will write sizeof data bytes to output, starting at the address of whatever swapped happens to point to. But this is the definition of swapped:

int swapped;

So that fwrite() call is undefined behavior.

Community
  • 1
  • 1
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • "But this is the definition of swapped" hmm i thought that i added to swapped when i tried to byteswap data. I think i see what you mean though, i should have did 'sizeof swapped' right? – james28909 Dec 14 '16 at 22:29
  • 1
    @james28909 - assuming you mean the `fwrite()` statement, it should probably be something like `fwrite( &swapped, sizeof swapped, 1, output );` Note that the first argument to `fwrite()` is the *address* of the data to be written. – Andrew Henle Dec 14 '16 at 23:30
  • i do appreciate your comments, so thanks for that. but i am going to put this down for the evening and pick it back up tomorrow. thanks for your help – james28909 Dec 15 '16 at 00:22