Example #1
0
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);
}
Example #2
0
block_state deflate_medium(deflate_state *s, int flush)
{
    struct match current_match, next_match;
    
    memset(&current_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, &current_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;
}