#include #include using namespace std; typedef unsigned char Uint8; typedef unsigned short Uint16; typedef unsigned long Uint32; struct AISFeeder { FILE *_f; unsigned int count; Uint8 word[sizeof(Uint32)]; enum { MAGIC_WORD = 0, SECT_LOAD, SECT_FILL, ENABLE_CRC, DISABLE_CRC, VALID_CRC, JUMP_CLOSE, JUMP, SEQ_READ, COMP_SECT_LOAD, EXEC, BOOT_TBL, NUM_OF_COMMAND,}; static const struct command_properties_t { Uint32 opcode; Uint32 min_arguments; Uint32 size_arg_index; const char *name; } command_properties[NUM_OF_COMMAND]; command_properties_t const *current_command; Uint32 index_on_command; Uint32 expected_command_size; AISFeeder(FILE *f) : _f(f), count(0), current_command(0), index_on_command(0), expected_command_size(0) {} unsigned int operator()(Uint8 *buf, const unsigned int &size){ unsigned int res(0), word_index(count % sizeof(word)); while(res < size){ if(word_index == 0){ unsigned int new_read( fread(word, sizeof(word[0]), sizeof(word) / sizeof(word[0]), _f)); if(new_read < sizeof(word)){break;} ++index_on_command; if(index_on_command >= expected_command_size){ current_command = 0; index_on_command = expected_command_size = 0; for(int i(0); i < sizeof(command_properties) / sizeof(command_properties[0]); i++){ if(command_properties[i].opcode == *(Uint32 *)(&word[0])){ current_command = &command_properties[i]; break; } } if(current_command){ expected_command_size = 1 + current_command->min_arguments; printf("Command: %s\n", current_command->name); }else{ printf("Unknown Command: %d\n", *(Uint32 *)(&word[0])); } }else if(index_on_command == current_command->size_arg_index){ expected_command_size += ((*(Uint32 *)(&word[0]) + sizeof(Uint32) - 1) / sizeof(Uint32)); printf("Section size: 0x%08x\n", *(Uint32 *)(&word[0])); }else if((current_command == &command_properties[EXEC]) && (index_on_command == 1)){ expected_command_size += (*(Uint32 *)(&word[0]) >> 16); printf("Function number: %d\n", (*(Uint32 *)(&word[0]) & 0xFFFF)); } } buf[res++] = word[word_index++]; count++; if(word_index == sizeof(word)){ word_index = 0; } } return res; } }; const AISFeeder::command_properties_t AISFeeder::command_properties[AISFeeder::NUM_OF_COMMAND] = { {0x41504954, 0, 0, "MAGIC_WORD"}, {0x58535901, 2, 2, "SECT_LOAD"}, {0x5853590A, 4, 2, "SECT_FILL"}, {0x58535903, 0, 0, "ENABLE_CRC"}, {0x58535904, 0, 0, "DISABLE_CRC"}, {0x58535902, 2, 0, "VALID_CRC"}, {0x58535906, 1, 0, "JUMP_CLOSE"}, {0x58535905, 1, 0, "JUMP"}, {0x58535963, 0, 0, "SEQ_READ"}, {0x58535909, 3, 3, "COMP_SECT_LOAD"}, {0x5853590D, 1, 0, "EXEC"}, {0x58535907, 4, 0, "BOOT_TBL"}, }; #ifdef _WIN32 # include # include # define SET_BINARY_MODE(handle) setmode(handle, O_BINARY) #else # define SET_BINARY_MODE(handle) ((void)0) #endif int main(){ int read_size; SET_BINARY_MODE(fileno(stdin)); AISFeeder feeder(stdin); Uint8 buf[2]; while(feof(stdin) == 0){ feeder(buf, sizeof(buf)); } printf("File size => %d bytes\n", feeder.count); return 0; }