static void read_tree_magic_from_directory (const gchar *prefix) { gchar *filename; gchar *text; gsize len; gchar **lines; gint i; TreeMatch *match; TreeMatchlet *matchlet; gint depth; filename = g_build_filename (prefix, "mime", "treemagic", NULL); if (g_file_get_contents (filename, &text, &len, NULL)) { if (strcmp (text, "MIME-TreeMagic") == 0) { lines = g_strsplit (text + strlen ("MIME-TreeMagic") + 2, "\n", 0); match = NULL; for (i = 0; lines[i] && lines[i][0]; i++) { if (lines[i][0] == '[') { match = parse_header (lines[i]); insert_match (match); } else if (match != NULL) { matchlet = parse_match_line (lines[i], &depth); insert_matchlet (match, matchlet, depth); } else { g_warning ("%s: header corrupt; skipping\n", filename); break; } } g_strfreev (lines); } else g_warning ("%s: header not found, skipping\n", filename); g_free (text); } g_free (filename); }
block_state deflate_medium(deflate_state *s, int flush) { struct match current_match, next_match; memset(¤t_match, 0, sizeof(struct match)); memset(&next_match, 0, sizeof(struct match)); for (;;) { IPos hash_head = 0; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next current_match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ next_match.match_length = 0; } s->prev_length = 2; /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ /* If we already have a future match from a previous round, just use that */ if (next_match.match_length > 0) { current_match = next_match; next_match.match_length = 0; } else { hash_head = 0; if (s->lookahead >= MIN_MATCH) { hash_head = insert_string(s, s->strstart); } /* set up the initial match to be a 1 byte literal */ current_match.match_start = 0; current_match.match_length = 1; current_match.strstart = s->strstart; current_match.orgstart = current_match.strstart; /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != 0 && s->strstart - hash_head <= MAX_DIST2) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ current_match.match_length = longest_match (s, hash_head); current_match.match_start = s->match_start; if (current_match.match_length < MIN_MATCH) current_match.match_length = 1; if (current_match.match_start >= current_match.strstart) { /* this can happen due to some restarts */ current_match.match_length = 1; } } } insert_match(s, current_match); /* now, look ahead one */ if (s->lookahead > MIN_LOOKAHEAD) { s->strstart = current_match.strstart + current_match.match_length; hash_head = insert_string(s, s->strstart); /* set up the initial match to be a 1 byte literal */ next_match.match_start = 0; next_match.match_length = 1; next_match.strstart = s->strstart; next_match.orgstart = next_match.strstart; /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != 0 && s->strstart - hash_head <= MAX_DIST2) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ next_match.match_length = longest_match (s, hash_head); next_match.match_start = s->match_start; if (next_match.match_start >= next_match.strstart) /* this can happen due to some restarts */ next_match.match_length = 1; if (next_match.match_length < MIN_MATCH) next_match.match_length = 1; else fizzle_matches(s, ¤t_match, &next_match); } /* short matches with a very long distance are rarely a good idea encoding wise */ if (next_match.match_length == 3 && (next_match.strstart - next_match.match_start) > 12000) next_match.match_length = 1; s->strstart = current_match.strstart; } else { next_match.match_length = 0; } /* now emit the current match */ bflush = emit_match(s, current_match, hash_head); /* move the "cursor" forward */ s->strstart += current_match.match_length; if (bflush) FLUSH_BLOCK(s, 0); } s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->last_lit) FLUSH_BLOCK(s, 0); return block_done; }