Exemple #1
0
gint
hex_document_read(HexDocument *doc)
{
  FILE *file;
  static HexChangeData change_data;

  if(doc->file_name == NULL)
    return FALSE;

  if(!get_document_attributes(doc))
    return FALSE;

  if((file = fopen(doc->file_name, "r")) == NULL)
    return FALSE;

  doc->gap_size = doc->buffer_size - doc->file_size;
  if(fread(doc->buffer + doc->gap_size, 1, doc->file_size, file) != doc->file_size)
    {
      g_return_val_if_reached(FALSE);
    }
  doc->gap_pos = doc->buffer;
  fclose(file);
  undo_stack_free(doc);

  change_data.start = 0;
  change_data.end = doc->file_size - 1;
  doc->changed = FALSE;
  hex_document_changed(doc, &change_data, FALSE);

  return TRUE;
}
Exemple #2
0
void
hex_document_set_byte(HexDocument *doc, guchar val, guint offset,
                      gboolean insert, gboolean undoable)
{
  static HexChangeData change_data;

  if(offset <= doc->file_size)
    {
      if(!insert && offset == doc->file_size)
        return;

      doc->changed = TRUE;
      change_data.start = offset;
      change_data.end = offset;
      change_data.rep_len = (insert?0:1);
      change_data.v_string = NULL;
      change_data.type = HEX_CHANGE_BYTE;
      change_data.lower_nibble = FALSE;
      change_data.insert = insert;
      if(insert)
        {
          move_gap_to(doc, offset, 1);
          doc->gap_size--;
          doc->gap_pos++;
          doc->file_size++;
        }
      else if(doc->buffer + offset >= doc->gap_pos)
        offset += doc->gap_size;

      change_data.v_byte = doc->buffer[offset];
      doc->buffer[offset] = val;

      hex_document_changed(doc, &change_data, undoable);
    }
}
Exemple #3
0
void
hex_document_set_data(HexDocument *doc, guint offset, guint len,
                      guint rep_len, guchar *data, gboolean undoable)
{
    guint i;
    guchar *ptr;
    static HexChangeData change_data;

    if(offset <= doc->file_size) {
        if(doc->file_size - offset < rep_len)
            rep_len -= doc->file_size - offset;

        doc->changed = TRUE;

        change_data.v_string = g_realloc(change_data.v_string, rep_len);
        change_data.start = offset;
        change_data.end = change_data.start + len - 1;
        change_data.rep_len = rep_len;
        change_data.type = HEX_CHANGE_STRING;
        change_data.lower_nibble = FALSE;

        i = 0;
        ptr = &doc->buffer[offset];
        if(ptr >= doc->gap_pos)
            ptr += doc->gap_size;
        while(offset + i < doc->file_size && i < rep_len) {
            if(ptr >= doc->gap_pos && ptr < doc->gap_pos + doc->gap_size)
                ptr += doc->gap_size;
            change_data.v_string[i] = *ptr++;
            i++;
        }

        if(rep_len == len) {
            if(doc->buffer + offset >= doc->gap_pos)
                offset += doc->gap_size;
        }
        else {
            if(rep_len > len) {
                move_gap_to(doc, offset + rep_len, 1);
            }
            else if(rep_len < len) {
                move_gap_to(doc, offset + rep_len, len - rep_len);
            }
            doc->gap_pos -= (gint)rep_len - (gint)len;
            doc->gap_size += (gint)rep_len - (gint)len;
            doc->file_size += (gint)len - (gint)rep_len;
        }

        ptr = &doc->buffer[offset];
        i = 0;
        while(offset + i < doc->buffer_size && i < len) {
            *ptr++ = *data++;
            i++;
        }

        hex_document_changed(doc, &change_data, undoable);
    }
}
Exemple #4
0
void
hex_document_set_nibble(HexDocument *doc, guchar val, guint offset,
                        gboolean lower_nibble, gboolean insert,
                        gboolean undoable)
{
  static HexChangeData change_data;

  if(offset <= doc->file_size)
    {
      if(!insert && offset == doc->file_size)
        return;

      doc->changed = TRUE;
      change_data.start = offset;
      change_data.end = offset;
      change_data.v_string = NULL;
      change_data.type = HEX_CHANGE_BYTE;
      change_data.lower_nibble = lower_nibble;
      change_data.insert = insert;
      if(!lower_nibble && insert)
        {
          move_gap_to(doc, offset, 1);
          doc->gap_size--;
          doc->gap_pos++;
          doc->file_size++;
          change_data.rep_len = 0;
          if(offset == doc->file_size)
            doc->buffer[offset] = 0;
        }
      else
        {
          if(doc->buffer + offset >= doc->gap_pos)
            offset += doc->gap_size;
          change_data.rep_len = 1;
        }

      change_data.v_byte = doc->buffer[offset];
      doc->buffer[offset] = (doc->buffer[offset] & (lower_nibble?0xF0:0x0F)) | (lower_nibble?val:(val << 4));

      hex_document_changed(doc, &change_data, undoable);
    }
}
Exemple #5
0
static void
hex_document_real_undo (HexDocument *doc)
{
  HexChangeData *cd;
  gint len;
  guchar *rep_data;
  gchar c_val;

  cd = (HexChangeData *)doc->undo_top->data;

  switch(cd->type)
    {
    case HEX_CHANGE_BYTE:
      if(cd->start >= 0 && cd->end < doc->file_size)
        {
          c_val = hex_document_get_byte(doc, cd->start);
          if(cd->rep_len > 0)
            hex_document_set_byte(doc, cd->v_byte, cd->start, FALSE, FALSE);
          else if(cd->rep_len == 0)
            hex_document_delete_data(doc, cd->start, 1, FALSE);
          else
            hex_document_set_byte(doc, cd->v_byte, cd->start, TRUE, FALSE);
          cd->v_byte = c_val;
        }
      break;
    case HEX_CHANGE_STRING:
      len = cd->end - cd->start + 1;
      rep_data = hex_document_get_data(doc, cd->start, len);
      hex_document_set_data(doc, cd->start, cd->rep_len, len, cd->v_string, FALSE);
      g_free(cd->v_string);
      cd->end = cd->start + cd->rep_len - 1;
      cd->rep_len = len;
      cd->v_string = rep_data;
      break;
    }

  hex_document_changed(doc, cd, FALSE);
  undo_stack_descend(doc);
}