-
Notifications
You must be signed in to change notification settings - Fork 6
/
bitmap_method.c
110 lines (99 loc) · 2.93 KB
/
bitmap_method.c
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
static int bitmap_get_byte_addr(php_bitmap_base_t *intern, size_t index, char **pos, char *rm) {
size_t byteIndex;
short offset, i;
unsigned char mask = 0x80;
if (index <= 0) {
return 0;
}
byteIndex = (size_t)floor((index - 1) / 8);
offset = (index - 1) % 8;
for (i = 0; i < offset; i++) {
mask = mask >> 1;
}
*rm = mask;
*pos = intern->bytes + byteIndex;
return 1;
}
static int bitmap_resize_byte_map(php_bitmap_base_t *intern, size_t size) {
size_t oldSize = intern->size;
if (oldSize > size) {
return 1;
}
char *newBytes = ecalloc(1, size);
memcpy(newBytes, intern->bytes, intern->size);
efree(intern->bytes);
intern->bytes = newBytes;
intern->size = size;
return 0;
}
static ZEND_METHOD(bitmap, getBit) {
php_bitmap_base_t *intern;
int offset, index, byteIndex, i;
char* pos, rm;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
return;
}
Z_BITMAP_INTERN(intern, GET_BITMAP_THIS(getThis()));
if (index > intern->size) {
RETURN_FALSE;
}
bitmap_get_byte_addr(intern, index, &pos, &rm);
char result = *pos & rm ? '1' : '0';
BITMAP_RETURN_STRING(&result, 1);
}
static ZEND_METHOD(bitmap, setBit) {
php_bitmap_base_t *intern;
int offset, index, byteIndex, i;
char *pos, rm;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
return;
}
Z_BITMAP_INTERN(intern, GET_BITMAP_THIS(getThis()));
size_t byteOffset = (size_t)floor((index - 1) / 8);
if (byteOffset >= intern->size) {
bitmap_resize_byte_map(intern, byteOffset * 2);
}
bitmap_get_byte_addr(intern, index, &pos, &rm);
*pos = *pos | rm;
}
static ZEND_METHOD(bitmap, dumpBit) {
php_bitmap_base_t *intern;
Z_BITMAP_INTERN(intern, GET_BITMAP_THIS(getThis()));
short j, count;
size_t total, i;
total = intern->size * sizeof(char) * 8;
char *result = ecalloc(1, total);
for (i = 0; i < intern->size; i ++) {
count = 0;
for (j = 0x80; j > 0; j /= 2) {
result[i * 8 + count] = intern->bytes[i] & j ? '1' : '0';
count ++;
}
}
BITMAP_RETURN_STRING(result, total);
efree(result);
}
static ZEND_METHOD(bitmap, getBytes) {
php_bitmap_base_t *intern;
Z_BITMAP_INTERN(intern, GET_BITMAP_THIS(getThis()));
BITMAP_RETURN_STRING(intern->bytes, intern->size);
}
static ZEND_METHOD(bitmap, __construct) /* {{{ */ {
php_bitmap_base_t *intern;
int len = 0;
char *str;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s", &str, &len) == FAILURE) {
return;
}
if (len == 0) {
return;
}
Z_BITMAP_INTERN(intern, GET_BITMAP_THIS(getThis()));
if (len >= intern->size) {
char *newBytes = ecalloc(1, len);
efree(intern->bytes);
intern->bytes = newBytes;
intern->size = len;
}
memcpy(intern->bytes, str, len);
}