- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
char *stringFromDTM(MDTM *dtm)
{
if (dtm->count < 1)
return "";
uint32_t size = (sizeof(MDTMPoint) + sizeof(uint32_t)) * dtm->count;
void *data = calloc(1, size);
uint32_t *ptr = data;
*(ptr++) = size;
uint32_t index;
for (index = 0; index < dtm->count; index++)
*(ptr++) = dtm->points[index].x;
for (index = 0; index < dtm->count; index++)
*(ptr++) = dtm->points[index].y;
for (index = 0; index < dtm->count; index++)
*(ptr++) = dtm->points[index].color;
for (index = 0; index < dtm->count; index++)
*(ptr++) = dtm->points[index].tol;
for (index = 0; index < dtm->count; index++)
*(ptr++) = dtm->points[index].size;
for (index = 0; index < dtm->count; index++)
*(ptr++) = dtm->points[index].x;
bool *bptr = (bool *)ptr;
for (index = 0; index < dtm->count; index++)
*(bptr++) = dtm->points[index].bad;
uint32_t len = compressBound(size);
char *buffer = malloc(len);
if (compress((Bytef *)buffer, (uLongf *)&len, data, size) == Z_OK)
{
free(data);
char *compressed = malloc(len + sizeof(uint32_t));
*((uint32_t *)(compressed)) = len;
strcpy(compressed + sizeof(uint32_t), buffer);
free(buffer);
}
free(buffer);
free(data);
return "";
}
Пару раз в качестве стилевого эксперимента пытался передавать calloc() оба параметра без предварительного умножения, но как-то не прижилось.
PS strcpy() на потенциально двоичные данные? выглядит загадочно. (и да, данные скорее всего двоичные, потому что Z_OK это скорее всего код возврата GNU zip'ного libz.)
Вот, кстати, еще красивое говно: функция возвращает то литерал "" (который не надо освобождать) то буфер (который надо освободить). Всё для удобства вызывающего!
Особенно с учетом того, что в начале compressed'а лежит длина, у которой с вероятностью 1/256 (если little-endian архитектура) нолик в первом байте... Как они собираются отличать этот буфер от "" - хуй знает. Скорее всего так:
По-моему, маловато видов пустых строк... Надо ещё что-нибудь добавить.
-----
* При включенной оптимизации и при некоторых предположениях о линкере.
Данунахуй? А посоны и не знали.
> указателем на произвольный нулевой байт, лежащий где угодно
Именно так. А вот будет ли этот байт одним и тем же для каждого литерала - знают только линкер и компилятор.
P.S. А еще в древних гцц (3.х) была дурацкая опция -fwritable-strings.