Created
March 14, 2015 09:50
-
-
Save deevus/3dce7aecfef5582e50e7 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| /* | |
| @author Simon Hartcher | |
| @studentNo c3185790 | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <limits.h> | |
| #include <stdint.h> | |
| #include <stdbool.h> | |
| #include <string.h> | |
| #if CHAR_BIT != 8 | |
| #error "unsupported char size" | |
| #endif | |
| enum | |
| { | |
| O32_LITTLE_ENDIAN = 0x03020100ul, | |
| O32_BIG_ENDIAN = 0x00010203ul, | |
| O32_PDP_ENDIAN = 0x01000302ul | |
| }; | |
| static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order = | |
| { { 0, 1, 2, 3 } }; | |
| #define O32_HOST_ORDER (o32_host_order.value) | |
| inline bool | |
| will_overflow(int n) { | |
| int int_size = sizeof(int); | |
| if (n > int_size) { | |
| fprintf(stderr, "Error: Number of bytes exceeded. Int size: %d > %d.\n", int_size, n); | |
| return true; | |
| } | |
| return false; | |
| } | |
| void | |
| reverse(char bytes[], int n) { | |
| int i = 0; | |
| int j = n - 1; | |
| while (j - i > 0) | |
| { | |
| char temp = bytes[j]; | |
| bytes[j] = bytes[i]; | |
| bytes[i] = temp; | |
| i++; | |
| j--; | |
| } | |
| } | |
| int | |
| read_bytes(char *str, int n) { | |
| int res; | |
| int i; | |
| for (i = 0; i < n; ++i) | |
| { | |
| int val = (int)str[i]; | |
| res = res | (val << (i * 8)); | |
| } | |
| return res; | |
| } | |
| void | |
| print_bytes(char bytes[], int n) { | |
| int k; | |
| for (k = 0; k < n; ++k) | |
| { | |
| printf("%d ", bytes[k]); | |
| } | |
| printf("\n"); | |
| } | |
| int | |
| extract_endian(char *str, int offset, int n, uint32_t order) { | |
| if (!will_overflow(n)) { | |
| char bytes[n]; | |
| memcpy(&bytes, str, n * sizeof(char)); | |
| printf("Before: "); | |
| print_bytes(bytes, n); | |
| if (O32_HOST_ORDER != order) { | |
| reverse(bytes, n); | |
| } | |
| printf("After: "); | |
| print_bytes(bytes, n); | |
| return read_bytes(&bytes, n); | |
| } | |
| return 0; | |
| } | |
| int | |
| extract_little(char *str, int ofset, int n) { | |
| return extract_endian(str, ofset, n, O32_LITTLE_ENDIAN); | |
| } | |
| int | |
| extract_big(char *str, int ofset, int n) { | |
| return extract_endian(str, ofset, n, O32_BIG_ENDIAN); | |
| } | |
| int | |
| main(int argc, const char* argv[]) | |
| { | |
| if (argc < 4) { | |
| fputs("Usage: ./question1 <string> <offset> <num>\n", stderr); | |
| return 1; | |
| } | |
| printf("Int size: %d, Char size: %d \n", sizeof(int), sizeof(char)); | |
| char *str = (char*)argv[1]; | |
| int offset = atoi(argv[2]); | |
| int n = atoi(argv[3]); | |
| printf("String: %s, Offset: %d, N: %d\n", str, offset, n); | |
| int little = extract_little(str, offset, n); | |
| printf("Little Endian: %d\n", little); | |
| int big = extract_big(str, offset, n); | |
| printf("Big Endian: %d\n", big); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment