summaryrefslogtreecommitdiff
path: root/2/homework/bytes_structure_2.71.c
blob: 61ead1c372ddf7bfe45fe8642662fc09744046f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>
#include <string.h>

typedef unsigned packed_t;

/*
  3    2    1    0
  byte byte byte byte
  1000 1100 1110 1111
  xbyte(..., 2);
  >> 8
  0000 0000 1000 1100
  & 0xFF
  0000 0000 0000 1100

  0 <= x < 7 -> id
  -8 < x <  0 -> minus
*/
int xbyte(packed_t word, int bytenume);
int xbyte(packed_t word, int bytenum) {
    int max_bytes = 3;
    int max_bits = max_bytes << 3;
    int shift_bits = (3 - bytenum) << 3;
    return (int) word << shift_bits >> max_bits;
}

/*
  Copy integer into buffer if space is available
  WARNING: The following code is buggy

  size_t is an unsigned. So one of the operands gets casted.
  Either
  int -> unsigned
  or
  unsigned -> int

  apparently the result of unsigned - int or int - unsigned -> unsigned
 */
void buggy_copy_int(int val, void *buf, int maxbytes) {
    /*
      Check if maxbytes will cause problems when converted to unsigned.
     */
    if (maxbytes < 0) {
        return;
    }
    if (maxbytes >= sizeof(val)) {
        memcpy(buf, (void *) &val, sizeof(val));
    }
}

int main() {
    int maxbytes = 4;
    char buf[maxbytes];
    int i;
    for (i=0; i<maxbytes; ++i) {
        buf[i] = 'a';
    }

    buggy_copy_int(32, buf, maxbytes);
    for (i=0; i<maxbytes; ++i) {
        printf("%x\n", buf[i]);
    }
    return 0;

    printf("%x\n", xbyte(0x0000FF00, 1));
    return 0;
}