void bitfile_put_bit(struct bitfile *bf, u8 bit) { assert(bf->mode == 'w'); assert(bit == 0 || bit == 1); if (bit) BIT_SET(*bf->pos, bf->bit_pos); else BIT_UNSET(*bf->pos, bf->bit_pos); bf->bit_pos++; if (bf->bit_pos > 7) { bf->bit_pos = 0; bf->pos++; if (bf->pos >= bf->buffer_end) { write_buffer(bf); } } }
void huffman_make_codes(struct hcnode *root) { /* Macros for pushing the bitvector position forwards and backwards */ #define BITS_FWD() \ bit_pos++; \ code_len++; \ if (bit_pos > 7) { \ pos++; \ bit_pos = 0; \ } #define BITS_BACK() \ code_len--; \ if (bit_pos < 1) { \ pos--; \ bit_pos = 7; \ } else { \ bit_pos--; \ } struct hcnode *n = root; u8 code[32] = {0,}; int code_len = 0; u8 *pos = code; u8 bit_pos = 0; while (1) { while (n->left != NULL) { /* going left (0), unset current bit */ BIT_UNSET(*pos, bit_pos); BITS_FWD(); n = n->left; } /* Process the leaf node */ if (n->left == NULL && n->right == NULL) { memcpy(n->code, code, 32); n->code_len = code_len; /* go back one level */ BITS_BACK(); } while (n->parent != NULL) { if (n != n->parent->right) { /* going right (1), set current bit */ BIT_SET(*pos, bit_pos); BITS_FWD(); n = n->parent->right; break; } else { /* going up */ BITS_BACK(); n = n->parent; } } if (n->parent == NULL) break; } #undef BITS_FWD #undef BITS_BACK }
ret_t cherokee_downloader_step (cherokee_downloader_t *downloader, cherokee_buffer_t *ext_tmp1, cherokee_buffer_t *ext_tmp2) { ret_t ret; cherokee_buffer_t *tmp1; cherokee_buffer_t *tmp2; /* Set the temporary buffers */ tmp1 = (ext_tmp1) ? ext_tmp1 : &downloader->tmp1; tmp2 = (ext_tmp2) ? ext_tmp2 : &downloader->tmp2; TRACE (ENTRIES, "phase=%d\n", downloader->phase); /* Process it */ switch (downloader->phase) { case downloader_phase_init: { cherokee_request_header_t *req = &downloader->request; TRACE(ENTRIES, "Phase %s\n", "init"); /* Maybe add the post info */ if (! cherokee_buffer_is_empty (&downloader->post)) { req->method = http_post; req->post_len = downloader->post.len; } /* Build the request header */ ret = cherokee_request_header_build_string (req, &downloader->request_header, tmp1, tmp2); if (unlikely(ret < ret_ok)) return ret; /* Deal with the connection */ if (! is_connected (downloader)) { ret = cherokee_downloader_connect (downloader); if (ret < ret_ok) return ret; } /* Everything is ok, go ahead! */ downloader->phase = downloader_phase_send_headers; } case downloader_phase_send_headers: TRACE(ENTRIES, "Phase %s\n", "send_headers"); ret = downloader_send_buffer (downloader, &downloader->request_header); if (unlikely(ret != ret_ok)) return ret; BIT_SET (downloader->status, downloader_status_headers_sent); downloader->phase = downloader_phase_send_post; case downloader_phase_send_post: TRACE(ENTRIES, "Phase %s\n", "send_post"); if (! cherokee_buffer_is_empty (&downloader->post)) { size_t written = 0; ret = cherokee_socket_bufwrite (&downloader->socket, &downloader->post, &written); if (ret != ret_ok) { return ret; } cherokee_buffer_move_to_begin (&downloader->post, written); if (! cherokee_buffer_is_empty (&downloader->post)) { return ret_eagain; } } BIT_SET (downloader->status, downloader_status_post_sent); downloader->phase = downloader_phase_read_headers; break; case downloader_phase_read_headers: TRACE(ENTRIES, "Phase %s\n", "read_headers"); ret = downloader_header_read (downloader, tmp1, tmp2); if (unlikely(ret != ret_ok)) return ret; /* We have the header parsed, continue.. */ BIT_SET (downloader->status, downloader_status_headers_received); downloader->phase = downloader_phase_step; /* Does it read the full reply in the first received chunk? */ if (downloader->info.body_recv >= downloader->content_length) { BIT_SET (downloader->status, downloader_status_data_available); BIT_SET (downloader->status, downloader_status_finished); return ret_eof_have_data; } case downloader_phase_step: TRACE(ENTRIES, "Phase %s\n", "step"); ret = downloader_step (downloader); switch (ret) { case ret_error: break; case ret_ok: BIT_SET (downloader->status, downloader_status_data_available); break; case ret_eof_have_data: BIT_SET (downloader->status, downloader_status_data_available); BIT_SET (downloader->status, downloader_status_finished); break; case ret_eof: BIT_UNSET (downloader->status, downloader_status_data_available); BIT_SET (downloader->status, downloader_status_finished); break; case ret_eagain: BIT_UNSET (downloader->status, downloader_status_data_available); break; default: RET_UNKNOWN(ret); } return ret; case downloader_phase_finished: TRACE(ENTRIES, "Phase %s\n", "finished"); BIT_SET (downloader->status, downloader_status_finished); BIT_UNSET (downloader->status, downloader_status_data_available); return ret_ok; default: SHOULDNT_HAPPEN; break; } return ret_ok; }