Created
March 12, 2014 08:53
-
-
Save wuyongzheng/9503212 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
/* read 32bit little endian integer */ | |
int read_leint (FILE *in, uint32_t *outint) | |
{ | |
unsigned char bytes[4]; | |
if (fread(bytes, 4, 1, in) != 1) | |
return 1; | |
*outint = (bytes[3] << 24) | | |
(bytes[2] << 16) | | |
(bytes[1] << 8) | | |
bytes[0]; | |
return 0; | |
} | |
void hexdump (const char *msg, const unsigned char *data, size_t len) | |
{ | |
int i; | |
fprintf(stderr, "%s: ", msg); | |
for (i = 0; i < len; i ++) { | |
fprintf(stderr, "%02x", data[i]); | |
fprintf(stderr, "%c", i == len - 1 ? '\n' : ' '); | |
} | |
} | |
int copyField (FILE *in, FILE *out) | |
{ | |
uint32_t n1, size; | |
unsigned char buffer[8192]; | |
if (read_leint(in, &n1) || read_leint(in, &size)) { | |
fprintf(stderr, "Unexpected EOF\n"); | |
return 1; | |
} | |
fprintf(stderr, "copyField: %x %x\n", n1, size); | |
size -= 12; | |
while (size > 0) { | |
size_t len = size < sizeof(buffer) ? size : sizeof(buffer); | |
if (fread(buffer, len, 1, in) != 1) { | |
fprintf(stderr, "Unexpected EOF\n"); | |
return 1; | |
} | |
fwrite(buffer, len, 1, out); | |
size -= len; | |
} | |
return 0; | |
} | |
int writeZeros (FILE *in, FILE *out) | |
{ | |
uint32_t pages, n2; | |
unsigned char buffer[4096] = {0}; | |
if (read_leint(in, &pages) || read_leint(in, &n2)) { | |
fprintf(stderr, "Unexpected EOF\n"); | |
return 1; | |
} | |
fprintf(stderr, "writeZeros: %x %x\n", pages, n2); | |
for (; pages > 0; pages --) | |
fwrite(buffer, 4096, 1, out); | |
return 0; | |
} | |
int convert (FILE *in, FILE *out) | |
{ | |
unsigned char buffer[4096]; | |
if (fread(buffer, 1, 28, in) != 28) { | |
fprintf(stderr, "File too short\n"); | |
return 1; | |
} | |
hexdump("H28", buffer, 28); | |
while (1) { | |
uint32_t opcode; | |
if (read_leint(in, &opcode)) { | |
return 0; | |
} | |
switch (opcode) { | |
case 0xCAC1: | |
if (copyField(in, out)) | |
return 1; | |
break; | |
case 0xCAC3: | |
if (writeZeros(in, out)) | |
return 1; | |
break; | |
default: | |
fprintf(stderr, "Invalid header %x\n", opcode); | |
return 1; | |
} | |
} | |
} | |
int main (void) | |
{ | |
return convert(stdin, stdout); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment